diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index c3ac0ddc8..ca5fd8f82 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -872,20 +872,8 @@ void CheckBufferOverrun::checkScope(const Token *tok, const std::vector 0) - { - if (Token::Match(tok, "%varid% [ %num% ]", varid)) - { - const MathLib::bigint index = MathLib::toLongNumber(tok->strAt(2)); - if (index >= size) - { - std::vector indexes; - indexes.push_back(index); - arrayIndexOutOfBoundsError(tok, info, indexes); - } - } - } - else if (Token::Match(tok, (varnames + " [ %num% ]").c_str())) + if ((varid > 0 && Token::Match(tok, "%varid% [ %num% ]", varid)) || + (varid == 0 && Token::Match(tok, (varnames + " [ %num% ]").c_str()))) { const MathLib::bigint index = MathLib::toLongNumber(tok->strAt(2 + varc)); if (index >= size) @@ -929,33 +917,9 @@ void CheckBufferOverrun::checkScope(const Token *tok, const std::vector 0) - { - if (!tok->isName() && !Token::Match(tok, "[.&]") && Token::Match(tok->next(), "%varid% [ %num% ]", varid)) - { - const MathLib::bigint index = MathLib::toLongNumber(tok->strAt(3)); - if (index < 0 || index >= size) - { - if (index > size || !Token::simpleMatch(tok->previous(), "& (")) - { - std::vector indexes; - indexes.push_back(index); - arrayIndexOutOfBoundsError(tok->next(), info, indexes); - } - } - } - if (Token::Match(tok, "return %varid% [ %num% ]", varid)) - { - const MathLib::bigint index = MathLib::toLongNumber(tok->strAt(3)); - if (index < 0 || index >= size) - { - std::vector indexes; - indexes.push_back(index); - arrayIndexOutOfBoundsError(tok->next(), info, indexes); - } - } - } - else if (!tok->isName() && !Token::Match(tok, "[.&]") && Token::Match(tok->next(), (varnames + " [ %num% ]").c_str())) + if ((varid > 0 && ((tok->str() == "return" || (!tok->isName() && !Token::Match(tok, "[.&]"))) && Token::Match(tok->next(), "%varid% [ %num% ]", varid))) || + (varid == 0 && ((tok->str() == "return" || (!tok->isName() && !Token::Match(tok, "[.&]"))) && Token::Match(tok->next(), (varnames + " [ %num% ]").c_str())))) + { const MathLib::bigint index = MathLib::toLongNumber(tok->strAt(3 + varc)); if (index >= size) @@ -964,11 +928,10 @@ void CheckBufferOverrun::checkScope(const Token *tok, const std::vectortokAt(1 + varc), info, indexes); } - tok = tok->tokAt(4); + tok = tok->tokAt(4 + varc); continue; } - // memset, memcmp, memcpy, strncpy, fgets.. if (varid == 0 && size > 0) { diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index b35b937e2..b860f537b 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -502,6 +502,18 @@ private: "}\n"); ASSERT_EQUALS("[test.cpp:9]: (error) Array 'str[10]' index 10 out of bounds\n", errout.str()); + check("struct ABC\n" + "{\n" + " char str[10];\n" + "};\n" + "\n" + "static char f()\n" + "{\n" + " struct ABC abc;\n" + " return abc.str[10];\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:9]: (error) Array 'str[10]' index 10 out of bounds\n", errout.str()); + // This is not out of bounds because it is a variable length array check("struct ABC\n" "{\n" @@ -2769,13 +2781,21 @@ private: ASSERT_EQUALS("[test.cpp:4]: (error) Array 's[10]' index 10 out of bounds\n", errout.str()); // ticket #1670 - false negative when using return - check("void f()\n" + check("char f()\n" "{\n" " char *s = new int[10];\n" " return s[10];\n" "}\n"); ASSERT_EQUALS("[test.cpp:4]: (error) Array 's[10]' index 10 out of bounds\n", errout.str()); + check("struct Fred { char c[10]; };\n" + "char f()\n" + "{\n" + " Fred *f = new Fred;\n" + " return f->c[10];\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:5]: (error) Array 'c[10]' index 10 out of bounds\n", errout.str()); + check("void foo()\n" "{\n" "char * buf = new char[8];\n"