Modify CheckBufferOverrun::checkGlobalAndLocalVariable() to use varid only.

Also add some TODO test cases.
This commit is contained in:
Reijo Tomperi 2009-10-28 22:42:54 +02:00
parent 46328ae01a
commit 9db22d9b48
2 changed files with 72 additions and 12 deletions

View File

@ -132,7 +132,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con
unsigned int varc = 0;
std::string varnames;
while (varname[varc])
while (varname && varname[varc])
{
if (varc > 0)
varnames += " . ";
@ -148,7 +148,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con
varc = 2 * (varc - 1);
// Array index..
if (varid > 0)
if (varid > 0 && Token::Match(tok, "%varid% [ %num% ]", varid))
{
if (Token::Match(tok, "%varid% [ %num% ]", varid))
{
@ -449,7 +449,8 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con
// Writing data into array..
if (Token::Match(tok, ("strcpy|strcat ( " + varnames + " , %str% )").c_str()))
if ((varid > 0 && Token::Match(tok, "strcpy|strcat ( %varid% , %str% )", varid)) ||
(varid == 0 && Token::Match(tok, ("strcpy|strcat ( " + varnames + " , %str% )").c_str())))
{
size_t len = Token::getStrLength(tok->tokAt(varc + 4));
if (len >= static_cast<size_t>(size))
@ -459,7 +460,6 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con
}
}
// Dangerous usage of strncat..
if (varid > 0 && Token::Match(tok, "strncat ( %varid% , %any% , %num% )", varid))
{
@ -551,10 +551,14 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con
++par;
}
if (parlevel == 1 && Token::Match(tok2, std::string("[(,] " + varnames + " [,)]").c_str()))
if (parlevel == 1)
{
++par;
break;
if ((varid > 0 && Token::Match(tok2, std::string("[(,] %varid% [,)]").c_str(), varid)) ||
(varid == 0 && Token::Match(tok2, std::string("[(,] " + varnames + " [,)]").c_str())))
{
++par;
break;
}
}
}
@ -623,7 +627,6 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable()
else if (tok->str() == "}")
--indentlevel;
const char *varname[2] = {0};
unsigned int size = 0;
const char *type = 0;
unsigned int varid = 0;
@ -638,7 +641,6 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable()
unsigned int varpos = 1;
if (tok->next()->str() == "*")
++varpos;
varname[0] = tok->strAt(varpos);
size = std::strtoul(tok->strAt(varpos + 2), NULL, 10);
type = tok->strAt(varpos - 1);
varid = tok->tokAt(varpos)->varId();
@ -646,7 +648,6 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable()
}
else if (indentlevel > 0 && Token::Match(tok, "[*;{}] %var% = new %type% [ %num% ]"))
{
varname[0] = tok->strAt(1);
size = std::strtoul(tok->strAt(6), NULL, 10);
type = tok->strAt(4);
varid = tok->tokAt(1)->varId();
@ -654,7 +655,6 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable()
}
else if (indentlevel > 0 && Token::Match(tok, "[*;{}] %var% = malloc ( %num% ) ;"))
{
varname[0] = tok->strAt(1);
size = std::strtoul(tok->strAt(5), NULL, 10);
type = "char";
varid = tok->tokAt(1)->varId();
@ -673,7 +673,7 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable()
// The callstack is empty
_callStack.clear();
checkScope(tok->tokAt(nextTok), varname, size, total_size, varid);
checkScope(tok->tokAt(nextTok), 0, size, total_size, varid);
}
}
//---------------------------------------------------------------------------

View File

@ -89,6 +89,7 @@ private:
TEST_CASE(array_index_17);
TEST_CASE(array_index_18);
TEST_CASE(array_index_19);
TEST_CASE(array_index_multidim);
TEST_CASE(buffer_overrun_1);
TEST_CASE(buffer_overrun_2);
@ -623,6 +624,65 @@ private:
ASSERT_EQUALS("[test.cpp:4]: (error) Array index out of bounds\n", errout.str());
}
void array_index_multidim()
{
check("void f()\n"
"{\n"
" char a[2][2];\n"
" a[1][1] = 'a';\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("void f()\n"
"{\n"
" char a[2][2][2];\n"
" a[1][1][1] = 'a';\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("void f()\n"
"{\n"
" char a[2][2];\n"
" a[2][1] = 'a';\n"
"}\n");
TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Array index out of bounds\n", errout.str());
check("void f()\n"
"{\n"
" char a[2][2];\n"
" a[1][2] = 'a';\n"
"}\n");
TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Array index out of bounds\n", errout.str());
check("void f()\n"
"{\n"
" char a[2][2][2];\n"
" a[2][1][1] = 'a';\n"
"}\n");
TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Array index out of bounds\n", errout.str());
check("void f()\n"
"{\n"
" char a[2][2][2];\n"
" a[1][2][1] = 'a';\n"
"}\n");
TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Array index out of bounds\n", errout.str());
check("void f()\n"
"{\n"
" char a[2][2][2];\n"
" a[1][1][2] = 'a';\n"
"}\n");
TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Array index out of bounds\n", errout.str());
check("void f()\n"
"{\n"
" char a[2][2][2];\n"
" a[1][1][2] = 'a';\n"
"}\n");
TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Array index out of bounds\n", errout.str());
}
void buffer_overrun_1()
{
check("void f()\n"