dovecot-2.2: lib-fts: Changed filter's internal APIs to return e...

dovecot at dovecot.org dovecot at dovecot.org
Sat May 9 09:30:41 UTC 2015


details:   http://hg.dovecot.org/dovecot-2.2/rev/cfa35069876b
changeset: 18562:cfa35069876b
user:      Timo Sirainen <tss at iki.fi>
date:      Sat May 09 11:46:09 2015 +0300
description:
lib-fts: Changed filter's internal APIs to return error_r directly.
It's not very safe to store strings allocated from data stack to any
permanent structs.

diffstat:

 src/lib-fts/fts-filter-normalizer-icu.c    |  73 +++++++++--------------------
 src/lib-fts/fts-filter-normalizer-simple.c |   9 +--
 src/lib-fts/fts-filter-private.h           |   4 +-
 src/lib-fts/fts-filter-stemmer-snowball.c  |  15 +++--
 src/lib-fts/fts-filter-stopwords.c         |  15 +++--
 src/lib-fts/fts-filter.c                   |  14 +----
 src/lib-fts/fts-filter.h                   |   2 +-
 7 files changed, 53 insertions(+), 79 deletions(-)

diffs (truncated from 331 to 300 lines):

diff -r 7de648f42bc0 -r cfa35069876b src/lib-fts/fts-filter-normalizer-icu.c
--- a/src/lib-fts/fts-filter-normalizer-icu.c	Sat May 09 11:33:45 2015 +0300
+++ b/src/lib-fts/fts-filter-normalizer-icu.c	Sat May 09 11:46:09 2015 +0300
@@ -1,6 +1,7 @@
 /* Copyright (c) 2014-2015 Dovecot authors, see the included COPYING file */
 
 #include "lib.h"
+#include "str.h"
 #include "unichar.h" /* unicode replacement char */
 #include "fts-filter.h"
 #include "fts-filter-private.h"
@@ -21,32 +22,6 @@
 	UTransliterator *transliterator;
 };
 
-static void
-icu_error(const char **error_r, const UErrorCode err, const char *func)
-{
-	if (error_r == NULL)
-		return;
-
-	if (U_FAILURE(err)) {
-		*error_r = t_strdup_printf("Lib ICU function %s failed: %s\n",
-		                            func, u_errorName(err));
-	}
-}
-
-/* Thin wrapper for vprintf */
-static void ATTR_FORMAT(2, 3)
-fts_filter_normalizer_icu_error(const char **error_r, const char *format, ...)
-{
-	va_list args;
-
-	if (error_r == NULL)
-		return;
-
-	va_start(args, format);
-	*error_r = t_strdup_vprintf(format, args);
-	va_end(args);
-}
-
 /* Helper to create UTF16, which libicu wants as input.
 
  On input,  if *dst_uchars_r  > 0,  it indicates  the number  of UChar
@@ -154,7 +129,6 @@
 	if (np->transliterator != NULL)
 		utrans_close(np->transliterator);
 	pool_unref(&np->pool);
-	return;
 }
 
 static int
@@ -183,13 +157,14 @@
 	                           sizeof(struct fts_filter_normalizer));
 	np = p_new(pp, struct fts_filter_normalizer, 1);
 	np->pool = pp;
-	np->filter =  *fts_filter_normalizer_icu;
+	np->filter = *fts_filter_normalizer_icu;
 	np->transliterator_id = p_strdup(pp, id);
 	*filter_r = &np->filter;
 	return 0;
 }
 
-static int fts_filter_normalizer_icu_create_trans(struct fts_filter_normalizer *np)
+static int fts_filter_normalizer_icu_create_trans(struct fts_filter_normalizer *np,
+						  const char **error_r)
 {
 	UErrorCode err = U_ZERO_ERROR;
 	UParseError perr;
@@ -203,33 +178,36 @@
 	np->transliterator = utrans_openU(id_uchar, u_strlen(id_uchar), UTRANS_FORWARD,
 	                                  NULL, 0, &perr, &err);
 	if (U_FAILURE(err)) {
+		string_t *str = t_str_new(128);
+
+		str_printfa(str, "Failed to open transliterator for id '%s': %s",
+			    np->transliterator_id, u_errorName(err));
 		if (perr.line >= 1) {
-			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);
+			/* we have only one line in our ID */
+			str_printfa(str, " (parse error on offset %u)", perr.offset);
 		}
