From 956c4516eb3d592352ab4b959699ee4837240d00 Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Sun, 7 Jun 2026 10:20:31 -0400 Subject: [PATCH] Fix out-of-bounds token read on trailing address delimiters When the delimiter-skip loop in parse_address_tokens() advances start_tok to exactly toks->ntokens (an address followed by one or more trailing ',' or ';'), the addr-spec branch read toks->tokens[start_tok].token with start_tok == ntokens, one element past the ecalloc'd token array. mailparse_rfc822_parse_addresses("a@b,,") triggers it. Only strip the enclosing <> when the address span is non-empty (a_count > 0), which also guarantees a_start < ntokens. The route-addr branch is already guarded by its i < ntokens entry condition. Change applied to both the .re source and the generated .c. --- php_mailparse_rfc822.c | 2 +- php_mailparse_rfc822.re | 2 +- tests/addr_trailing_delim_oob.phpt | 16 ++++++++++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 tests/addr_trailing_delim_oob.phpt diff --git a/php_mailparse_rfc822.c b/php_mailparse_rfc822.c index 28a001a..903d810 100644 --- a/php_mailparse_rfc822.c +++ b/php_mailparse_rfc822.c @@ -547,7 +547,7 @@ static void parse_address_tokens(php_rfc822_tokenized_t *toks, a_count = i - start_tok; /* if an address is enclosed in <>, leave them out of the the * address value that we return */ - if (toks->tokens[a_start].token == '<') { + if (a_count > 0 && toks->tokens[a_start].token == '<') { a_start++; a_count--; } diff --git a/php_mailparse_rfc822.re b/php_mailparse_rfc822.re index 98699ac..c22dabb 100644 --- a/php_mailparse_rfc822.re +++ b/php_mailparse_rfc822.re @@ -410,7 +410,7 @@ mailbox: /* addr-spec / phrase route-addr */ a_count = i - start_tok; /* if an address is enclosed in <>, leave them out of the the * address value that we return */ - if (toks->tokens[a_start].token == '<') { + if (a_count > 0 && toks->tokens[a_start].token == '<') { a_start++; a_count--; } diff --git a/tests/addr_trailing_delim_oob.phpt b/tests/addr_trailing_delim_oob.phpt new file mode 100644 index 0000000..1502ac0 --- /dev/null +++ b/tests/addr_trailing_delim_oob.phpt @@ -0,0 +1,16 @@ +--TEST-- +Trailing delimiters in an address list do not read past the token array +--SKIPIF-- + +--FILE-- + +--EXPECT-- +string(3) "a@b" +bool(true) +done