]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-mail: rfc2231_parse() - Replace NULs with 0x80
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Sat, 21 Apr 2018 13:47:16 +0000 (16:47 +0300)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Thu, 30 Aug 2018 08:13:18 +0000 (11:13 +0300)
Instead of truncating the strings at NULs.

src/lib-mail/rfc2231-parser.c
src/lib-mail/rfc2231-parser.h
src/lib-mail/test-rfc2231-parser.c

index e940b9492ffdab9773c454dd55b17534403777e7..9b6cd4d360221d62864efc191e813914f19cde80 100644 (file)
@@ -47,8 +47,14 @@ int rfc2231_parse(struct rfc822_parser_context *ctx,
        string_t *str;
        unsigned int i, j, count, next, next_idx;
        bool ok, have_extended, broken = FALSE;
+       char prev_replacement_char;
        int ret;
 
+       /* Temporarily replace the nul_replacement_char while we're parsing
+          the content-params. It'll be restored before we return. */
+       prev_replacement_char = ctx->nul_replacement_char;
+       ctx->nul_replacement_char = RFC822_NUL_REPLACEMENT_CHAR;
+
        /* Get a list of all parameters. RFC 2231 uses key*<n>[*]=value pairs,
           which we want to merge to a key[*]=value pair. Save them to a
           separate array. */
@@ -97,6 +103,7 @@ int rfc2231_parse(struct rfc822_parser_context *ctx,
                        array_append(&result, &value, 1);
                }
        }
+       ctx->nul_replacement_char = prev_replacement_char;
 
        if (array_count(&rfc2231_params_arr) == 0) {
                /* No RFC 2231 parameters */
index 1c44349880a018697e9ea3a02cada7223ec6bac9..0db536fd4e0b3406bc84f1c030c10f86449c301e 100644 (file)
@@ -3,8 +3,9 @@
 
 /* Parse all content parameters using rfc822_parse_content_param() and return
    them as a NULL-terminated [key, value] array. RFC 2231-style continuations
-   are merged to a single key. Returns -1 if some of the input was invalid
-   (but valid key/value pairs are still returned), 0 if everything looked ok. */
+   are merged to a single key. NULs are converted into 0x80. Returns -1 if some
+   of the input was invalid (but valid key/value pairs are still returned), 0
+   if everything looked ok. */
 int ATTR_NOWARN_UNUSED_RESULT
 rfc2231_parse(struct rfc822_parser_context *ctx,
              const char *const **result_r);
index 59204f4ee53c1b0c4583103624d4ffe81cdc6839..3c7e1b61f79be0b6521e8478ed7ab83007e9dbc4 100644 (file)
@@ -7,18 +7,18 @@
 
 static void test_rfc2231_parser(void)
 {
-       const char *input =
+       const unsigned char input[] =
                "; key4*=us-ascii''foo"
                "; key*2=ba%"
                "; key2*0=a"
                "; key3*0*=us-ascii'en'xyz"
-               "; key*0=\"foo\""
+               "; key*0=\"f\0oo\""
                "; key2*1*=b%25"
                "; key3*1=plop%"
                "; key*1=baz";
        const char *output[] = {
                "key",
-               "foobazba%",
+               "f\x80oobazba%",
                "key2*",
                "''ab%25",
                "key3*",
@@ -32,10 +32,10 @@ static void test_rfc2231_parser(void)
        unsigned int i;
 
        test_begin("rfc2231 parser");
-       rfc822_parser_init(&parser, (const void *)input, strlen(input), NULL);
+       rfc822_parser_init(&parser, input, sizeof(input)-1, NULL);
        test_assert(rfc2231_parse(&parser, &result) == 0);
        for (i = 0; output[i] != NULL && result[i] != NULL; i++)
-               test_assert(strcmp(output[i], result[i]) == 0);
+               test_assert_idx(strcmp(output[i], result[i]) == 0, i);
        rfc822_parser_deinit(&parser);
        test_assert(output[i] == NULL && result[i] == NULL);
        test_end();