diff --git a/php_mailparse_rfc822.c b/php_mailparse_rfc822.c index c66d802..357538d 100644 --- a/php_mailparse_rfc822.c +++ b/php_mailparse_rfc822.c @@ -485,7 +485,7 @@ static void parse_address_tokens(php_rfc822_tokenized_t *toks, ; /* the stuff from start_tok to i - 1 is the display name part */ - if (addrs && !in_group && i - start_tok > 0) { + if (addrs && !in_group && i - start_tok > 0 && iaddr < addrs->naddrs) { int j, has_comments = 0, has_strings = 0; switch(i < toks->ntokens ? toks->tokens[i].token : 0) { case ';': case ',': case '<': @@ -561,9 +561,10 @@ static void parse_address_tokens(php_rfc822_tokenized_t *toks, } if (addrs && address_value) { + int slot_ok = iaddr < addrs->naddrs; /* if no display name has been given, use the address */ - if (addrs->addrs[iaddr].name == NULL) { + if (slot_ok && addrs->addrs[iaddr].name == NULL) { addrs->addrs[iaddr].name = estrdup(address_value); } @@ -572,8 +573,10 @@ static void parse_address_tokens(php_rfc822_tokenized_t *toks, smart_string_appendl(&group_addrs, ",", 1); smart_string_appends(&group_addrs, address_value); efree(address_value); - } else { + } else if (slot_ok) { addrs->addrs[iaddr].address = address_value; + } else { + efree(address_value); } address_value = NULL; } @@ -586,7 +589,7 @@ static void parse_address_tokens(php_rfc822_tokenized_t *toks, if ((start_tok < toks->ntokens && toks->tokens[start_tok].token == ';') || start_tok == toks->ntokens) { /* end of group */ - if (addrs) { + if (addrs && iaddr < addrs->naddrs) { smart_string_appendl(&group_addrs, ";", 1); smart_string_0(&group_addrs); addrs->addrs[iaddr].address = estrdup(group_addrs.c); diff --git a/php_mailparse_rfc822.re b/php_mailparse_rfc822.re index c22dabb..997e662 100644 --- a/php_mailparse_rfc822.re +++ b/php_mailparse_rfc822.re @@ -348,7 +348,7 @@ mailbox: /* addr-spec / phrase route-addr */ ; /* the stuff from start_tok to i - 1 is the display name part */ - if (addrs && !in_group && i - start_tok > 0) { + if (addrs && !in_group && i - start_tok > 0 && iaddr < addrs->naddrs) { int j, has_comments = 0, has_strings = 0; switch(i < toks->ntokens ? toks->tokens[i].token : 0) { case ';': case ',': case '<': @@ -424,9 +424,10 @@ mailbox: /* addr-spec / phrase route-addr */ } if (addrs && address_value) { + int slot_ok = iaddr < addrs->naddrs; /* if no display name has been given, use the address */ - if (addrs->addrs[iaddr].name == NULL) { + if (slot_ok && addrs->addrs[iaddr].name == NULL) { addrs->addrs[iaddr].name = estrdup(address_value); } @@ -435,8 +436,10 @@ mailbox: /* addr-spec / phrase route-addr */ smart_string_appendl(&group_addrs, ",", 1); smart_string_appends(&group_addrs, address_value); efree(address_value); - } else { + } else if (slot_ok) { addrs->addrs[iaddr].address = address_value; + } else { + efree(address_value); } address_value = NULL; } @@ -449,7 +452,7 @@ mailbox: /* addr-spec / phrase route-addr */ if ((start_tok < toks->ntokens && toks->tokens[start_tok].token == ';') || start_tok == toks->ntokens) { /* end of group */ - if (addrs) { + if (addrs && iaddr < addrs->naddrs) { smart_string_appendl(&group_addrs, ";", 1); smart_string_0(&group_addrs); addrs->addrs[iaddr].address = estrdup(group_addrs.c); diff --git a/tests/rfc822_group_routeaddr_oob.phpt b/tests/rfc822_group_routeaddr_oob.phpt new file mode 100644 index 0000000..1151285 --- /dev/null +++ b/tests/rfc822_group_routeaddr_oob.phpt @@ -0,0 +1,20 @@ +--TEST-- +A route-addr inside a group does not read past the parsed address array +--SKIPIF-- + +--FILE-- +") + * used to desync the counting and building passes of the address parser and + * index one slot past the end of the allocated address array. */ +foreach (array("<>:<", ":;:<", "a@b,<>:<") as $in) { + $r = mailparse_rfc822_parse_addresses($in); + var_dump(is_array($r)); +} +echo "done\n"; +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) +done