diff --git a/src/checkbufferoverrun.cpp b/src/checkbufferoverrun.cpp index de2ce334a..d4a91b0ed 100644 --- a/src/checkbufferoverrun.cpp +++ b/src/checkbufferoverrun.cpp @@ -388,7 +388,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co // Checking local variables in a scope //--------------------------------------------------------------------------- -void CheckBufferOverrunClass::CheckBufferOverrun_LocalVariable() +void CheckBufferOverrunClass::CheckBufferOverrun_GlobalAndLocalVariable() { int indentlevel = 0; for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) @@ -399,43 +399,40 @@ void CheckBufferOverrunClass::CheckBufferOverrun_LocalVariable() else if (tok->str() == "}") --indentlevel; - else if (indentlevel > 0) + const char *varname[2] = {0}; + unsigned int size = 0; + const char *type = 0; + unsigned int varid = 0; + int nextTok = 0; + + if (Token::Match(tok, "%type% %var% [ %num% ] ;")) { - const char *varname[2] = {0}; - unsigned int size = 0; - const char *type = 0; - unsigned int varid = 0; - int nextTok = 0; - - if (Token::Match(tok, "%type% %var% [ %num% ] ;")) - { - varname[0] = tok->strAt(1); - size = std::strtoul(tok->strAt(3), NULL, 10); - type = tok->aaaa(); - varid = tok->tokAt(1)->varId(); - nextTok = 6; - } - else if (Token::Match(tok, "[*;{}] %var% = new %type% [ %num% ]")) - { - varname[0] = tok->strAt(1); - size = std::strtoul(tok->strAt(6), NULL, 10); - type = tok->strAt(4); - varid = tok->tokAt(1)->varId(); - nextTok = 8; - } - else - { - continue; - } - - int total_size = size * _tokenizer->SizeOfType(type); - if (total_size == 0) - continue; - - // The callstack is empty - _callStack.clear(); - CheckBufferOverrun_CheckScope(tok->tokAt(nextTok), varname, size, total_size, varid); + varname[0] = tok->strAt(1); + size = std::strtoul(tok->strAt(3), NULL, 10); + type = tok->aaaa(); + varid = tok->tokAt(1)->varId(); + nextTok = 6; } + else if (indentlevel > 0 && Token::Match(tok, "[*;{}] %var% = new %type% [ %num% ]")) + { + varname[0] = tok->strAt(1); + size = std::strtoul(tok->strAt(6), NULL, 10); + type = tok->strAt(4); + varid = tok->tokAt(1)->varId(); + nextTok = 8; + } + else + { + continue; + } + + int total_size = size * _tokenizer->SizeOfType(type); + if (total_size == 0) + continue; + + // The callstack is empty + _callStack.clear(); + CheckBufferOverrun_CheckScope(tok->tokAt(nextTok), varname, size, total_size, varid); } } //--------------------------------------------------------------------------- @@ -560,7 +557,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_StructVariable() void CheckBufferOverrunClass::bufferOverrun() { - CheckBufferOverrun_LocalVariable(); + CheckBufferOverrun_GlobalAndLocalVariable(); CheckBufferOverrun_StructVariable(); } //--------------------------------------------------------------------------- diff --git a/src/checkbufferoverrun.h b/src/checkbufferoverrun.h index faac4e0bb..a96e62444 100644 --- a/src/checkbufferoverrun.h +++ b/src/checkbufferoverrun.h @@ -43,8 +43,8 @@ private: /** Check for buffer overruns - locate struct variables and check them with the .._CheckScope function */ void CheckBufferOverrun_StructVariable(); - /** Check for buffer overruns - locate local function variables and check them with the .._CheckScope function */ - void CheckBufferOverrun_LocalVariable(); + /** Check for buffer overruns - locate global variables and local function variables and check them with the .._CheckScope function */ + void CheckBufferOverrun_GlobalAndLocalVariable(); /** Check for buffer overruns - this is the function that performs the actual checking */ void CheckBufferOverrun_CheckScope(const Token *tok, const char *varname[], const int size, const int total_size, unsigned int varid); diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index e9ce1f494..cd0baa0ae 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -85,6 +85,7 @@ private: TEST_CASE(buffer_overrun_1); TEST_CASE(buffer_overrun_2); + TEST_CASE(buffer_overrun_3); TEST_CASE(sprintf1); TEST_CASE(snprintf1); @@ -373,6 +374,9 @@ private: } + + + void buffer_overrun_1() { check("void f()\n" @@ -399,6 +403,24 @@ private: } + void buffer_overrun_3() + { + check("int a[10];\n" + "\n" + "void foo()\n" + "{\n" + " int i;\n" + " for (i = 0; i <= 10; ++i)\n" + " a[i] = 0;\n" + "}\n"); + std::string err(errout.str()); + ASSERT_EQUALS(std::string("[test.cpp:7]: (all) Buffer overrun\n"), err); + } + + + + + void sprintf1() { check("void f()\n"