Skip to content

Commit

Permalink
lib-mail: rfc2231_parse() - Replace NULs with 0x80
Browse files Browse the repository at this point in the history
Instead of truncating the strings at NULs.
  • Loading branch information
sirainen committed Aug 30, 2018
1 parent 102735b commit ce7821c
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 7 deletions.
7 changes: 7 additions & 0 deletions src/lib-mail/rfc2231-parser.c
Expand Up @@ -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. */
Expand Down Expand Up @@ -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 */
Expand Down
5 changes: 3 additions & 2 deletions src/lib-mail/rfc2231-parser.h
Expand Up @@ -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);
Expand Down
10 changes: 5 additions & 5 deletions src/lib-mail/test-rfc2231-parser.c
Expand Up @@ -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*",
Expand All @@ -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();
Expand Down

0 comments on commit ce7821c

Please sign in to comment.