dovecot-2.2: fts: Improve filter error handling.

dovecot at dovecot.org dovecot at dovecot.org
Sat May 9 08:32:24 UTC 2015


details:   http://hg.dovecot.org/dovecot-2.2/rev/230698a51fbb
changeset: 18555:230698a51fbb
user:      Teemu Huovila <teemu.huovila at dovecot.fi>
date:      Sat May 09 11:13:49 2015 +0300
description:
fts: Improve filter error handling.

In lib-fts:
Move error storage to the generic filter struct level. Change make_utf8
helper to void also.

In fts:
Add the error argument to _filter() calls.

diffstat:

 src/lib-fts/fts-filter-normalizer-icu.c |  26 ++++++++------------------
 src/lib-fts/fts-filter-private.h        |   2 ++
 src/lib-fts/fts-filter.c                |  23 ++++++++++++++++-------
 src/lib-fts/fts-filter.h                |   3 ++-
 src/lib-fts/test-fts-filter.c           |  26 +++++++++++++-------------
 src/plugins/fts/fts-build-mail.c        |   5 ++++-
 src/plugins/fts/fts-search-args.c       |   6 ++++--
 7 files changed, 49 insertions(+), 42 deletions(-)

diffs (truncated from 316 to 300 lines):

diff -r 8c33d375c73e -r 230698a51fbb src/lib-fts/fts-filter-normalizer-icu.c
--- a/src/lib-fts/fts-filter-normalizer-icu.c	Sat May 09 11:10:31 2015 +0300
+++ b/src/lib-fts/fts-filter-normalizer-icu.c	Sat May 09 11:13:49 2015 +0300
@@ -16,7 +16,6 @@
 
 struct fts_filter_normalizer {
 	struct fts_filter filter;
-	const char *error;
 	pool_t pool;
 	const char *transliterator_id;
 	UTransliterator *transliterator;
@@ -97,7 +96,7 @@
 	i_assert(ustr_len == ustr_len_actual);
 }
 
-static int make_utf8(const UChar *src, const char **_dst, const char **error_r)
+static void make_utf8(const UChar *src, const char **_dst)
 {
 	char *dst;
 	char *retp = NULL;
@@ -133,14 +132,11 @@
 		        dsize_actual, dsize);
 	}
 	if (0 != sub_num) {
-		fts_filter_normalizer_icu_error(error_r, "UTF8 string not well formed."
-		                    " Substitutions (%d) were made.", sub_num);
-		return -1;
+		i_panic("UTF8 string not well formed. "
+		        "Substitutions (%d) were made.", sub_num);
 	}
 	i_assert(retp == dst);
-
 	*_dst = dst;
-	return 0;
 }
 
 static bool fts_filter_normalizer_icu_supports(const struct fts_language *lang)
@@ -208,11 +204,11 @@
 	                                  NULL, 0, &perr, &err);
 	if (U_FAILURE(err)) {
 		if (perr.line >= 1) {
-			fts_filter_normalizer_icu_error(&np->error, "Failed to open transliterator for id: %s. Lib ICU error: %s. Parse error on line %u offset %u.",
+			fts_filter_normalizer_icu_error(&np->filter.error, "Failed to open transliterator for id: %s. Lib ICU error: %s. Parse error on line %u offset %u.",
 			                                np->transliterator_id, u_errorName(err), perr.line, perr.offset);
 		}
 		else {
-			fts_filter_normalizer_icu_error(&np->error, "Failed to open transliterator for id: %s. Lib ICU error: %s.",
+			fts_filter_normalizer_icu_error(&np->filter.error, "Failed to open transliterator for id: %s. Lib ICU error: %s.",
 			                                np->transliterator_id, u_errorName(err));
 		}
 		return -1;
@@ -231,10 +227,6 @@
 	struct fts_filter_normalizer *np =
 		(struct fts_filter_normalizer *)filter;
 
-	/* TODO: fix error handling */
-	if (np->error != NULL)
-		goto err_exit;
-
 	if (np->transliterator == NULL)
 		if (fts_filter_normalizer_icu_create_trans(np) < 0)
 			goto err_exit;
@@ -262,15 +254,13 @@
 	}
 
 	if (U_FAILURE(err)) {
-		icu_error(&np->error, err, "utrans_transUChars()");
+		icu_error(&np->filter.error, err, "utrans_transUChars()");
 		goto err_exit;
 	}
 
-	if (make_utf8(utext, token, &np->error) < 0) {
-		goto err_exit;
-	}
+	make_utf8(utext, token);
+	return 1;
 
-	return 1;
  err_exit:
 	*token = NULL;
 	return -1;
diff -r 8c33d375c73e -r 230698a51fbb src/lib-fts/fts-filter-private.h
--- a/src/lib-fts/fts-filter-private.h	Sat May 09 11:10:31 2015 +0300
+++ b/src/lib-fts/fts-filter-private.h	Sat May 09 11:13:49 2015 +0300
@@ -18,12 +18,14 @@
 	              struct fts_filter **filter_r,
 	              const char **error_r);
 	int (*filter)(struct fts_filter *filter, const char **token);
+
 	void (*destroy)(struct fts_filter *filter);
 };
 
 struct fts_filter {
 	const char *class_name; /* name of the class this is based on */
 	const struct fts_filter_vfuncs *v;
+	const char *error;
 	int refcount;
 	struct fts_filter *parent;
 };
