Fix ticket #94 (STL container overrun). Check is currently behind --all
This commit is contained in:
parent
1373e14bc9
commit
9dff3f4c52
|
@ -555,12 +555,73 @@ void CheckBufferOverrunClass::CheckBufferOverrun_StructVariable()
|
|||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void CheckBufferOverrunClass::STLSizeProblems()
|
||||
{
|
||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
|
||||
{
|
||||
if (!Token::simpleMatch(tok, "for ("))
|
||||
continue;
|
||||
|
||||
|
||||
int indent = 1;
|
||||
tok = tok->tokAt(2);
|
||||
const Token *num = 0;
|
||||
const Token *var = 0;
|
||||
while (tok)
|
||||
{
|
||||
|
||||
if (tok->str() == "(")
|
||||
++indent;
|
||||
if (tok->str() == ")")
|
||||
{
|
||||
--indent;
|
||||
if (indent == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (Token::Match(tok, "; %var% <= %var% . size ( ) ;"))
|
||||
{
|
||||
num = tok->tokAt(1);
|
||||
var = tok->tokAt(3);
|
||||
}
|
||||
|
||||
tok = tok->next();
|
||||
}
|
||||
|
||||
tok = tok->next();
|
||||
if (!num || tok->str() != "{")
|
||||
continue;
|
||||
|
||||
std::string pattern = var->str() + " [ " + num->str() + " ]";
|
||||
while (tok)
|
||||
{
|
||||
|
||||
if (tok->str() == "{")
|
||||
++indent;
|
||||
if (tok->str() == "}")
|
||||
{
|
||||
--indent;
|
||||
if (indent == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (Token::Match(tok, pattern.c_str()))
|
||||
{
|
||||
_errorLogger->outOfBounds(_tokenizer, tok, "When " + num->str() + " == size(), " + pattern);
|
||||
}
|
||||
|
||||
tok = tok->next();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CheckBufferOverrunClass::bufferOverrun()
|
||||
{
|
||||
CheckBufferOverrun_LocalVariable();
|
||||
CheckBufferOverrun_StructVariable();
|
||||
STLSizeProblems();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -45,6 +45,12 @@ private:
|
|||
/** Check for buffer overruns - this is the function that performs the actual checking */
|
||||
void CheckBufferOverrun_CheckScope(const Token *tok, const char *varname[], const int size, const int total_size, unsigned int varid);
|
||||
|
||||
/**
|
||||
* Finds errors like this:
|
||||
* for (unsigned ii = 0; ii <= foo.size(); ++ii)
|
||||
*/
|
||||
void STLSizeProblems();
|
||||
|
||||
const Tokenizer *_tokenizer;
|
||||
const Settings _settings;
|
||||
ErrorLogger *_errorLogger;
|
||||
|
|
|
@ -93,6 +93,8 @@ private:
|
|||
|
||||
TEST_CASE(varid1);
|
||||
TEST_CASE(varid2);
|
||||
TEST_CASE(STLSize);
|
||||
TEST_CASE(STLSizeNoErr);
|
||||
}
|
||||
|
||||
|
||||
|
@ -471,7 +473,44 @@ private:
|
|||
ASSERT_EQUALS(std::string(""), errout.str());
|
||||
}
|
||||
|
||||
void STLSize()
|
||||
{
|
||||
check("void foo()\n"
|
||||
"{\n"
|
||||
" std::vector<int> foo;\n"
|
||||
" for (unsigned int ii = 0; ii <= foo.size(); ++ii)\n"
|
||||
" {\n"
|
||||
" foo[ii] = 0;\n"
|
||||
" }\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS(std::string("[test.cpp:6]: (error) When ii == size(), foo [ ii ] is out of bounds\n"), errout.str());
|
||||
}
|
||||
|
||||
void STLSizeNoErr()
|
||||
{
|
||||
{
|
||||
check("void foo()\n"
|
||||
"{\n"
|
||||
" std::vector<int> foo;\n"
|
||||
" for (unsigned int ii = 0; ii < foo.size(); ++ii)\n"
|
||||
" {\n"
|
||||
" foo[ii] = 0;\n"
|
||||
" }\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS(std::string(""), errout.str());
|
||||
}
|
||||
|
||||
{
|
||||
check("void foo()\n"
|
||||
"{\n"
|
||||
" std::vector<int> foo;\n"
|
||||
" for (unsigned int ii = 0; ii <= foo.size(); ++ii)\n"
|
||||
" {\n"
|
||||
" }\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS(std::string(""), errout.str());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_TEST(TestBufferOverrun)
|
||||
|
|
Loading…
Reference in New Issue