Skip to content

Commit 6b38f78

Browse files
Fix #13494 fuzzing crash in getEnumType() (#7246)
1 parent e32e2ba commit 6b38f78

File tree

5 files changed

+22
-0
lines changed

5 files changed

+22
-0
lines changed

lib/symboldatabase.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -7152,6 +7152,10 @@ static ValueType::Type getEnumType(const Scope* scope, const Platform& platform)
71527152
{
71537153
ValueType::Type type = ValueType::Type::INT;
71547154
for (const Token* tok = scope->bodyStart; tok && tok != scope->bodyEnd; tok = tok->next()) {
7155+
if (const Token* lam = findLambdaEndToken(tok)) {
7156+
tok = lam;
7157+
continue;
7158+
}
71557159
if (!tok->isAssignmentOp())
71567160
continue;
71577161
const Token* vTok = tok->astOperand2();

lib/tokenize.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -8602,13 +8602,24 @@ void Tokenizer::findGarbageCode() const
86028602
if (Token::Match(tok->next(), ": %num%| {"))
86038603
syntaxError(tok->tokAt(2), "Unexpected token '" + tok->strAt(2) + "'");
86048604
if (const Token* start = SymbolDatabase::isEnumDefinition(tok)) {
8605+
int nEquals = 0;
86058606
for (const Token* tok2 = start->next(); tok2 && tok2 != start->link(); tok2 = tok2->next()) {
86068607
if (Token::simpleMatch(tok2, "sizeof (")) {
86078608
tok2 = tok2->linkAt(1);
86088609
continue;
86098610
}
8611+
if (const Token* lam = findLambdaEndTokenWithoutAST(tok2)) {
8612+
tok2 = lam;
8613+
continue;
8614+
}
86108615
if (tok2->str() == ";")
86118616
syntaxError(tok2);
8617+
if (tok2->str() == "=")
8618+
++nEquals;
8619+
else if (tok2->str() == ",")
8620+
nEquals = 0;
8621+
if (nEquals > 1)
8622+
syntaxError(tok2);
86128623
}
86138624
}
86148625
}

lib/tokenlist.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -1443,6 +1443,8 @@ const Token* findLambdaEndTokenWithoutAST(const Token* tok) {
14431443
tok = tok->link()->next();
14441444
if (Token::simpleMatch(tok, "(") && tok->link())
14451445
tok = tok->link()->next();
1446+
if (Token::simpleMatch(tok, "mutable"))
1447+
tok = tok->next();
14461448
if (Token::simpleMatch(tok, ".")) { // trailing return type
14471449
tok = tok->next();
14481450
while (Token::Match(tok, "%type%|%name%|::|&|&&|*|<|(")) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{enum{A=s(u)0=s};}

test/testgarbage.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ class TestGarbage : public TestFixture {
254254
TEST_CASE(garbageCode225);
255255
TEST_CASE(garbageCode226);
256256
TEST_CASE(garbageCode227);
257+
TEST_CASE(garbageCode228);
257258

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

@@ -1761,6 +1762,9 @@ class TestGarbage : public TestFixture {
17611762
void garbageCode227() { // #12615
17621763
ASSERT_NO_THROW(checkCode("f(&S::operator=);"));
17631764
}
1765+
void garbageCode228() {
1766+
ASSERT_NO_THROW(checkCode("void f() { enum { A = [=]() mutable { return 0; }() }; }"));
1767+
}
17641768

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

0 commit comments

Comments
 (0)