]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-mail: Extend quoted-printable encoding tests
authorMarkus Valentin <markus.valentin@open-xchange.com>
Mon, 9 Nov 2020 11:35:09 +0000 (12:35 +0100)
committertimo.sirainen <timo.sirainen@open-xchange.com>
Tue, 1 Dec 2020 14:36:26 +0000 (14:36 +0000)
src/lib-mail/test-istream-qp-encoder.c
src/lib-mail/test-qp-encoder.c

index fb4e5fa77c4d49c230e616c1466b0a26dd363912..148fe24f956ce5c95b13fac6c936b81b4f1b20d0 100644 (file)
@@ -5,6 +5,9 @@
 #include "istream-private.h"
 #include "istream-qp.h"
 
+#define WHITESPACE10 "   \t   \t \t"
+#define WHITESPACE70 WHITESPACE10 WHITESPACE10 WHITESPACE10 WHITESPACE10 WHITESPACE10 WHITESPACE10 WHITESPACE10
+
 static const struct {
        const void *input;
        const char *output;
@@ -63,6 +66,11 @@ static const struct {
          "chov=C3=A1n=C3=AD =C3=BAstavy a ku blahu v=C5=A1ech.",
          0
        },
+       /* Test line breaking */
+       { WHITESPACE70"1234567", WHITESPACE70"123=\r\n4567", 0 },
+       { WHITESPACE70"      7", WHITESPACE70" =20=\r\n    7", 0 },
+       { WHITESPACE70""WHITESPACE10"1", WHITESPACE70" =20=\r\n \t   \t \t1", 0 },
+
 };
 
 static void