diff -r 8c33d375c73e -r 230698a51fbb src/lib-fts/fts-filter.c
--- a/src/lib-fts/fts-filter.c	Sat May 09 11:10:31 2015 +0300
+++ b/src/lib-fts/fts-filter.c	Sat May 09 11:13:49 2015 +0300
@@ -93,18 +93,27 @@
 /* TODO: Avoid multiple allocations by using a buffer in v->filter?
  Do this non-recursively? */
 int
-fts_filter_filter(struct fts_filter *filter, const char **token)
+fts_filter_filter(struct fts_filter *filter, const char **token,
+                  const char **error_r)
 
 {
-	int ret;
+	int ret = 0;
 
-	if (filter->parent == NULL)
-		return filter->v->filter(filter, token);
+	if (filter->error != NULL) {
+		*error_r = filter->error;
+		return -1;
+	}
 
-	ret = fts_filter_filter(filter->parent, token);
+	/* Recurse to parent. */
+	if (filter->parent != NULL)
+		ret = fts_filter_filter(filter->parent, token, error_r);
 
-	if(ret > 0)
-		return filter->v->filter(filter, token);
+	/* Parent returned token or no parent. */
+	if(ret > 0 || filter->parent == NULL)
+		ret = filter->v->filter(filter, token);
+
+	if (filter->error != NULL)
+		*error_r = filter->error;
 
 	return ret;
 }
diff -r 8c33d375c73e -r 230698a51fbb src/lib-fts/fts-filter.h
--- a/src/lib-fts/fts-filter.h	Sat May 09 11:10:31 2015 +0300
+++ b/src/lib-fts/fts-filter.h	Sat May 09 11:13:49 2015 +0300
@@ -63,6 +63,7 @@
    Input is also given via *token.
 */
 int
-fts_filter_filter(struct fts_filter *filter, const char **token);
+fts_filter_filter(struct fts_filter *filter, const char **token,
+                  const char **error_r);
 
 #endif
