diff --git a/src/checkbufferoverrun.cpp b/src/checkbufferoverrun.cpp index cff83d7e0..ee0ae054d 100644 --- a/src/checkbufferoverrun.cpp +++ b/src/checkbufferoverrun.cpp @@ -32,7 +32,7 @@ #include #include - +#include // <- assert #include // <- strtoul //--------------------------------------------------------------------------- @@ -246,14 +246,17 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con else continue; + int value = 0; if (counter_varid) { if (Token::Match(tok2, "%varid% < %num% ;", counter_varid)) { - max_counter_value = MathLib::toString(std::atol(tok2->strAt(2)) - 1); + value = std::atoi(tok2->strAt(2)); + max_counter_value = MathLib::toString(value - 1); } else if (Token::Match(tok2, "%varid% <= %num% ;", counter_varid)) { + value = std::atoi(tok2->strAt(2)); max_counter_value = tok2->strAt(2); } } @@ -261,10 +264,25 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con // Get index variable and stopsize. const char *strindex = tok2->str().c_str(); bool condition_out_of_bounds = true; - int value = ((tok2->strAt(1)[1] == '=') ? 1 : 0) + std::atoi(tok2->strAt(2)); - if (value <= size) + if (value < size) condition_out_of_bounds = false;; + const Token *tok3 = tok2->tokAt(4); + assert(tok3 != NULL); + if (Token::Match(tok3, "%varid% += %num% )", counter_varid) || + Token::Match(tok3, "%varid% = %num% + %varid% )", counter_varid)) + { + const int num = std::atoi(tok3->strAt(2)); + if (num > value) + condition_out_of_bounds = false; + } + else if (Token::Match(tok3, "%varid% = %varid% + %num% )", counter_varid)) + { + const int num = std::atoi(tok3->strAt(4)); + if (num > value) + condition_out_of_bounds = false; + } + // Goto the end paranthesis of the for-statement: "for (x; y; z)" .. tok2 = tok->next()->link(); if (!tok2 || !tok2->tokAt(5)) diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index f10c32a46..982d670c4 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -95,6 +95,7 @@ private: TEST_CASE(buffer_overrun_5); TEST_CASE(buffer_overrun_6); TEST_CASE(buffer_overrun_7); + TEST_CASE(buffer_overrun_8); TEST_CASE(sprintf1); TEST_CASE(sprintf2); @@ -594,6 +595,41 @@ private: ASSERT_EQUALS("", errout.str()); } + void buffer_overrun_8() + { + // ticket #714 + check("void f()\n" + "{\n" + " char a[5];\n" + " for (int i = 0; i < 20; i+= 100)\n" + " {\n" + " a[i] = 0;\n" + " }\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + check("void f()\n" + "{\n" + " char a[5];\n" + " for (int i = 0; i < 20; i = i + 100)\n" + " {\n" + " a[i] = 0;\n" + " }\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + check("void f()\n" + "{\n" + " char a[5];\n" + " for (int i = 0; i < 20; i = 100 + i)\n" + " {\n" + " a[i] = 0;\n" + " }\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + } + + void sprintf1() { check("void f()\n"