-		else {
-			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));
-		}
+		*error_r = str_c(str);
 		return -1;
 	}
 	return 0;
 }
 
 static int
-fts_filter_normalizer_icu_filter(struct fts_filter *filter, const char **token)
+fts_filter_normalizer_icu_filter(struct fts_filter *filter, const char **token,
+				 const char **error_r)
 {
+	struct fts_filter_normalizer *np =
+		(struct fts_filter_normalizer *)filter;
 	UErrorCode err = U_ZERO_ERROR;
 	UChar *utext = NULL;
 	int32_t utext_cap = 0;
 	int32_t utext_len = -1;
 	int32_t utext_limit;
-	struct fts_filter_normalizer *np =
-		(struct fts_filter_normalizer *)filter;
 
-	if (np->transliterator == NULL)
-		if (fts_filter_normalizer_icu_create_trans(np) < 0)
-			goto err_exit;
+	if (np->transliterator == NULL) {
+		if (fts_filter_normalizer_icu_create_trans(np, error_r) < 0)
+			return -1;
+	}
 
 	make_uchar(*token, &utext, &utext_cap);
 	utext_limit = u_strlen(utext);
@@ -238,7 +216,6 @@
 
 	/* Data did not fit into utext. */
 	if (utext_len > utext_cap || err == U_BUFFER_OVERFLOW_ERROR) {
-
 		/* This is a crude retry fix... Make a new utext of the
 		   size utrans_transUChars indicated */
 		utext_len++; /* room for '\0' bytes(2) */
@@ -254,16 +231,13 @@
 	}
 
 	if (U_FAILURE(err)) {
-		icu_error(&np->filter.error, err, "utrans_transUChars()");
-		goto err_exit;
+		*error_r = t_strdup_printf("utrans_transUChars() failed: %s\n",
+		                            u_errorName(err));
+		return -1;
 	}
 
 	make_utf8(utext, token);
 	return 1;
-
- err_exit:
-	*token = NULL;
-	return -1;
 }
 
 #else
@@ -286,7 +260,8 @@
 
 static int
 fts_filter_normalizer_icu_filter(struct fts_filter *filter ATTR_UNUSED,
-				 const char *token ATTR_UNUSED)
+				 const char **token ATTR_UNUSED,
+				 const char **error_r ATTR_UNUSED)
 {
 	return NULL;
 }
diff -r 7de648f42bc0 -r cfa35069876b src/lib-fts/fts-filter-normalizer-simple.c
--- a/src/lib-fts/fts-filter-normalizer-simple.c	Sat May 09 11:33:45 2015 +0300
+++ b/src/lib-fts/fts-filter-normalizer-simple.c	Sat May 09 11:46:09 2015 +0300
@@ -50,17 +50,16 @@
 
 static int
 fts_filter_normalizer_simple_filter(struct fts_filter *_filter,
-				    const char **token)
+				    const char **token,
+				    const char **error_r ATTR_UNUSED)
 {
 	struct fts_filter_normalizer_simple *filter =
 		(struct fts_filter_normalizer_simple *)_filter;
 
 	str_truncate(filter->str, 0);
 	if (uni_utf8_to_decomposed_titlecase(*token, strlen(*token),
-	                                     filter->str) < 0) {
-		*token = NULL;
-		return -1;
-	}
+					     filter->str) < 0)
+		i_panic("fts-normalizer-simple: Token is not valid UTF-8: %s", *token);
 	*token = str_c(filter->str);
 	return 1;
 }
diff -r 7de648f42bc0 -r cfa35069876b src/lib-fts/fts-filter-private.h
--- a/src/lib-fts/fts-filter-private.h	Sat May 09 11:33:45 2015 +0300
+++ b/src/lib-fts/fts-filter-private.h	Sat May 09 11:46:09 2015 +0300
@@ -17,7 +17,8 @@
 	              const char *const *settings,
 	              struct fts_filter **filter_r,
 	              const char **error_r);
-	int (*filter)(struct fts_filter *filter, const char **token);
+	int (*filter)(struct fts_filter *filter, const char **token,
+		      const char **error_r);
 
 	void (*destroy)(struct fts_filter *filter);
 };
@@ -25,7 +26,6 @@
 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 7de648f42bc0 -r cfa35069876b src/lib-fts/fts-filter-stemmer-snowball.c
