From fe85b8779ef7c011dc9213cbd9297eb9a1371bef Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Sun, 4 Sep 2011 21:39:52 -0400 Subject: [PATCH] fix #2528 (false negative: buffer access out of bounds) --- lib/checkbufferoverrun.cpp | 58 +++++++++++++++++++++++--------------- test/testbufferoverrun.cpp | 2 +- 2 files changed, 36 insertions(+), 24 deletions(-) diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 92ca5c500..1b3cd8b76 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -1473,6 +1473,41 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable() void CheckBufferOverrun::checkStructVariable() { + const SymbolDatabase * symbolDatabase = _tokenizer->getSymbolDatabase(); + + std::list::const_iterator scope; + + // find every class and struct + for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope) + { + // only check classes and structures + if (!scope->isClassOrStruct()) + continue; + + // check all variables + std::list::const_iterator var; + for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var) + { + // find all array variables + if (var->isArray()) + { + ArrayInfo arrayInfo(&*var, _tokenizer); + + // check each function for array variable usage + std::list::const_iterator func; + for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func) + { + // check existing and non-empty function + if (func->hasBody && func->start->next() != func->start->link()) + { + const Token *tok = func->start->next(); + checkScope(tok, arrayInfo); + } + } + } + } + } + for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { if (tok->str() == "{") @@ -1519,29 +1554,6 @@ void CheckBufferOverrun::checkStructVariable() varname.push_back(""); varname.push_back(arrayInfo.varname()); - // Class member variable => Check functions - if (tok->str() == "class") - { - std::string func_pattern(structname + " :: %var% ("); - const Token *tok3 = Token::findmatch(_tokenizer->tokens(), func_pattern.c_str()); - while (tok3) - { - for (const Token *tok4 = tok3; tok4; tok4 = tok4->next()) - { - if (Token::Match(tok4, "[;{}]")) - break; - - if (Token::simpleMatch(tok4, ") {")) - { - std::vector v; - checkScope(tok4->tokAt(2), v, static_cast(arrayInfo.num(0)), static_cast(arrayInfo.num(0) * arrayInfo.element_size()), arrayInfo.varid()); - break; - } - } - tok3 = Token::findmatch(tok3->next(), func_pattern.c_str()); - } - } - for (const Token *tok3 = _tokenizer->tokens(); tok3; tok3 = tok3->next()) { if (tok3->str() != structname) diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 6faa8b5db..54cc0b291 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -1139,7 +1139,7 @@ private: " }\n" " int m_x[1];\n" "};\n"); - TODO_ASSERT_EQUALS("[test.cpp:7]: (error) Array 'm_x[1]' index 1 out of bounds\n","", errout.str()); + ASSERT_EQUALS("[test.cpp:7]: (error) Array 'm_x[1]' index 1 out of bounds\n", errout.str()); } void array_index_33()