Fixed #714 (False Buffer overrun with -a when i is increased by more than 1 in a loop)

http://sourceforge.net/apps/trac/cppcheck/ticket/714
This commit is contained in:
Slava Semushin 2009-09-27 21:09:41 +07:00
parent d1f3953cce
commit 07f41f4563
2 changed files with 58 additions and 4 deletions

View File

@ -32,7 +32,7 @@
#include <cstring>
#include <cctype>
#include <cassert> // <- assert
#include <cstdlib> // <- 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<long>(std::atol(tok2->strAt(2)) - 1);
value = std::atoi(tok2->strAt(2));
max_counter_value = MathLib::toString<long>(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))

View File

@ -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"