changeset 22511:f0694e6eda8d

lib-storage: index: Made MIME FILENAME search criterion match case-insensitively.
author Stephan Bosch <stephan.bosch@dovecot.fi>
date Tue, 23 May 2017 14:05:02 +0200
parents 3c4348ffe0d6
children bcc3a15c18a6
files src/lib-storage/index/index-search-mime.c src/lib-storage/index/index-search-private.h src/lib-storage/index/index-search.c
diffstat 3 files changed, 82 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/index/index-search-mime.c	Wed Sep 20 01:47:38 2017 +0300
+++ b/src/lib-storage/index/index-search-mime.c	Tue May 23 14:05:02 2017 +0200
@@ -21,6 +21,8 @@
 	/* message parts parsed from BODYSTRUCTURE */
 	struct message_part *mime_parts, *mime_part;
 
+	string_t *buf;
+
 	unsigned int depth, index;
 	ARRAY(struct search_mimepart_stack) stack;
 };
@@ -243,18 +245,38 @@
 
 static int
 seach_arg_mime_filename_match(struct search_mimepart_context *mpctx,
-				   enum mail_search_mime_arg_type type, const char *key)
+				   struct mail_search_mime_arg *arg)
 {
+	struct index_search_context *ictx = mpctx->index_ctx;
 	struct message_part *part = mpctx->mime_part;
+	char *key;
 	const char *value;
 	size_t vlen, alen;
 
 	if (!message_part_data_get_filename(part, &value))
 		return 0;
 
-	/* FIXME: Normalization is probably required */
+	if (mpctx->buf == NULL)
+		mpctx->buf = str_new(default_pool, 256);
+
+	if (arg->context == NULL) {
+		str_truncate(mpctx->buf, 0);
 
-	switch (type) {
+		if (ictx->mail_ctx.normalizer(arg->value.str,
+			strlen(arg->value.str), mpctx->buf) < 0)
+			i_panic("search key not utf8: %s", arg->value.str);
+		key = i_strdup(str_c(mpctx->buf));
+		arg->context = (void *)key;
+	} else {
+		key = (char *)arg->context;
+	}
+
+	str_truncate(mpctx->buf, 0);
+	if (ictx->mail_ctx.normalizer(value,
+		strlen(value), mpctx->buf) >= 0)
+		value = str_c(mpctx->buf);
+
+	switch (arg->type) {
 	case SEARCH_MIME_FILENAME_IS:
 		return (strcmp(value, key) == 0 ? 1 : 0);
 	case SEARCH_MIME_FILENAME_CONTAINS:
@@ -270,6 +292,15 @@
 	}
 	i_unreached();
 }
+static void
+search_arg_mime_filename_deinit(
+	struct search_mimepart_context *mpctx ATTR_UNUSED,
+	struct mail_search_mime_arg *arg)
+{
+	char *key = (char *)arg->context;
+
+	i_free(key);
+}
 
 static int
 seach_arg_mime_param_match(const struct message_part_param *params,
@@ -426,8 +457,7 @@
 	case SEARCH_MIME_FILENAME_CONTAINS:
 	case SEARCH_MIME_FILENAME_BEGINS:
 	case SEARCH_MIME_FILENAME_ENDS:
-		return seach_arg_mime_filename_match(mpctx,
-			arg->type, arg->value.str);
+		return seach_arg_mime_filename_match(mpctx, arg);
 
 	case SEARCH_MIME_HEADER:
 	case SEARCH_MIME_BODY:
@@ -558,6 +588,40 @@
 
 	if (mpctx.pool != NULL)
 		pool_unref(&mpctx.pool);
+	if (mpctx.buf != NULL)
+		str_free(&mpctx.buf);
 	return ret;
 }
 
+static void
+search_mime_arg_deinit(struct mail_search_mime_arg *arg,
+			      struct search_mimepart_context *mpctx ATTR_UNUSED)
+{
+	switch (arg->type) {
+	case SEARCH_MIME_FILENAME_IS:
+	case SEARCH_MIME_FILENAME_CONTAINS:
+	case SEARCH_MIME_FILENAME_BEGINS:
+	case SEARCH_MIME_FILENAME_ENDS:
+		search_arg_mime_filename_deinit(mpctx, arg);
+		break;
+	default:
+		break;
+	}
+}
+
+void index_search_mime_arg_deinit(struct mail_search_arg *arg,
+	struct index_search_context *ctx)
+{
+	struct search_mimepart_context mpctx;
+	struct mail_search_mime_arg *args;
+
+	i_assert(arg->type == SEARCH_MIMEPART);
+	args = arg->value.mime_part->args;
+
+	i_zero(&mpctx);
+	mpctx.index_ctx = ctx;
+
+	mail_search_mime_args_reset(args, TRUE);
+	(void)mail_search_mime_args_foreach(args,
+		search_mime_arg_deinit, &mpctx);
+}
--- a/src/lib-storage/index/index-search-private.h	Wed Sep 20 01:47:38 2017 +0300
+++ b/src/lib-storage/index/index-search-private.h	Tue May 23 14:05:02 2017 +0200
@@ -42,5 +42,7 @@
 
 int index_search_mime_arg_match(struct mail_search_arg *args,
 	struct index_search_context *ctx);
+void index_search_mime_arg_deinit(struct mail_search_arg *arg,
+	struct index_search_context *ctx);
 
 #endif
--- a/src/lib-storage/index/index-search.c	Wed Sep 20 01:47:38 2017 +0300
+++ b/src/lib-storage/index/index-search.c	Tue May 23 14:05:02 2017 +0200
@@ -1317,13 +1317,18 @@
 
 static void ATTR_NULL(2)
 search_arg_deinit(struct mail_search_arg *arg,
-		  struct index_search_context *ctx ATTR_UNUSED)
+		  struct index_search_context *ctx)
 {
-	struct message_search_context *search_ctx = arg->context;
-
-	if (search_ctx != NULL) {
-		message_search_deinit(&search_ctx);
-		arg->context = NULL;
+	switch (arg->type) {
+	case SEARCH_MIMEPART:
+		index_search_mime_arg_deinit(arg, ctx);
+		break;
+	default:
+		if (arg->context != NULL) {
+			struct message_search_context *search_ctx = arg->context;
+			message_search_deinit(&search_ctx);
+			arg->context = NULL;
+		}
 	}
 }