Modify CheckBufferOverrun::checkGlobalAndLocalVariable() to use varid only.
Also add some TODO test cases.
This commit is contained in:
parent
46328ae01a
commit
9db22d9b48
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in New Issue