Skip to content

Commit

Permalink
Fix #13494 fuzzing crash in getEnumType() (#7246)
Browse files Browse the repository at this point in the history
  • Loading branch information
chrchr-github authored Jan 21, 2025
1 parent e32e2ba commit 6b38f78
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 0 deletions.
4 changes: 4 additions & 0 deletions lib/symboldatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7152,6 +7152,10 @@ static ValueType::Type getEnumType(const Scope* scope, const Platform& platform)
{
ValueType::Type type = ValueType::Type::INT;
for (const Token* tok = scope->bodyStart; tok && tok != scope->bodyEnd; tok = tok->next()) {
if (const Token* lam = findLambdaEndToken(tok)) {
tok = lam;
continue;
}
if (!tok->isAssignmentOp())
continue;
const Token* vTok = tok->astOperand2();
Expand Down
11 changes: 11 additions & 0 deletions lib/tokenize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8602,13 +8602,24 @@ void Tokenizer::findGarbageCode() const
if (Token::Match(tok->next(), ": %num%| {"))
syntaxError(tok->tokAt(2), "Unexpected token '" + tok->strAt(2) + "'");
if (const Token* start = SymbolDatabase::isEnumDefinition(tok)) {
int nEquals = 0;
for (const Token* tok2 = start->next(); tok2 && tok2 != start->link(); tok2 = tok2->next()) {
if (Token::simpleMatch(tok2, "sizeof (")) {
tok2 = tok2->linkAt(1);
continue;
}
if (const Token* lam = findLambdaEndTokenWithoutAST(tok2)) {
tok2 = lam;
continue;
}
if (tok2->str() == ";")
syntaxError(tok2);
if (tok2->str() == "=")
++nEquals;
else if (tok2->str() == ",")
nEquals = 0;
if (nEquals > 1)
syntaxError(tok2);
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions lib/tokenlist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1443,6 +1443,8 @@ const Token* findLambdaEndTokenWithoutAST(const Token* tok) {
tok = tok->link()->next();
if (Token::simpleMatch(tok, "(") && tok->link())
tok = tok->link()->next();
if (Token::simpleMatch(tok, "mutable"))
tok = tok->next();
if (Token::simpleMatch(tok, ".")) { // trailing return type
tok = tok->next();
while (Token::Match(tok, "%type%|%name%|::|&|&&|*|<|(")) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{enum{A=s(u)0=s};}
4 changes: 4 additions & 0 deletions test/testgarbage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ class TestGarbage : public TestFixture {
TEST_CASE(garbageCode225);
TEST_CASE(garbageCode226);
TEST_CASE(garbageCode227);
TEST_CASE(garbageCode228);

TEST_CASE(garbageCodeFuzzerClientMode1); // test cases created with the fuzzer client, mode 1

Expand Down Expand Up @@ -1761,6 +1762,9 @@ class TestGarbage : public TestFixture {
void garbageCode227() { // #12615
ASSERT_NO_THROW(checkCode("f(&S::operator=);"));
}
void garbageCode228() {
ASSERT_NO_THROW(checkCode("void f() { enum { A = [=]() mutable { return 0; }() }; }"));
}

void syntaxErrorFirstToken() {
ASSERT_THROW_INTERNAL(checkCode("&operator(){[]};"), SYNTAX); // #7818
Expand Down

0 comments on commit 6b38f78

Please sign in to comment.