@@ -101,7 +109,28 @@ encode_test(const char *qp_input, const char *output, int stream_errno,
 
        test_assert(ret == -1);
        test_assert(input->stream_errno == stream_errno);
-       test_assert(strcmp(str_c(str), output) == 0);
+       test_assert_strcmp(str_c(str), output);
+
+       if (stream_errno == 0) {
+               /* Test seeking on streams where the testcases do not
+                * expect a specific errno already. */
+               uoff_t v_off = input->v_offset;
+               /* Seeking backwards */
+               i_stream_seek(input, 0);
+               test_assert(input->v_offset == 0);
+
+               /* Seeking forward */
+               i_stream_seek(input, v_off+1);
+               test_assert(input->stream_errno == ESPIPE);
+       }
+
+       i_stream_unref(&input);
+       /* Test closing stream gives expected results */
+       i_stream_seek(input_data, 0);
+       input = i_stream_create_qp_encoder(input_data, 0);
+       i_stream_close(input);
+       test_assert(input->closed);
+       test_assert(i_stream_read_more(input, &data, &size) == -1);
 
        i_stream_unref(&input);
        i_stream_unref(&input_data);
index 1117cf0979220d24e5a3c3e39fc1ee28d9c67d1b..bb31b1e517d45f004c49a260bb69dd107239b1ca 100644 (file)
@@ -9,21 +9,72 @@ struct test_quoted_printable_encode_data {
        const void *input;
        size_t input_len;
        const char *output;
+       size_t max_line_len;
 };
 
 static void test_qp_encoder(void)
 {
+#define WHITESPACE10 "   \t   \t \t"
+#define WHITESPACE70 WHITESPACE10 WHITESPACE10 WHITESPACE10 WHITESPACE10 WHITESPACE10 WHITESPACE10 WHITESPACE10
        static struct test_quoted_printable_encode_data tests[] = {
-               { "", 0, "" },
-               { "a", 1, "a" },
-               { "a b \r c d", 9, "a b =0D c d" },
-               { "a b \n c d", 9, "a b \r\n c d" },
+               { "", 0, "", 20 },
+               { "a", 1, "a", 20 },
+               { "a b \r c d", 9, "a b =0D c d", 20 },
+               { "a b c d\r", 8, "a b c d=0D", 20 },
+               { "a b \n c d", 9, "a b \r\n c d", 20 },
                {
                  "test wrap at max 20 characters tab\ttoo", 38,
-                 "test wrap at max=20=\r\n20 characters tab=09=\r\ntoo"
+                 "test wrap at max=20=\r\n20 characters tab=09=\r\ntoo",
+                  20
+               },
+               { "Invalid UTF-8 sequence in \x99", 27, "Invalid UTF-8 sequ=\r\nence in =99", 20 },
+               { "keep CRLF\r\non two lines", 23, "keep CRLF\r\non two lines", 20 },
+               /* Trailing whitespace should be followed by encoded char. */
+               { "Keep trailing whitesp\xC3\xA4""ce ", 26, "Keep trailing whit=\r\nesp=C3=A4ce =", 20 },
+               { "Keep trailing whitesp\xC3\xA4""ce\t", 26, "Keep trailing whitesp=C3=A4ce\t=", 67 },
+               { "Keep trailing whitesp\xC3\xA4""ce ", 26, "Keep trailing whitesp=C3=A4ce =", 67 },
+               { "Keep trailing whitesp\xC3\xA4""ce   ", 28, "Keep trailing whitesp=C3=A4ce   =", 67 },
+               { "Keep trailing whitesp\xC3\xA4""ce \t ", 28, "Keep trailing whitesp=C3=A4ce \t =", 67 },
+               { "Keep trailing whitesp\xC3\xA4""ce    ", 29, "Keep trailing whitesp=C3=A4ce    =", 67 },
+               { "Keep trailing whitesp\xC3\xA4""ce     ", 30, "Keep trailing whitesp=C3=A4ce     =", 67 },
+               { "Keep trailing whitesp\xC3\xA4""ce      ", 31, "Keep trailing whitesp=C3=A4ce      =", 67 },
+               /* Test line breaking */
+               { WHITESPACE70"1234567", 77, WHITESPACE70"1234=\r\n567", 76 },
+               { WHITESPACE70"      7", 77, WHITESPACE70"  =20=\r\n   7", 76 },
+               { WHITESPACE70""WHITESPACE10"1", 81, WHITESPACE70"  =20=\r\n\t   \t \t1", 76 },
+               /* Control characters */
+               { "\x0C\x07", 2, "=0C=07", 20},
+               /* Data */
+               { "\xDE\xAD\xBE\xEF""deadbeef", 12 ,"=DE=AD=BE=EFdeadbe=\r\nef", 20 },
+               { "\xDE""de""\xAD""ad""\xBE""be""\xEF""ef", 12 ,"=DEde=ADad=BEbe=EF=\r\nef", 20 },
+               /* boundary delimiter */
+               { "___________ \xc3\x9c", 14, "___________ =C3=9C", 20 },
+               { "----------- \xc3\x9c", 14, "----------- =C3=9C", 20 },
+               { "=---------- \xc3\x9c", 14, "=3D---------- =C3=\r\n=9C", 20 },
+               { "=__________ \xc3\x9c", 14, "=3D__________ =C3=\r\n=9C", 20 },
+               /* mixed inputs */
+               { "\xed\xae\x80\xed\xbf\xbf", 6, "=ED=AE=80=ED=BF=BF", 20 },
+               { "f\x6f\x6f""bar\xae\x80\xed\xbf\xbf", 11, "foobar=AE=80=ED=BF=\r\n=BF", 20 },
+               {
+                       "\xc3\x9c""ber\x6d\xc3\xa4\xc3\x9f\x69\x67\x0a\xe0\x80\x80 \xf0\x9d\x84\x9e", 21,
+                       "=C3=9Cberm=C3=A4=C3=9Fig\r\n=E0=80=80 =F0=9D=84=9E",
+                       76
+               },
+               {
+                       "\xc3\x9c""ber\x6d\xc3\xa4\xc3\x9f\x69\x67\x0a\xe0\x80\x80 \xf0\x9d\x84\x9e", 21,
+                       "=C3=9Cberm=C3=A4=\r\n=C3=9Fig\r\n=E0=80=80 =F0=9D=\r\n=84=9E",
+                       20
+               },
+               {
+                       "\xc3\x9c""ber\x6dä\xc3\x9fi\x0a\xe0g\x80\x80 \xf0\x9d\x84\x9e", 21,
+                       "=C3=9Cberm=C3=A4=C3=9Fi\r\n=E0g=80=80 =F0=9D=84=9E",
+                       76
+               },
+               {
+                       "\xc3\x9c""ber\x6dä\xc3\xff\x9fi\x0a\xe0g\x80\x80\xfe\xf0\x9d\x84\x9e", 22,
+                       "=C3=9Cberm=C3=A4=C3=FF=9Fi\r\n=E0g=80=80=FE=F0=9D=84=9E",
+                       76
                },
-               { "Invalid UTF-8 sequence in \x99", 27, "Invalid UTF-8 sequ=\r\nence in =99" },
-               { "keep CRLF\r\non two lines", 23, "keep CRLF\r\non two lines" },
        };
        string_t *str;
        unsigned int i, j;
@@ -32,13 +83,13 @@ static void test_qp_encoder(void)
        str = t_str_new(128);
        for (i = 0; i < N_ELEMENTS(tests); i++) {
                const unsigned char *input = tests[i].input;
-               struct qp_encoder *qp = qp_encoder_init(str, 20, 0);
+               struct qp_encoder *qp = qp_encoder_init(str, tests[i].max_line_len, 0);
 
                /* try all at once */
                qp_encoder_more(qp, input, tests[i].input_len);
                qp_encoder_finish(qp);
 
-               test_assert_idx(strcmp(str_c(str), tests[i].output) == 0, i);
+               test_assert_strcmp_idx(str_c(str), tests[i].output, i);
 
                /* try in small pieces */
                str_truncate(str, 0);
@@ -47,7 +98,7 @@ static void test_qp_encoder(void)
                        qp_encoder_more(qp, &c, 1);
                }
                qp_encoder_finish(qp);
-               test_assert_idx(strcmp(str_c(str), tests[i].output) == 0, i);
+               test_assert_strcmp_idx(str_c(str), tests[i].output, i);
 
                qp_encoder_deinit(&qp);
                str_truncate(str, 0);
@@ -58,11 +109,12 @@ static void test_qp_encoder(void)
 static void test_qp_encoder_binary(void)
 {
        static struct test_quoted_printable_encode_data tests[] = {
-               { "\0nil\0delimited\0string\0", 22, "=00nil=00delimited=\r\n=00string=00" },
+               { "\0nil\0delimited\0string\0", 22, "=00nil=00delimited=\r\n=00string=00" ,20 },
                {
                  "\xef\x4e\xc5\xe0\x31\x66\xd7\xef\xae\x12\x7d\x45\x1e\x05\xc7\x2a",
                  16,
-                 "=EFN=C5=E01f=D7=EF=\r\n=AE=12}E=1E=05=C7*"
+                 "=EFN=C5=E01f=D7=EF=\r\n=AE=12}E=1E=05=C7*",
+                 20
                },
        };
 
@@ -73,7 +125,7 @@ static void test_qp_encoder_binary(void)
        str = t_str_new(128);
        for (i = 0; i < N_ELEMENTS(tests); i++) {
                const unsigned char *input = tests[i].input;
-               struct qp_encoder *qp = qp_encoder_init(str, 20, QP_ENCODER_FLAG_BINARY_DATA);
+               struct qp_encoder *qp = qp_encoder_init(str, tests[i].max_line_len, QP_ENCODER_FLAG_BINARY_DATA);
 
                /* try all at once */
                qp_encoder_more(qp, input, tests[i].input_len);
@@ -99,14 +151,15 @@ static void test_qp_encoder_binary(void)
 static void test_qp_encoder_header(void)
 {
         static struct test_quoted_printable_encode_data tests[] = {
-               { "simple", 6, "=?utf-8?Q?simple?=" },
-               { "J'esuis de paris caf\xc3\xa9", 22, "=?utf-8?Q?J'esuis_de_paris_caf=C3=A9?=" },
-               { "hello_world", 11, "=?utf-8?Q?hello=5Fworld?=" },
+               { "simple", 6, "=?utf-8?Q?simple?=", 75 },
+               { "J'esuis de paris caf\xc3\xa9", 22, "=?utf-8?Q?J'esuis_de_paris_caf=C3=A9?=", 75 },
+               { "hello_world", 11, "=?utf-8?Q?hello=5Fworld?=", 75 },
                {
                  "make sure this wraps and that the actual lines are not longer than maximum length including preamble",
                  100,
                  "=?utf-8?Q?make_sure_this_wraps_and_that_the_actual_lines_are_not_longer_t?=\r\n"
-                 " =?utf-8?Q?han_maximum_length_including_preamble?="
+                 " =?utf-8?Q?han_maximum_length_including_preamble?=",
+                 75
                },
         };
 
@@ -117,7 +170,7 @@ static void test_qp_encoder_header(void)
         str = t_str_new(128);
         for (i = 0; i < N_ELEMENTS(tests); i++) {
                 const unsigned char *input = tests[i].input;
-                struct qp_encoder *qp = qp_encoder_init(str, 75, QP_ENCODER_FLAG_HEADER_FORMAT);
+                struct qp_encoder *qp = qp_encoder_init(str, tests[i].max_line_len, QP_ENCODER_FLAG_HEADER_FORMAT);
 
                 /* try all at once */
                 qp_encoder_more(qp, input, tests[i].input_len);