]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-mail: Added message_search_more_get_decoded()
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Tue, 16 Feb 2016 15:48:53 +0000 (17:48 +0200)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Tue, 16 Feb 2016 15:54:49 +0000 (17:54 +0200)
src/lib-mail/Makefile.am
src/lib-mail/message-search.c
src/lib-mail/message-search.h
src/lib-mail/test-message-search.c [new file with mode: 0644]

index 6da8b9e63cff79e315e95e00992e25388b28fc10..96bd8bb7877b3253b4df5c7c195b18440853f4c0 100644 (file)
@@ -94,6 +94,7 @@ test_programs = \
        test-message-id \
        test-message-parser \
        test-message-part \
+       test-message-search \
        test-message-snippet \
        test-ostream-dot \
        test-qp-decoder \
@@ -180,6 +181,10 @@ test_message_part_SOURCES = test-message-part.c
 test_message_part_LDADD = message-part.lo message-parser.lo message-header-parser.lo message-size.lo rfc822-parser.lo rfc2231-parser.lo $(test_libs)
 test_message_part_DEPENDENCIES = $(test_deps)
 
+test_message_search_SOURCES = test-message-search.c
+test_message_search_LDADD = libmail.la ../lib-charset/libcharset.la $(test_libs)
+test_message_search_DEPENDENCIES = $(test_deps)
+
 test_message_snippet_SOURCES = test-message-snippet.c
 test_message_snippet_LDADD = message-snippet.lo mail-html2text.lo $(test_message_decoder_LDADD) message-parser.lo message-header-parser.lo message-header-decode.lo message-size.lo
 test_message_snippet_DEPENDENCIES = $(test_deps)
index 1f17519923ca27bebf4fec5eb019692e9163ed24..c78006cafa41af44c4e7e78bdab6608bf6889076 100644 (file)
@@ -109,9 +109,21 @@ static bool message_search_more_decoded2(struct message_search_context *ctx,
 
 bool message_search_more(struct message_search_context *ctx,
                         struct message_block *raw_block)
+{
+       struct message_block decoded_block;
+
+       return message_search_more_get_decoded(ctx, raw_block, &decoded_block);
+}
+
+bool message_search_more_get_decoded(struct message_search_context *ctx,
+                                    struct message_block *raw_block,
+                                    struct message_block *decoded_block_r)
 {
        struct message_header_line *hdr = raw_block->hdr;
-       struct message_block block;
+       struct message_block decoded_block;
+
+       memset(decoded_block_r, 0, sizeof(*decoded_block_r));
+       decoded_block_r->part = raw_block->part;
 
        if (raw_block->part != ctx->prev_part) {
                /* part changes. we must change this before looking at
@@ -143,16 +155,18 @@ bool message_search_more(struct message_search_context *ctx,
                if (!ctx->content_type_text)
                        return FALSE;
        }
-       if (!message_decoder_decode_next_block(ctx->decoder, raw_block, &block))
+       if (!message_decoder_decode_next_block(ctx->decoder, raw_block,
+                                              &decoded_block))
                return FALSE;
 
-       if (block.hdr != NULL &&
+       if (decoded_block.hdr != NULL &&
            (ctx->flags & MESSAGE_SEARCH_FLAG_SKIP_HEADERS) != 0) {
                /* Content-* header */
                return FALSE;
        }
 
-       return message_search_more_decoded2(ctx, &block);
+       *decoded_block_r = decoded_block;
+       return message_search_more_decoded2(ctx, &decoded_block);
 }
 
 bool message_search_more_decoded(struct message_search_context *ctx,
index c3efed97ae8b00bd9a5ed004ef09ca04735a2c16..5c0c949d5c4951fa255947bc215d259ddbb8f988 100644 (file)
@@ -20,6 +20,12 @@ void message_search_deinit(struct message_search_context **ctx);
 /* Returns TRUE if key is found from input buffer, FALSE if not. */
 bool message_search_more(struct message_search_context *ctx,
                         struct message_block *raw_block);
+/* Same as message_search_more(), but return the decoded block. If the same
+   input is being fed to multiple searches, this avoids duplicating the work
+   by doing the following searches with message_search_more_decoded() */
+bool message_search_more_get_decoded(struct message_search_context *ctx,
+                                    struct message_block *raw_block,
+                                    struct message_block *decoded_block_r);
 /* The data has already passed through decoder. */
 bool message_search_more_decoded(struct message_search_context *ctx,
                                 struct message_block *block);
diff --git a/src/lib-mail/test-message-search.c b/src/lib-mail/test-message-search.c
new file mode 100644 (file)
index 0000000..401d513
--- /dev/null
@@ -0,0 +1,61 @@
+/* Copyright (c) 2016 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "str.h"
+#include "unichar.h"
+#include "message-parser.h"
+#include "message-search.h"
+#include "test-common.h"
+
+static void test_message_search_more_get_decoded(void)
+{
+       const char input[] = "p\xC3\xB6\xC3\xB6";
+       const unsigned char text_plain[] = "text/plain; charset=utf-8";
+       struct message_search_context *ctx1, *ctx2;
+       struct message_block raw_block, decoded_block;
+       struct message_header_line hdr;
+       struct message_part part;
+       unsigned int i;
+
+       test_begin("message_search_more_get_decoded()");
+
+       ctx1 = message_search_init("p\xC3\xA4\xC3\xA4", NULL, 0);
+       ctx2 = message_search_init("p\xC3\xB6\xC3\xB6", NULL, 0);
+
+       memset(&raw_block, 0, sizeof(raw_block));
+       raw_block.part = &part;
+
+       /* feed the Content-Type header */
+       memset(&hdr, 0, sizeof(hdr));
+       hdr.name = "Content-Type"; hdr.name_len = strlen(hdr.name);
+       hdr.value = hdr.full_value = text_plain;
+       hdr.value_len = hdr.full_value_len = sizeof(text_plain)-1;
+       raw_block.hdr = &hdr;
+       test_assert(!message_search_more_get_decoded(ctx1, &raw_block, &decoded_block));
+       test_assert(!message_search_more_decoded(ctx2, &decoded_block));
+
+       /* EOH */
+       raw_block.hdr = NULL;
+       test_assert(!message_search_more_get_decoded(ctx1, &raw_block, &decoded_block));
+       test_assert(!message_search_more_decoded(ctx2, &decoded_block));
+
+       /* body */
+       raw_block.size = 1;
+       for (i = 0; input[i] != '\0'; i++) {
+               raw_block.data = (const void *)&input[i];
+               test_assert(!message_search_more_get_decoded(ctx1, &raw_block, &decoded_block));
+               test_assert(message_search_more_decoded(ctx2, &decoded_block) == (input[i+1] == '\0'));
+       }
+       message_search_deinit(&ctx1);
+       message_search_deinit(&ctx2);
+       test_end();
+}
+
+int main(void)
+{
+       static void (*test_functions[])(void) = {
+               test_message_search_more_get_decoded,
+               NULL
+       };
+       return test_run(test_functions);
+}