From 25c562da81b65a1c33a92d452f87879baf4dd283 Mon Sep 17 00:00:00 2001 From: chrchr Date: Tue, 12 Mar 2024 15:32:53 +0100 Subject: [PATCH] Enable validateVariables(), fix fuzzing crash --- lib/symboldatabase.cpp | 17 +++++++--- lib/symboldatabase.h | 12 +++---- ...h-2490dbc1880f2d7883c1b634deee8da3805186f8 | 1 + test/testgarbage.cpp | 33 ++++++++++--------- 4 files changed, 37 insertions(+), 26 deletions(-) create mode 100644 test/cli/fuzz-crash/crash-2490dbc1880f2d7883c1b634deee8da3805186f8 diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 4c056626ef1..be3a65d8e23 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -2161,6 +2161,17 @@ namespace { } } } + if (const Scope* scope = var->nameToken()->scope()) { + auto it = std::find_if(scope->functionList.begin(), scope->functionList.end(), [&](const Function& function) { + for (std::size_t arg = 0; arg < function.argCount(); ++arg) { + if (var == function.getArgumentVar(arg)) + return true; + } + return false; + }); + if (it != scope->functionList.end()) + return &*it; + } return nullptr; } } @@ -2172,9 +2183,8 @@ void SymbolDatabase::validateVariables() const if (var) { if (!var->scope()) { const Function* function = getFunctionForArgumentvariable(var, functionScopes); - if (!var->isArgument() || (function && function->hasBody())) { + if (!var->isArgument() || (!function || function->hasBody())) { throw InternalError(var->nameToken(), "Analysis failed (variable without scope). If the code is valid then please report this failure.", InternalError::INTERNAL); - //std::cout << "!!!Variable found without scope: " << var->nameToken()->str() << std::endl; } } } @@ -2186,8 +2196,7 @@ void SymbolDatabase::validate() const if (mSettings.debugwarnings) { validateExecutableScopes(); } - // TODO - //validateVariables(); + validateVariables(); } void SymbolDatabase::clangSetVariables(const std::vector &variableList) diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index f718e695842..9d378298f7e 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -1394,12 +1394,6 @@ class CPPCHECKLIB SymbolDatabase { */ void validate() const; - void validateExecutableScopes() const; - /** - * @brief Check variable list, e.g. variables w/o scope - */ - void validateVariables() const; - /** Set valuetype in provided tokenlist */ void setValueTypeInTokenList(bool reportDebugWarnings, Token *tokens=nullptr); @@ -1467,6 +1461,12 @@ class CPPCHECKLIB SymbolDatabase { void setValueType(Token* tok, const Variable& var, const SourceLocation &loc = SourceLocation::current()); void setValueType(Token* tok, const Enumerator& enumerator, const SourceLocation &loc = SourceLocation::current()); + void validateExecutableScopes() const; + /** + * @brief Check variable list, e.g. variables w/o scope + */ + void validateVariables() const; + Tokenizer& mTokenizer; const Settings &mSettings; ErrorLogger *mErrorLogger; diff --git a/test/cli/fuzz-crash/crash-2490dbc1880f2d7883c1b634deee8da3805186f8 b/test/cli/fuzz-crash/crash-2490dbc1880f2d7883c1b634deee8da3805186f8 new file mode 100644 index 00000000000..60a55bed0b9 --- /dev/null +++ b/test/cli/fuzz-crash/crash-2490dbc1880f2d7883c1b634deee8da3805186f8 @@ -0,0 +1 @@ +i a;m t(=a[]);m e(){a[]=0} \ No newline at end of file diff --git a/test/testgarbage.cpp b/test/testgarbage.cpp index 639b931e7e0..25a1c698fd5 100644 --- a/test/testgarbage.cpp +++ b/test/testgarbage.cpp @@ -1625,22 +1625,23 @@ class TestGarbage : public TestFixture { } void garbageCode205() { - checkCode("class CodeSnippetsEvent : public wxCommandEvent {\n" - "public :\n" - " CodeSnippetsEvent ( wxEventType commandType = wxEventType , int id = 0 ) ;\n" - " CodeSnippetsEvent ( const CodeSnippetsEvent & event ) ;\n" - "virtual wxEvent * Clone ( ) const { return new CodeSnippetsEvent ( * this ) ; }\n" - "private :\n" - " int m_SnippetID ;\n" - "} ;\n" - "const wxEventType wxEVT_CODESNIPPETS_GETFILELINKS = wxNewEventType ( )\n" - "CodeSnippetsEvent :: CodeSnippetsEvent ( wxEventType commandType , int id )\n" - ": wxCommandEvent ( commandType , id ) {\n" - "}\n" - "CodeSnippetsEvent :: CodeSnippetsEvent ( const CodeSnippetsEvent & Event )\n" - ": wxCommandEvent ( Event )\n" - ", m_SnippetID ( 0 ) {\n" - "}"); // don't crash + ASSERT_THROW(checkCode("class CodeSnippetsEvent : public wxCommandEvent {\n" + "public :\n" + " CodeSnippetsEvent ( wxEventType commandType = wxEventType , int id = 0 ) ;\n" + " CodeSnippetsEvent ( const CodeSnippetsEvent & event ) ;\n" + "virtual wxEvent * Clone ( ) const { return new CodeSnippetsEvent ( * this ) ; }\n" + "private :\n" + " int m_SnippetID ;\n" + "} ;\n" + "const wxEventType wxEVT_CODESNIPPETS_GETFILELINKS = wxNewEventType ( )\n" + "CodeSnippetsEvent :: CodeSnippetsEvent ( wxEventType commandType , int id )\n" + ": wxCommandEvent ( commandType , id ) {\n" + "}\n" + "CodeSnippetsEvent :: CodeSnippetsEvent ( const CodeSnippetsEvent & Event )\n" + ": wxCommandEvent ( Event )\n" + ", m_SnippetID ( 0 ) {\n" + "}"), + InternalError); } void garbageCode206() {