]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
quoted-printable decode didn't ignore whitespace at the end of soft line break.
authorTimo Sirainen <tss@iki.fi>
Fri, 10 Aug 2012 04:31:28 +0000 (07:31 +0300)
committerTimo Sirainen <tss@iki.fi>
Fri, 10 Aug 2012 04:31:28 +0000 (07:31 +0300)
src/lib-mail/quoted-printable.c
src/lib-mail/test-quoted-printable.c

index 6a6214762c6ad05d17c829161944e7331b4e7a09..edab5e733d055e0d5ec38e5e58dd4e62bae0ea2b 100644 (file)
@@ -8,11 +8,31 @@
 #define QP_IS_TRAILING_SPACE(c) \
        ((c) == ' ' || (c) == '\t')
 
+static int
+qp_is_end_of_line(const unsigned char *src, size_t *src_pos, size_t size)
+{
+       size_t i = *src_pos;
+
+       i_assert(src[i] == '=');
+       for (i++; i < size; i++) {
+               if (QP_IS_TRAILING_SPACE(src[i]) || src[i] == '\r')
+                       continue;
+
+               if (src[i] != '\n')
+                       return 0;
+
+               *src_pos = i;
+               return 1;
+       }
+       return -1;
+}
+
 void quoted_printable_decode(const unsigned char *src, size_t src_size,
                             size_t *src_pos_r, buffer_t *dest)
 {
        char hexbuf[3];
        size_t src_pos, pos, next;
+       int ret;
 
        hexbuf[2] = '\0';
 
@@ -38,25 +58,17 @@ void quoted_printable_decode(const unsigned char *src, size_t src_size,
                buffer_append(dest, src + next, src_pos - next);
                next = src_pos;
 
-               if (src_pos+1 >= src_size)
-                       break;
-
-               if (src[src_pos+1] == '\n') {
-                       /* =\n -> skip both */
-                       src_pos++;
-                       next += 2;
+               if ((ret = qp_is_end_of_line(src, &src_pos, src_size)) > 0) {
+                       /* =[whitespace][\r]\n */
+                       next = src_pos+1;
                        continue;
                }
-
-               if (src_pos+2 >= src_size)
+               if (ret < 0) {
+                       /* unknown yet if this is end of line */
                        break;
-
-               if (src[src_pos+1] == '\r' && src[src_pos+2] == '\n') {
-                       /* =\r\n -> skip both */
-                       src_pos += 2;
-                       next += 3;
-                       continue;
                }
+               if (src_pos+2 >= src_size)
+                       break;
 
                /* =<hex> */
                hexbuf[0] = src[src_pos+1];
index 2270d738a0373c4ae2fffb53a12bf5f9261a85b0..4587fb0e5a1cadeecb09a7b851db6b299e6e5de0 100644 (file)
@@ -16,9 +16,9 @@ static void test_quoted_printable_decode(void)
 {
        static struct test_quoted_printable_decode_data data[] = {
                { "foo  \r\nbar=", "foo\r\nbar", 1 },
-               { "foo =\nbar", "foo bar", 0 },
-               { "foo =\n=01", "foo \001", 0 },
-               { "foo =\r\nbar", "foo bar", 0 },
+               { "foo\t=\nbar", "foo\tbar", 0 },
+               { "foo = \n=01", "foo \001", 0 },
+               { "foo =\t\r\nbar", "foo bar", 0 },
                { "foo =\r\n=01", "foo \001", 0 },
                { "foo  \nbar=", "foo\r\nbar", 1 },
                { "=0A=0D  ", "\n\r", 2 },