refactor to unify functionally identical code in CheckBufferOverrun::checkScope()
This commit is contained in:
parent
e18fe56d56
commit
19928e26d1
|
@ -872,20 +872,8 @@ void CheckBufferOverrun::checkScope(const Token *tok, const std::vector<std::str
|
||||||
}
|
}
|
||||||
|
|
||||||
// Array index..
|
// Array index..
|
||||||
if (varid > 0)
|
if ((varid > 0 && Token::Match(tok, "%varid% [ %num% ]", varid)) ||
|
||||||
{
|
(varid == 0 && Token::Match(tok, (varnames + " [ %num% ]").c_str())))
|
||||||
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()))
|
|
||||||
{
|
{
|
||||||
const MathLib::bigint index = MathLib::toLongNumber(tok->strAt(2 + varc));
|
const MathLib::bigint index = MathLib::toLongNumber(tok->strAt(2 + varc));
|
||||||
if (index >= size)
|
if (index >= size)
|
||||||
|
@ -929,33 +917,9 @@ void CheckBufferOverrun::checkScope(const Token *tok, const std::vector<std::str
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Array index..
|
// Array index..
|
||||||
if (varid > 0)
|
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()))))
|
||||||
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()))
|
|
||||||
{
|
{
|
||||||
const MathLib::bigint index = MathLib::toLongNumber(tok->strAt(3 + varc));
|
const MathLib::bigint index = MathLib::toLongNumber(tok->strAt(3 + varc));
|
||||||
if (index >= size)
|
if (index >= size)
|
||||||
|
@ -964,11 +928,10 @@ void CheckBufferOverrun::checkScope(const Token *tok, const std::vector<std::str
|
||||||
indexes.push_back(index);
|
indexes.push_back(index);
|
||||||
arrayIndexOutOfBoundsError(tok->tokAt(1 + varc), info, indexes);
|
arrayIndexOutOfBoundsError(tok->tokAt(1 + varc), info, indexes);
|
||||||
}
|
}
|
||||||
tok = tok->tokAt(4);
|
tok = tok->tokAt(4 + varc);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// memset, memcmp, memcpy, strncpy, fgets..
|
// memset, memcmp, memcpy, strncpy, fgets..
|
||||||
if (varid == 0 && size > 0)
|
if (varid == 0 && size > 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -502,6 +502,18 @@ private:
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:9]: (error) Array 'str[10]' index 10 out of bounds\n", errout.str());
|
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
|
// This is not out of bounds because it is a variable length array
|
||||||
check("struct ABC\n"
|
check("struct ABC\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -2769,13 +2781,21 @@ private:
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Array 's[10]' index 10 out of bounds\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Array 's[10]' index 10 out of bounds\n", errout.str());
|
||||||
|
|
||||||
// ticket #1670 - false negative when using return
|
// ticket #1670 - false negative when using return
|
||||||
check("void f()\n"
|
check("char f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" char *s = new int[10];\n"
|
" char *s = new int[10];\n"
|
||||||
" return s[10];\n"
|
" return s[10];\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Array 's[10]' index 10 out of bounds\n", errout.str());
|
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"
|
check("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
"char * buf = new char[8];\n"
|
"char * buf = new char[8];\n"
|
||||||
|
|
Loading…
Reference in New Issue