diff -r 8c33d375c73e -r 230698a51fbb src/lib-fts/test-fts-filter.c
--- a/src/lib-fts/test-fts-filter.c	Sat May 09 11:10:31 2015 +0300
+++ b/src/lib-fts/test-fts-filter.c	Sat May 09 11:13:49 2015 +0300
@@ -35,7 +35,7 @@
 	op = output;
 	while (*ip != NULL) {
 		token = *ip;
-		ret = fts_filter_filter(filter, &token);
+		ret = fts_filter_filter(filter, &token, &error);
 		test_assert(ret >= 0);
 		if (ret == 0)
 			test_assert(*op == NULL);
@@ -79,7 +79,7 @@
 	op = output;
 	while (*ip != NULL) {
 		token = *ip;
-		ret = fts_filter_filter(filter, &token);
+		ret = fts_filter_filter(filter, &token, &error);
 		test_assert(ret >= 0);
 		if (ret == 0)
 			test_assert(*op == NULL);
@@ -100,7 +100,7 @@
 	op = output2;
 	while (*ip != NULL) {
 		token = *ip;
-		ret = fts_filter_filter(filter, &token);
+		ret = fts_filter_filter(filter, &token, &error);
 		if (ret == 0)
 			test_assert(*op == NULL);
 		else {
@@ -143,7 +143,7 @@
 	op = output;
 	while (*ip != NULL) {
 		token = *ip;
-		ret = fts_filter_filter(filter, &token);
+		ret = fts_filter_filter(filter, &token, &error);
 		test_assert(ret >= 0);
 		if (ret == 0)
 			test_assert(*op == NULL);
@@ -207,7 +207,7 @@
 	bpp = bases;
 	for (tpp=tokens; *tpp != NULL; tpp++) {
 		token = *tpp;
-		ret = fts_filter_filter(stemmer, &token);
+		ret = fts_filter_filter(stemmer, &token, &error);
 		test_assert(token != NULL);
 		test_assert(null_strcmp(token, *bpp) == 0);
 		bpp++;
@@ -242,7 +242,7 @@
 	bpp = bases;
 	for (tpp=tokens; *tpp != NULL; tpp++) {
 		token = *tpp;
-		ret = fts_filter_filter(stemmer, &token);
+		ret = fts_filter_filter(stemmer, &token, &error);
 		test_assert(token != NULL);
 		test_assert(null_strcmp(token, *bpp) == 0);
 		bpp++;
@@ -289,7 +289,7 @@
 	bpp = bases;
 	for (tpp=tokens; *tpp != NULL; tpp++) {
 		token = *tpp;
-		ret = fts_filter_filter(stemmer, &token);
+		ret = fts_filter_filter(stemmer, &token, &error);
 		if (ret == 0)
 			test_assert(*bpp == NULL);
 		else {
@@ -344,7 +344,7 @@
 		for (i = 0; i < N_ELEMENTS(input); i++) {
 			if (input[i] != NULL) {
 				token = input[i];
-				test_assert_idx(fts_filter_filter(norm, &token) == 1, i);
+				test_assert_idx(fts_filter_filter(norm, &token, &error) == 1, i);
 				test_assert_idx(null_strcmp(token, expected_output[i]) == 0, i);
 			}
 		}
@@ -389,7 +389,7 @@
 		for (i = 0; i < N_ELEMENTS(input); i++) {
 			if (input[i] != NULL) {
 				token = input[i];
-				test_assert_idx(fts_filter_filter(norm, &token) == 1, i);
+				test_assert_idx(fts_filter_filter(norm, &token, &error) == 1, i);
 				test_assert_idx(null_strcmp(token, expected_output[i]) == 0, i);
 			}
 		}
@@ -437,7 +437,7 @@
 		sha512_init(&ctx);
 		while (NULL != fgets(buf, sizeof(buf), input)) {
 			tokens = buf;
-			if (fts_filter_filter(norm, &tokens) != 1){
+			if (fts_filter_filter(norm, &tokens, &error) != 1){
 				break;
 			}
 			sha512_loop(&ctx, tokens, strlen(tokens));
@@ -466,8 +466,8 @@
 	filter_class = fts_filter_find(ICU_NORMALIZER_FILTER_NAME);
 	ret = fts_filter_create(filter_class, NULL, NULL, settings, &norm, &error);
 	test_assert(ret ==  0 && error == NULL);
-	ret = fts_filter_filter(norm, &token);
-	test_assert(ret <  0);
+	ret = fts_filter_filter(norm, &token, &error);
+	test_assert(ret < 0 && error != NULL);
 	test_end();
 }
 
@@ -517,7 +517,7 @@
 	bpp = bases;
 	for (tpp = tokens; *tpp != NULL; tpp++) {
 		token = *tpp;
-		ret = fts_filter_filter(stemmer, &token);
+		ret = fts_filter_filter(stemmer, &token, &error);
 		if (ret == 0)
 			test_assert(*bpp == NULL);
 		else {
diff -r 8c33d375c73e -r 230698a51fbb src/plugins/fts/fts-build-mail.c
--- a/src/plugins/fts/fts-build-mail.c	Sat May 09 11:10:31 2015 +0300
+++ b/src/plugins/fts/fts-build-mail.c	Sat May 09 11:13:49 2015 +0300
@@ -244,12 +244,13 @@
 	struct fts_tokenizer *tokenizer;
 	struct fts_filter *filter = ctx->cur_user_lang->filter;
 	const char *token;
+	const char *error;
 	int ret;
 
 	tokenizer = fts_user_get_index_tokenizer(ctx->update_ctx->backend->ns->user);
 	while ((ret = fts_tokenizer_next(tokenizer, data, size, &token)) > 0) {
 		if (filter != NULL) {
-			ret = fts_filter_filter(filter, &token);
+			ret = fts_filter_filter(filter, &token, &error);
 			if (ret == 0)
 				continue;
 			if (ret < 0)
@@ -260,6 +261,8 @@
 						  strlen(token)) < 0)
 			return -1;
 	}
+	if (ret < 0)
+		i_error("fts: Couldn't create indexable tokens: %s", error);
 	return ret;
 }
 
diff -r 8c33d375c73e -r 230698a51fbb src/plugins/fts/fts-search-args.c
--- a/src/plugins/fts/fts-search-args.c	Sat May 09 11:10:31 2015 +0300
+++ b/src/plugins/fts/fts-search-args.c	Sat May 09 11:13:49 2015 +0300
@@ -63,7 +63,7 @@
 	struct mail_search_arg *arg;
 	struct fts_user_language *const *langp;
 	ARRAY_TYPE(const_string) tokens;
-	const char *token2;
+	const char *token2, *error;
 	int ret;
 


More information about the dovecot-cvs mailing list