Skip to content

Commit a288d5e

Browse files
committed
danmar#7027 TokenList::validateAst() did not detect broken AST with endless recursion
1 parent f8de6a6 commit a288d5e

File tree

2 files changed

+17
-6
lines changed

2 files changed

+17
-6
lines changed

lib/tokenlist.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,7 +1098,7 @@ void TokenList::createAst()
10981098

10991099
void TokenList::validateAst()
11001100
{
1101-
std::set < const Token* > astTokens;
1101+
std::set < const Token* > safeAstTokens;
11021102
// Verify that ast looks ok
11031103
for (const Token *tok = _front; tok; tok = tok->next()) {
11041104
// Syntax error if binary operator only has 1 operand
@@ -1111,14 +1111,15 @@ void TokenList::validateAst()
11111111

11121112
// check for endless recursion
11131113
const Token* parent=tok;
1114+
std::set < const Token* > astTokens;
11141115
while ((parent = parent->astParent()) != nullptr) {
1115-
if (parent==tok)
1116-
throw InternalError(tok, "AST broken: endless recursion from '" + tok->str() + "'", InternalError::SYNTAX);
1117-
if (astTokens.find(parent)!= astTokens.end()) {
1116+
if (safeAstTokens.find(parent)!= safeAstTokens.end())
11181117
break;
1119-
}
1118+
if (astTokens.find(parent)!= astTokens.end())
1119+
throw InternalError(tok, "AST broken: endless recursion from '" + tok->str() + "'", InternalError::SYNTAX);
11201120
astTokens.insert(parent);
11211121
}
1122+
safeAstTokens.insert(astTokens.begin(), astTokens.end());
11221123
}
11231124
}
11241125

@@ -1136,7 +1137,7 @@ bool TokenList::validateToken(const Token* tok) const
11361137
{
11371138
if (!tok)
11381139
return true;
1139-
for (Token *t = _front; t; t = t->next()) {
1140+
for (const Token *t = _front; t; t = t->next()) {
11401141
if (tok==t)
11411142
return true;
11421143
}

test/testgarbage.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ class TestGarbage : public TestFixture {
223223
TEST_CASE(garbageCode172);
224224
TEST_CASE(garbageCode173); // #6781
225225
TEST_CASE(garbageCode174); // #7356
226+
TEST_CASE(garbageCode175);
226227
TEST_CASE(garbageValueFlow);
227228
TEST_CASE(garbageSymbolDatabase);
228229
TEST_CASE(garbageAST);
@@ -1464,6 +1465,15 @@ class TestGarbage : public TestFixture {
14641465
void garbageCode174() { // #7356
14651466
checkCode("{r e() { w*constD = (())D = cast< }}");
14661467
}
1468+
1469+
void garbageCode175() { // #7027
1470+
ASSERT_THROW(checkCode("int f() {\n"
1471+
" int i , j;\n"
1472+
" for ( i = t3 , i < t1 ; i++ )\n"
1473+
" for ( j = 0 ; j < = j++ )\n"
1474+
" return t1 ,\n"
1475+
"}"), InternalError);
1476+
}
14671477
};
14681478

14691479
REGISTER_TEST(TestGarbage)

0 commit comments

Comments
 (0)