From 121f820aeb2f25c563a5dcbcf353a7b0e9a7e6e1 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Tue, 16 Feb 2016 17:48:53 +0200 Subject: [PATCH] lib-mail: Added message_search_more_get_decoded() --- src/lib-mail/Makefile.am | 5 +++ src/lib-mail/message-search.c | 22 +++++++++-- src/lib-mail/message-search.h | 6 +++ src/lib-mail/test-message-search.c | 61 ++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 4 deletions(-) create mode 100644 src/lib-mail/test-message-search.c diff --git a/src/lib-mail/Makefile.am b/src/lib-mail/Makefile.am index 6da8b9e63c..96bd8bb787 100644 --- a/src/lib-mail/Makefile.am +++ b/src/lib-mail/Makefile.am @@ -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) diff --git a/src/lib-mail/message-search.c b/src/lib-mail/message-search.c index 1f17519923..c78006cafa 100644 --- a/src/lib-mail/message-search.c +++ b/src/lib-mail/message-search.c @@ -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, diff --git a/src/lib-mail/message-search.h b/src/lib-mail/message-search.h index c3efed97ae..5c0c949d5c 100644 --- a/src/lib-mail/message-search.h +++ b/src/lib-mail/message-search.h @@ -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 index 0000000000..401d513e23 --- /dev/null +++ b/src/lib-mail/test-message-search.c @@ -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 = ∂ + + /* 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); +}