]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
message-decoder now supports optionally returning non-text bodyparts as-is.
authorTimo Sirainen <tss@iki.fi>
Mon, 18 May 2009 17:09:25 +0000 (13:09 -0400)
committerTimo Sirainen <tss@iki.fi>
Mon, 18 May 2009 17:09:25 +0000 (13:09 -0400)
--HG--
branch : HEAD

src/lib-mail/message-decoder.c
src/lib-mail/message-decoder.h
src/lib-mail/message-search.c
src/plugins/fts/fts-storage.c

index 409b19bdff49e4b5eaef48b778937220e33959c9..47c3c64c154b76894b46b9b059eec0f4da7d196c 100644 (file)
@@ -28,6 +28,7 @@ enum content_type {
 #define MAX_TRANSLATION_BUF_SIZE 10
 
 struct message_decoder_context {
+       enum message_decoder_flags flags;
        struct message_part *prev_part;
 
        struct message_header_line hdr;
@@ -44,16 +45,17 @@ struct message_decoder_context {
        char *content_charset;
        enum content_type content_type;
 
-       unsigned int dtcase:1;
        unsigned int charset_utf8:1;
+       unsigned int binary_input:1;
 };
 
-struct message_decoder_context *message_decoder_init(bool dtcase)
+struct message_decoder_context *
+message_decoder_init(enum message_decoder_flags flags)
 {
        struct message_decoder_context *ctx;
 
        ctx = i_new(struct message_decoder_context, 1);
-       ctx->dtcase = dtcase;
+       ctx->flags = flags;
        ctx->buf = buffer_create_dynamic(default_pool, 8192);
        ctx->buf2 = buffer_create_dynamic(default_pool, 8192);
        return ctx;
@@ -139,6 +141,7 @@ static bool message_decode_header(struct message_decoder_context *ctx,
                                  struct message_header_line *hdr,
                                  struct message_block *output)
 {
+       bool dtcase = (ctx->flags & MESSAGE_DECODER_FLAG_DTCASE) != 0;
        size_t value_len;
 
        if (hdr->continues) {
@@ -157,10 +160,10 @@ static bool message_decode_header(struct message_decoder_context *ctx,
 
        buffer_set_used_size(ctx->buf, 0);
        message_header_decode_utf8(hdr->full_value, hdr->full_value_len,
-                                  ctx->buf, ctx->dtcase);
+                                  ctx->buf, dtcase);
        value_len = ctx->buf->used;
 
-       if (ctx->dtcase) {
+       if (dtcase) {
                (void)uni_utf8_to_decomposed_titlecase(hdr->name, hdr->name_len,
                                                       ctx->buf);
                buffer_append_c(ctx->buf, '\0');
@@ -170,7 +173,7 @@ static bool message_decode_header(struct message_decoder_context *ctx,
        ctx->hdr.full_value = ctx->buf->data;
        ctx->hdr.full_value_len = value_len;
        ctx->hdr.value_len = 0;
-       if (ctx->dtcase) {
+       if (dtcase) {
                ctx->hdr.name = CONST_PTR_OFFSET(ctx->buf->data,
                                                 ctx->hdr.full_value_len);
                ctx->hdr.name_len = ctx->buf->used - 1 - value_len;
@@ -210,7 +213,9 @@ static void translation_buf_decode(struct message_decoder_context *ctx,
        ctx->translation_size = 0;
 }
 
-static void message_decode_body_init_charset(struct message_decoder_context *ctx)
+static void
+message_decode_body_init_charset(struct message_decoder_context *ctx,
+                                struct message_part *part)
 {
        enum charset_flags flags;
 
@@ -225,9 +230,17 @@ static void message_decode_body_init_charset(struct message_decoder_context *ctx
 
        if (ctx->charset_trans != NULL)
                charset_to_utf8_end(&ctx->charset_trans);
-       i_free(ctx->charset_trans_charset);
+       i_free_and_null(ctx->charset_trans_charset);
+
+       ctx->binary_input = ctx->content_charset == NULL &&
+               (ctx->flags & MESSAGE_DECODER_FLAG_RETURN_BINARY) != 0 &&
+               (part->flags & (MESSAGE_PART_FLAG_TEXT |
+                               MESSAGE_PART_FLAG_MESSAGE_RFC822)) == 0;
+       if (ctx->binary_input)
+               return;
 
-       flags = ctx->dtcase ? CHARSET_FLAG_DECOMP_TITLECASE : 0;
+       flags = (ctx->flags & MESSAGE_DECODER_FLAG_DTCASE) != 0 ?
+               CHARSET_FLAG_DECOMP_TITLECASE : 0;
        ctx->charset_trans_charset = i_strdup(ctx->content_charset != NULL ?
                                              ctx->content_charset : "UTF-8");
        if (charset_to_utf8_begin(ctx->charset_trans_charset,
@@ -318,9 +331,12 @@ static bool message_decode_body(struct message_decoder_context *ctx,
                ctx->encoding_size = 0;
        }
 
-       if (ctx->charset_utf8) {
+       if (ctx->binary_input) {
+               output->data = data;
+               output->size = size;
+       } else if (ctx->charset_utf8) {
                buffer_set_used_size(ctx->buf2, 0);
-               if (ctx->dtcase) {
+               if ((ctx->flags & MESSAGE_DECODER_FLAG_DTCASE) != 0) {
                        (void)uni_utf8_to_decomposed_titlecase(data, size,
                                                               ctx->buf2);
                        output->data = ctx->buf2->data;
@@ -384,7 +400,7 @@ bool message_decoder_decode_next_block(struct message_decoder_context *ctx,
        else {
                output->hdr = NULL;
                output->size = 0;
-               message_decode_body_init_charset(ctx);
+               message_decode_body_init_charset(ctx, input->part);
                return TRUE;
        }
 }
index 317160e7d56655df4c9ae4389a9c345c6a4a500c..4961d9350743281470d0ff9e2e035b45318753b8 100644 (file)
@@ -1,13 +1,20 @@
 #ifndef MESSAGE_DECODER_H
 #define MESSAGE_DECODER_H
 
+enum message_decoder_flags {
+       /* Return all headers and parts through
+          uni_utf8_to_decomposed_titlecase() */
+       MESSAGE_DECODER_FLAG_DTCASE             = 0x01,
+       /* Return binary MIME parts as-is without any conversion. */
+       MESSAGE_DECODER_FLAG_RETURN_BINARY      = 0x02
+};
+
 struct message_block;
 
 /* Decode message's contents as UTF-8, both the headers and the MIME bodies.
-   The bodies are decoded from quoted-printable and base64 formats if needed.
-   If dtcase=TRUE, the data is returned through
-   uni_utf8_to_decomposed_titlecase(). */
-struct message_decoder_context *message_decoder_init(bool dtcase);
+   The bodies are decoded from quoted-printable and base64 formats if needed. */
+struct message_decoder_context *
+message_decoder_init(enum message_decoder_flags flags);
 void message_decoder_deinit(struct message_decoder_context **ctx);
 
 /* Decode input and return decoded output. Headers are returned only in their
index af5ae022cac350771f5c91778751154d1182ccea..8e4f929670d6dcb316a5ad331a98bb894cd8773d 100644 (file)
@@ -46,7 +46,7 @@ message_search_init_real(const char *key, const char *charset,
                ctx->key_len = str_len(key_utf8);
                ctx->key_charset = i_strdup(charset);
                ctx->flags = flags;
-               ctx->decoder = message_decoder_init(TRUE);
+               ctx->decoder = message_decoder_init(MESSAGE_DECODER_FLAG_DTCASE);
                ctx->str_find_ctx = str_find_init(default_pool, ctx->key);
                ret = 1;
        }
index a0253a6cfce4d9694cb83c7f20b8f771ad57f5be..de20f98ddfa0995b2366116b0ccc75d9a7d839ab 100644 (file)
@@ -126,7 +126,7 @@ static int fts_build_mail(struct fts_storage_build_context *ctx, uint32_t uid)
        parser = message_parser_init(pool_datastack_create(), input,
                                     MESSAGE_HEADER_PARSER_FLAG_CLEAN_ONELINE,
                                     0);
-       decoder = message_decoder_init(TRUE);
+       decoder = message_decoder_init(MESSAGE_DECODER_FLAG_DTCASE);
        for (;;) {
                ret = message_parser_parse_next_block(parser, &raw_block);
                i_assert(ret != 0);