diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 77efffa4b..cb6ca2c37 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -1119,14 +1119,18 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable() void CheckBufferOverrun::checkStructVariable() { - const char declstruct[] = "struct|class %var% {"; + const char declstruct[] = "struct|class %var% {|:"; for (const Token *tok = Token::findmatch(_tokenizer->tokens(), declstruct); tok; tok = Token::findmatch(tok->next(), declstruct)) { const std::string &structname = tok->next()->str(); + const Token *tok2 = tok; + + while (tok2->str() != "{") + tok2 = tok2->next(); // Found a struct declaration. Search for arrays.. - for (const Token *tok2 = tok->tokAt(2); tok2; tok2 = tok2->next()) + for (; tok2; tok2 = tok2->next()) { // skip inner scopes.. if (tok2->next() && tok2->next()->str() == "{") diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 73b1c78ef..03f9bfef6 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -633,8 +633,11 @@ void CheckClass::privateFunctions() if (!_settings->_checkCodingStyle) return; + const char pattern_class[] = "class|struct %var% {|:"; + // Locate some class - for (const Token *tok1 = Token::findmatch(_tokenizer->tokens(), "class|struct %var% {"); tok1; tok1 = Token::findmatch(tok1->next(), "class|struct %var% {")) + for (const Token *tok1 = Token::findmatch(_tokenizer->tokens(), pattern_class); + tok1; tok1 = Token::findmatch(tok1->next(), pattern_class)) { /** @todo check that the whole class implementation is seen */ // until the todo above is fixed we only check classes that are diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index fdb182808..4682777aa 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2910,11 +2910,10 @@ void Tokenizer::setVarId() // class members.. for (Token *tok = _tokens; tok; tok = tok->next()) { - if (Token::Match(tok, "class %var% {")) + if (Token::Match(tok, "class|struct %var% {|:")) { const std::string &classname(tok->next()->str()); - // What member variables are there in this class? std::map varlist; { diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 435f9cae3..65f5aaaf8 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -124,6 +124,7 @@ private: TEST_CASE(buffer_overrun_12); TEST_CASE(buffer_overrun_13); TEST_CASE(buffer_overrun_14); + TEST_CASE(buffer_overrun_15); // ticket #1787 TEST_CASE(sprintf1); TEST_CASE(sprintf2); @@ -1624,6 +1625,19 @@ private: ASSERT_EQUALS("[test.cpp:3]: (error) Buffer access out-of-bounds\n", errout.str()); } + void buffer_overrun_15() // ticket #1787 + { + check("class A : public B {\n" + " char val[12];\n" + " void f(int i, int ii);\n" + "};\n" + "void A::f(int i, int ii)\n" + "{\n" + " sprintf(val, \"drive_%d_partition_%d_size\", i, ii) ;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:7]: (error) Buffer access out-of-bounds\n", errout.str()); + } + void sprintf1() { check("void f()\n"