Skip to content

never match an empty special-value symbol - #337

Open
0z5a wants to merge 1 commit into
google:masterfrom
0z5a:fix/empty-special-value-symbol
Open

0z5a wants to merge 1 commit into
google:masterfrom
0z5a:fix/empty-special-value-symbol

Conversation

@0z5a

@0z5a 0z5a commented Nov 14, 2026

Copy link
Copy Markdown

The string-to-double converter accepts NULL for infinity_symbol / nan_symbol to disable them, but an empty string "" is also accepted. With an empty symbol, an input whose first character (after the sign) is '\0' matches the symbol's first character, which is its terminator. ConsumeSubString then advances past that terminator and keeps comparing the following input with whatever bytes come after the symbol in memory.

Effects, for inputs with an embedded NUL (the input is length-delimited, so this is possible):

  • an out-of-bounds read of the bytes after the symbol (ASan reports a heap-buffer-overflow READ in ConsumeSubString when the symbol is a 1-byte heap allocation);
  • if those bytes happen to match the input, the input is parsed as Infinity / NaN. For example, with the symbol stored as {'\0', 'x', '\0'}, the input {'\0', 'x'} returns inf with processed == 2.

This change makes ConsumeFirstCharacter return false for an empty symbol, so an empty symbol never matches, like NULL. Non-empty symbols are unaffected.

Test: a new EmptySpecialValueSymbols case in test/cctest/test-conversions.cc covers an empty infinity symbol and an empty NaN symbol, char and uc16 input, a leading sign, the case-insensitive path and StringToFloat, and checks that the other symbol and ordinary numbers still parse. On master it fails with Expected: 1.0, Found: inf; with this change it passes. ctest (9/9) passes in a Debug build with -fsanitize=address,undefined.

This change was drafted with Claude Code (claude-opus-5-5); the test results above are from the runs described.

With an empty infinity_symbol or nan_symbol, an input character '\0'
matched the symbol's first character (its terminator), and
ConsumeSubString then stepped past the terminator and compared the
following input with whatever memory came after the symbol. Treat an
empty symbol as never matching.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant