mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-11-21 19:20:07 +00:00
spirv-as: Avoid recursion when skipping whitespace (#4866)
Excessive whitespace can lead to stack overflow during parsing as each character of skipped whitespace involves a recursive call. An iterative solution avoids this. Fixes #4729.
This commit is contained in:
parent
e4cfa190df
commit
388ce0ee64
@ -62,28 +62,29 @@ spv_result_t advanceLine(spv_text text, spv_position position) {
|
||||
// parameters, its the users responsibility to ensure these are non null.
|
||||
spv_result_t advance(spv_text text, spv_position position) {
|
||||
// NOTE: Consume white space, otherwise don't advance.
|
||||
if (position->index >= text->length) return SPV_END_OF_STREAM;
|
||||
switch (text->str[position->index]) {
|
||||
case '\0':
|
||||
return SPV_END_OF_STREAM;
|
||||
case ';':
|
||||
if (spv_result_t error = advanceLine(text, position)) return error;
|
||||
return advance(text, position);
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\r':
|
||||
position->column++;
|
||||
position->index++;
|
||||
return advance(text, position);
|
||||
case '\n':
|
||||
position->column = 0;
|
||||
position->line++;
|
||||
position->index++;
|
||||
return advance(text, position);
|
||||
default:
|
||||
break;
|
||||
while (true) {
|
||||
if (position->index >= text->length) return SPV_END_OF_STREAM;
|
||||
switch (text->str[position->index]) {
|
||||
case '\0':
|
||||
return SPV_END_OF_STREAM;
|
||||
case ';':
|
||||
if (spv_result_t error = advanceLine(text, position)) return error;
|
||||
continue;
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\r':
|
||||
position->column++;
|
||||
position->index++;
|
||||
continue;
|
||||
case '\n':
|
||||
position->column = 0;
|
||||
position->line++;
|
||||
position->index++;
|
||||
continue;
|
||||
default:
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
}
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
||||
// Fetches the next word from the given text stream starting from the given
|
||||
|
@ -130,5 +130,14 @@ TEST(TextAdvance, SkipOverCRLFs) {
|
||||
EXPECT_EQ(2u, pos.line);
|
||||
EXPECT_EQ(4u, pos.index);
|
||||
}
|
||||
|
||||
TEST(TextAdvance, HandleLotsOfWhitespace) {
|
||||
std::string lots_of_spaces(10000, ' ');
|
||||
lots_of_spaces += "Word";
|
||||
const auto pos = PositionAfterAdvance(lots_of_spaces.c_str());
|
||||
EXPECT_EQ(10000u, pos.column);
|
||||
EXPECT_EQ(0u, pos.line);
|
||||
EXPECT_EQ(10000u, pos.index);
|
||||
}
|
||||
} // namespace
|
||||
} // namespace spvtools
|
||||
|
Loading…
Reference in New Issue
Block a user