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; unsigned int varc = 0;
std::string varnames; std::string varnames;
while (varname[varc]) while (varname && varname[varc])
{ {
if (varc > 0) if (varc > 0)
varnames += " . "; varnames += " . ";
@ -148,7 +148,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con
varc = 2 * (varc - 1); varc = 2 * (varc - 1);
// Array index.. // Array index..
if (varid > 0) if (varid > 0 && Token::Match(tok, "%varid% [ %num% ]", varid))
{ {
if (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.. // 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)); size_t len = Token::getStrLength(tok->tokAt(varc + 4));
if (len >= static_cast<size_t>(size)) 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.. // Dangerous usage of strncat..
if (varid > 0 && Token::Match(tok, "strncat ( %varid% , %any% , %num% )", varid)) 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; ++par;
} }
if (parlevel == 1 && Token::Match(tok2, std::string("[(,] " + varnames + " [,)]").c_str())) if (parlevel == 1)
{ {
++par; if ((varid > 0 && Token::Match(tok2, std::string("[(,] %varid% [,)]").c_str(), varid)) ||
break; (varid == 0 && Token::Match(tok2, std::string("[(,] " + varnames + " [,)]").c_str())))
{
++par;
break;
}
} }
} }
@ -623,7 +627,6 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable()
else if (tok->str() == "}") else if (tok->str() == "}")
--indentlevel; --indentlevel;
const char *varname[2] = {0};
unsigned int size = 0; unsigned int size = 0;
const char *type = 0; const char *type = 0;
unsigned int varid = 0; unsigned int varid = 0;
@ -638,7 +641,6 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable()
unsigned int varpos = 1; unsigned int varpos = 1;
if (tok->next()->str() == "*") if (tok->next()->str() == "*")
++varpos; ++varpos;
varname[0] = tok->strAt(varpos);
size = std::strtoul(tok->strAt(varpos + 2), NULL, 10); size = std::strtoul(tok->strAt(varpos + 2), NULL, 10);
type = tok->strAt(varpos - 1); type = tok->strAt(varpos - 1);
varid = tok->tokAt(varpos)->varId(); varid = tok->tokAt(varpos)->varId();
@ -646,7 +648,6 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable()
} }
else if (indentlevel > 0 && Token::Match(tok, "[*;{}] %var% = new %type% [ %num% ]")) else if (indentlevel > 0 && Token::Match(tok, "[*;{}] %var% = new %type% [ %num% ]"))
{ {
varname[0] = tok->strAt(1);
size = std::strtoul(tok->strAt(6), NULL, 10); size = std::strtoul(tok->strAt(6), NULL, 10);
type = tok->strAt(4); type = tok->strAt(4);
varid = tok->tokAt(1)->varId(); varid = tok->tokAt(1)->varId();
@ -654,7 +655,6 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable()
} }
else if (indentlevel > 0 && Token::Match(tok, "[*;{}] %var% = malloc ( %num% ) ;")) else if (indentlevel > 0 && Token::Match(tok, "[*;{}] %var% = malloc ( %num% ) ;"))
{ {
varname[0] = tok->strAt(1);
size = std::strtoul(tok->strAt(5), NULL, 10); size = std::strtoul(tok->strAt(5), NULL, 10);
type = "char"; type = "char";
varid = tok->tokAt(1)->varId(); varid = tok->tokAt(1)->varId();
@ -673,7 +673,7 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable()
// The callstack is empty // The callstack is empty
_callStack.clear(); _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_17);
TEST_CASE(array_index_18); TEST_CASE(array_index_18);
TEST_CASE(array_index_19); TEST_CASE(array_index_19);
TEST_CASE(array_index_multidim);
TEST_CASE(buffer_overrun_1); TEST_CASE(buffer_overrun_1);
TEST_CASE(buffer_overrun_2); TEST_CASE(buffer_overrun_2);
@ -623,6 +624,65 @@ private:
ASSERT_EQUALS("[test.cpp:4]: (error) Array index out of bounds\n", errout.str()); 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() void buffer_overrun_1()
{ {
check("void f()\n" check("void f()\n"