--- a/src/lib-fts/fts-filter-stemmer-snowball.c	Sat May 09 11:33:45 2015 +0300
+++ b/src/lib-fts/fts-filter-stemmer-snowball.c	Sat May 09 11:46:09 2015 +0300
@@ -65,12 +65,14 @@
 }
 
 static int
-fts_filter_stemmer_snowball_create_stemmer(struct fts_filter_stemmer_snowball *sp)
+fts_filter_stemmer_snowball_create_stemmer(struct fts_filter_stemmer_snowball *sp,
+					   const char **error_r)
 {
 	sp->stemmer = sb_stemmer_new(sp->lang->name, NULL);
 	if (sp->stemmer == NULL) {
-		sp->filter.error = t_strdup_printf("Creating a Snowball stemmer failed." \
-		                                   " lang: %s", sp->lang->name);
+		*error_r = t_strdup_printf(
+			"Creating a Snowball stemmer for language '%s' failed.",
+			sp->lang->name);
 		fts_filter_stemmer_snowball_destroy(&sp->filter);
 		return -1;
 	}
@@ -79,14 +81,14 @@
 
 static int
 fts_filter_stemmer_snowball_filter(struct fts_filter *filter,
-                                   const char **token)
+                                   const char **token, const char **error_r)
 {
 	struct fts_filter_stemmer_snowball *sp =
 		(struct fts_filter_stemmer_snowball *) filter;
 	const sb_symbol *base;
 
 	if (sp->stemmer == NULL) {
-		if (fts_filter_stemmer_snowball_create_stemmer(sp) < 0)
+		if (fts_filter_stemmer_snowball_create_stemmer(sp, error_r) < 0)
 			return -1;
 	}
 
@@ -125,7 +127,8 @@
 
 static int
 fts_filter_stemmer_snowball_filter(struct fts_filter *filter ATTR_UNUSED,
-                                   const char **token ATTR_UNUSED)
+				   const char **token ATTR_UNUSED,
+				   const char **error_r ATTR_UNUSED)
 {
 	return -1;
 }
diff -r 7de648f42bc0 -r cfa35069876b src/lib-fts/fts-filter-stopwords.c
--- a/src/lib-fts/fts-filter-stopwords.c	Sat May 09 11:33:45 2015 +0300
+++ b/src/lib-fts/fts-filter-stopwords.c	Sat May 09 11:46:09 2015 +0300
@@ -117,27 +117,30 @@
 }
 
 static int
-fts_filter_stopwords_create_stopwords(struct fts_filter_stopwords *sp)
+fts_filter_stopwords_create_stopwords(struct fts_filter_stopwords *sp,
+				      const char **error_r)
 {
 	int ret;
 
 	hash_table_create(&sp->stopwords, sp->pool, 0, str_hash, strcmp);
 	ret = fts_filter_stopwords_read_list(sp);
-	if (ret < 0)
-		sp->filter.error = t_strdup_printf("Failed to read stopword list %s",
-		                                   sp->stopwords_dir);
+	if (ret < 0) {
+		*error_r = t_strdup_printf("Failed to read stopword list %s",
+					   sp->stopwords_dir);
+	}
 	return ret;
 }
 
 static int
-fts_filter_stopwords_filter(struct fts_filter *filter, const char **token)
+fts_filter_stopwords_filter(struct fts_filter *filter, const char **token,
+			    const char **error_r)
 {
 	const char *stopword;
 	struct fts_filter_stopwords *sp =
 		(struct fts_filter_stopwords *) filter;
 
 	if (!hash_table_is_created(sp->stopwords))
-		if (fts_filter_stopwords_create_stopwords(sp) < 0)
+		if (fts_filter_stopwords_create_stopwords(sp, error_r) < 0)
 			return -1;
 	stopword = hash_table_lookup(sp->stopwords, *token);
 	if (stopword != NULL) {
diff -r 7de648f42bc0 -r cfa35069876b src/lib-fts/fts-filter.c
--- a/src/lib-fts/fts-filter.c	Sat May 09 11:33:45 2015 +0300
+++ b/src/lib-fts/fts-filter.c	Sat May 09 11:46:09 2015 +0300
@@ -99,21 +99,15 @@
 {
 	int ret = 0;
 
-	if (filter->error != NULL) {
-		*error_r = filter->error;
-		return -1;


More information about the dovecot-cvs mailing list