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:
Alastair Donaldson 2022-07-26 15:56:04 +01:00 коммит произвёл GitHub
Родитель e4cfa190df
Коммит 388ce0ee64
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 31 добавлений и 21 удалений

Просмотреть файл

@ -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. // parameters, its the users responsibility to ensure these are non null.
spv_result_t advance(spv_text text, spv_position position) { spv_result_t advance(spv_text text, spv_position position) {
// NOTE: Consume white space, otherwise don't advance. // NOTE: Consume white space, otherwise don't advance.
if (position->index >= text->length) return SPV_END_OF_STREAM; while (true) {
switch (text->str[position->index]) { if (position->index >= text->length) return SPV_END_OF_STREAM;
case '\0': switch (text->str[position->index]) {
return SPV_END_OF_STREAM; case '\0':
case ';': return SPV_END_OF_STREAM;
if (spv_result_t error = advanceLine(text, position)) return error; case ';':
return advance(text, position); if (spv_result_t error = advanceLine(text, position)) return error;
case ' ': continue;
case '\t': case ' ':
case '\r': case '\t':
position->column++; case '\r':
position->index++; position->column++;
return advance(text, position); position->index++;
case '\n': continue;
position->column = 0; case '\n':
position->line++; position->column = 0;
position->index++; position->line++;
return advance(text, position); position->index++;
default: continue;
break; default:
return SPV_SUCCESS;
}
} }
return SPV_SUCCESS;
} }
// Fetches the next word from the given text stream starting from the given // 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(2u, pos.line);
EXPECT_EQ(4u, pos.index); 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
} // namespace spvtools } // namespace spvtools