]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-mail: message_header_encode_[bq]() now explicitly takes the first line length...
authorTimo Sirainen <tss@iki.fi>
Sun, 11 May 2014 18:08:51 +0000 (21:08 +0300)
committerTimo Sirainen <tss@iki.fi>
Sun, 11 May 2014 18:08:51 +0000 (21:08 +0300)
So this change partially reverts the previous change, because
message_header_encode() was actually internally relying on this behavior.
The explicit parameter makes it clearer.

src/lib-mail/message-header-encode.c
src/lib-mail/message-header-encode.h
src/lib-mail/test-message-header-encode.c

index 06c601b0be57a25744d3f0d7ab9d78a9c0fe708a..1dabffb374a90fbec2b41e459d53fbf2f1e2eb3c 100644 (file)
@@ -29,12 +29,20 @@ static bool input_idx_need_encoding(const unsigned char *input,
 }
 
 void message_header_encode_q(const unsigned char *input, unsigned int len,
-                            string_t *output)
+                            string_t *output, unsigned int first_line_len)
 {
        unsigned int i, line_len_left;
 
-       str_append(output, "=?utf-8?q?");
        line_len_left = MIME_MAX_LINE_LEN - MIME_WRAPPER_LEN;
+
+       if (first_line_len >= MIME_MAX_LINE_LEN - MIME_WRAPPER_LEN - 3) {
+               str_append(output, "\n\t");
+               line_len_left--;
+       } else {
+               line_len_left -= first_line_len;
+       }
+
+       str_append(output, "=?utf-8?q?");
        for (i = 0; i < len; i++) {
                if (line_len_left < 3) {
                        /* if we're not at the beginning of a character,
@@ -72,12 +80,18 @@ void message_header_encode_q(const unsigned char *input, unsigned int len,
 }
 
 void message_header_encode_b(const unsigned char *input, unsigned int len,
-                            string_t *output)
+                            string_t *output, unsigned int first_line_len)
 {
-       unsigned int line_len_left, max;
+       unsigned int line_len, line_len_left, max;
+
+       line_len = first_line_len;
+       if (line_len >= MIME_MAX_LINE_LEN - MIME_WRAPPER_LEN) {
+               str_append(output, "\n\t");
+               line_len = 1;
+       }
 
-       line_len_left = MIME_MAX_LINE_LEN - MIME_WRAPPER_LEN;
        for (;;) {
+               line_len_left = MIME_MAX_LINE_LEN - MIME_WRAPPER_LEN - line_len;
                max = MAX_BASE64_DECODED_SIZE(line_len_left);
                do {
                        max--;
@@ -105,7 +119,7 @@ void message_header_encode_b(const unsigned char *input, unsigned int len,
                        break;
 
                str_append(output, "\n\t");
-               line_len_left = MIME_MAX_LINE_LEN - MIME_WRAPPER_LEN - 1;
+               line_len = 1;
        }
 }
 
@@ -155,9 +169,12 @@ void message_header_encode_data(const unsigned char *input, unsigned int len,
 
        /* and do it */
        str_append_data(output, input, first_idx);
-       if (use_q)
-               message_header_encode_q(input + first_idx, enc_len, output);
-       else
-               message_header_encode_b(input + first_idx, enc_len, output);
+       if (use_q) {
+               message_header_encode_q(input + first_idx, enc_len,
+                                       output, first_idx);
+       } else {
+               message_header_encode_b(input + first_idx, enc_len,
+                                       output, first_idx);
+       }
        str_append_data(output, input + last_idx, len - last_idx);
 }
index 640f878922c0c2c1c64ff0f102f85f506d089e5e..ba7c54988aeac2aea84c4ff19b2fc220cee3cdb7 100644 (file)
@@ -1,16 +1,18 @@
 #ifndef MESSAGE_HEADER_ENCODE_H
 #define MESSAGE_HEADER_ENCODE_H
 
-/* Encode UTF-8 input into output wherever necessary. */
+/* Encode UTF-8 input into output wherever necessary using either Q or B
+   encoding depending on which takes less space (approximately). */
 void message_header_encode(const char *input, string_t *output);
 void message_header_encode_data(const unsigned char *input, unsigned int len,
                                string_t *output);
 
 /* Encode the whole UTF-8 input using "Q" or "B" encoding into output.
-   The output is split into multiple lines if necessary (max 76 chars/line). */
+   The output is split into multiple lines if necessary (max 76 chars/line).
+   The first line's length is given as parameter. */
 void message_header_encode_q(const unsigned char *input, unsigned int len,
-                            string_t *output);
+                            string_t *output, unsigned int first_line_len);
 void message_header_encode_b(const unsigned char *input, unsigned int len,
-                            string_t *output);
+                            string_t *output, unsigned int first_line_len);
 
 #endif
index 30c7cf3a64b88f820410d784c20e691fddf07cf9..13df05adf7c86739205792aa0c2b2e2bac026e1b 100644 (file)
@@ -67,7 +67,8 @@ static void test_message_header_encode_q(void)
                                str_append_c(str, ' ');
 
                        message_header_encode_q(str_data(input) + skip,
-                                               str_len(input) - skip, str);
+                                               str_len(input) - skip, str,
+                                               i == 0 ? 0 : i+1);
                        test_assert(verify_q(str_c(str), i, !skip));
                }
        }
@@ -153,7 +154,8 @@ static void test_message_header_encode_b(void)
                                str_append_c(str, ' ');
 
                        message_header_encode_b(str_data(input) + skip,
-                                               str_len(input) - skip, str);
+                                               str_len(input) - skip, str,
+                                               i == 0 ? 0 : i+1);
                        test_assert(verify_b(str_c(str), i, !skip));
                }
        }