Repository navigation
Avoid out-of-bounds table read in balsa URI char validators - #160
neeraj1235476 wants to merge 1 commit into
Conversation
HasInvalidPathChar and HasInvalidQueryChar iterated the value with a signed char and used it directly to index a 256-entry lookup table, so any byte >= 0x80 indexed the table out of bounds. The sibling validators in this file already cast to uint8_t before indexing; do the same here. Add regression cases covering high-bit bytes.
There was a problem hiding this comment.
Code Review
This pull request addresses potential out-of-bounds indexing issues in HasInvalidPathChar and HasInvalidQueryChar by ensuring characters with values >= 0x80 are safely processed, and adds corresponding test cases. The review feedback suggests avoiding implicit conversion warnings (such as -Wsign-conversion) in the range-based loops by iterating over const char and explicitly casting to uint8_t when indexing the lookup tables, which also aligns with other validators in the codebase.
| for (const uint8_t c : value) { | ||
| if (invalidCharTable[c]) { |
There was a problem hiding this comment.
Implicitly converting char to uint8_t in the range-based for loop can trigger compiler warnings (such as -Wsign-conversion or -Wconversion) in strict build environments. To prevent this and maintain consistency with other validators in this file (like IsValidToken and IsValidChunkExtension), it is better to iterate over const char c and perform an explicit static_cast<uint8_t>(c) when indexing the lookup table.
| for (const uint8_t c : value) { | |
| if (invalidCharTable[c]) { | |
| for (const char c : value) { | |
| if (invalidCharTable[static_cast<uint8_t>(c)]) { |
| for (const uint8_t c : value) { | ||
| if (invalidCharTable[c]) { |
There was a problem hiding this comment.
Implicitly converting char to uint8_t in the range-based for loop can trigger compiler warnings (such as -Wsign-conversion or -Wconversion) in strict build environments. To prevent this and maintain consistency with other validators in this file (like IsValidToken and IsValidChunkExtension), it is better to iterate over const char c and perform an explicit static_cast<uint8_t>(c) when indexing the lookup table.
| for (const uint8_t c : value) { | |
| if (invalidCharTable[c]) { | |
| for (const char c : value) { | |
| if (invalidCharTable[static_cast<uint8_t>(c)]) { |
AddressSanitizer, release byte of a URI path/query to the exported validators:
HasInvalidPathCharandHasInvalidQueryCharloop over the value with a signedcharand index a 256-entrystd::arraywith it directly. Any byte >= 0x80 is negative, so the lookup reads before the table. The sibling validators in this file (IsValidToken,IsValidChunkExtension) alreadystatic_cast<uint8_t>before indexing; these two were missed. Iterating asuint8_tmatches them and leaves results unchanged for valid ASCII input.Triggered by any request-target byte >= 0x80 reaching these validators, e.g. a percent-unescaped UTF-8 path.
Regression cases covering high-bit bytes are added to
header_properties_test.cc.