refactor to unify functionally identical code in CheckBufferOverrun::checkScope()

This commit is contained in:
Robert Reif 2011-09-11 14:00:53 -04:00
parent e18fe56d56
commit 19928e26d1
2 changed files with 27 additions and 44 deletions

View File

@ -872,20 +872,8 @@ void CheckBufferOverrun::checkScope(const Token *tok, const std::vector<std::str
}
// Array index..
if (varid > 0)
{
if (Token::Match(tok, "%varid% [ %num% ]", varid))
{
const MathLib::bigint index = MathLib::toLongNumber(tok->strAt(2));
if (index >= size)
{
std::vector<MathLib::bigint> 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<std::str
break;
// Array index..
if (varid > 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<MathLib::bigint> 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<MathLib::bigint> 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::vector<std::str
indexes.push_back(index);
arrayIndexOutOfBoundsError(tok->tokAt(1 + varc), info, indexes);
}
tok = tok->tokAt(4);
tok = tok->tokAt(4 + varc);
continue;
}
// memset, memcmp, memcpy, strncpy, fgets..
if (varid == 0 && size > 0)
{

View File

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