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