From 6b38f785076e7bdacc6a86e5547a06518c72a598 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Tue, 21 Jan 2025 07:49:31 +0100 Subject: [PATCH] Fix #13494 fuzzing crash in getEnumType() (#7246) --- lib/symboldatabase.cpp | 4 ++++ lib/tokenize.cpp | 11 +++++++++++ lib/tokenlist.cpp | 2 ++ .../crash-8b9b108955146efbdae71f7167251da89d1e18c4 | 1 + test/testgarbage.cpp | 4 ++++ 5 files changed, 22 insertions(+) create mode 100644 test/cli/fuzz-crash/crash-8b9b108955146efbdae71f7167251da89d1e18c4 diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 09850dd24ce..fc3a82a502b 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -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(); diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index fea21bc61ce..46d05ed81fb 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -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); } } } diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index c42ee552e1a..6941100a126 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -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%|::|&|&&|*|<|(")) { diff --git a/test/cli/fuzz-crash/crash-8b9b108955146efbdae71f7167251da89d1e18c4 b/test/cli/fuzz-crash/crash-8b9b108955146efbdae71f7167251da89d1e18c4 new file mode 100644 index 00000000000..dcf55359979 --- /dev/null +++ b/test/cli/fuzz-crash/crash-8b9b108955146efbdae71f7167251da89d1e18c4 @@ -0,0 +1 @@ +{enum{A=s(u)0=s};} \ No newline at end of file diff --git a/test/testgarbage.cpp b/test/testgarbage.cpp index 2a77ca86b0b..5b33910418b 100644 --- a/test/testgarbage.cpp +++ b/test/testgarbage.cpp @@ -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 @@ -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