CheckBufferOverrun : Using variable id to check local array variables

This commit is contained in:
Daniel Marjamäki 2008-12-12 20:10:56 +00:00
parent a44c21da08
commit 6383b9d2bd
3 changed files with 43 additions and 15 deletions

View File

@ -64,7 +64,7 @@ void CheckBufferOverrunClass::ReportError(const TOKEN *tok, const char errmsg[])
// Check array usage..
//---------------------------------------------------------------------------
void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope( const TOKEN *tok, const char *varname[], const int size, const int total_size )
void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope( const TOKEN *tok, const char *varname[], const int size, const int total_size, unsigned int varid )
{
unsigned int varc = 1;
while ( varname[varc] )
@ -72,8 +72,19 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope( const TOKEN *tok, c
varc = 2 * ( varc - 1 );
// Array index..
if ( TOKEN::Match(tok, "%var1% [ %num% ]", varname) )
// Array index..
if ( varid > 0 )
{
if ( TOKEN::Match(tok, "%varid% [ %num% ]", 0, 0, varid) )
{
const char *num = tok->strAt(2);
if (strtol(num, NULL, 10) >= size)
{
ReportError(tok->next(), "Array index out of bounds");
}
}
}
else if ( TOKEN::Match(tok, "%var1% [ %num% ]", varname) )
{
const char *num = tok->strAt(2 + varc);
if (strtol(num, NULL, 10) >= size)
@ -97,9 +108,20 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope( const TOKEN *tok, c
if ( indentlevel < 0 )
return;
}
// Array index..
if ( !tok->isName() && !TOKEN::Match(tok,"[.&]") && TOKEN::Match(tok->next(), "%var1% [ %num% ]", varname) )
// Array index..
if ( varid > 0 )
{
if ( !tok->isName() && !TOKEN::Match(tok,"[.&]") && TOKEN::Match(tok->next(), "%varid% [ %num% ]", 0, 0, varid) )
{
const char *num = tok->strAt(3);
if (strtol(num, NULL, 10) >= size)
{
ReportError(tok->next(), "Array index out of bounds");
}
}
}
else if ( !tok->isName() && !TOKEN::Match(tok,"[.&]") && TOKEN::Match(tok->next(), "%var1% [ %num% ]", varname) )
{
const char *num = tok->next()->strAt(2 + varc);
if (strtol(num, NULL, 10) >= size)
@ -288,7 +310,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope( const TOKEN *tok, c
// Check variable usage in the function..
_callStack.push_back( tok );
CheckBufferOverrun_CheckScope( ftok, parname, size, total_size );
CheckBufferOverrun_CheckScope( ftok, parname, size, total_size, 0 );
_callStack.pop_back();
// break out..
@ -321,19 +343,22 @@ void CheckBufferOverrunClass::CheckBufferOverrun_LocalVariable()
{
const char *varname[2] = {0};
unsigned int size = 0;
const char *type = 0;
const char *type = 0;
unsigned int varid = 0;
if (TOKEN::Match(tok, "%type% %var% [ %num% ] ;"))
{
varname[0] = tok->strAt(1);
size = strtoul(tok->strAt(3), NULL, 10);
type = tok->aaaa();
type = tok->aaaa();
varid = tok->tokAt(1)->varId();
}
else if (indentlevel > 0 && TOKEN::Match(tok, "[*;{}] %var% = new %type% [ %num% ]"))
{
varname[0] = tok->strAt(1);
size = strtoul(tok->strAt(6), NULL, 10);
type = tok->strAt(4);
varid = tok->tokAt(1)->varId();
}
else
{
@ -346,7 +371,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_LocalVariable()
// The callstack is empty
_callStack.clear();
CheckBufferOverrun_CheckScope( tok->tokAt(5), varname, size, total_size );
CheckBufferOverrun_CheckScope( tok->tokAt(5), varname, size, total_size, varid );
}
}
}
@ -413,7 +438,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_StructVariable()
if ( TOKEN::Match(tok4, ") {") )
{
const char *names[2] = {varname[1], 0};
CheckBufferOverrun_CheckScope( tok4->tokAt(2), names, arrsize, total_size );
CheckBufferOverrun_CheckScope( tok4->tokAt(2), names, arrsize, total_size, 0 );
break;
}
}
@ -470,7 +495,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_StructVariable()
continue;
// Check variable usage..
CheckBufferOverrun_CheckScope( CheckTok, varname, arrsize, total_size );
CheckBufferOverrun_CheckScope( CheckTok, varname, arrsize, total_size, 0 );
}
}
}

View File

@ -40,7 +40,7 @@ public:
private:
void CheckBufferOverrun_StructVariable();
void CheckBufferOverrun_LocalVariable();
void CheckBufferOverrun_CheckScope( const TOKEN *tok, const char *varname[], const int size, const int total_size );
void CheckBufferOverrun_CheckScope( const TOKEN *tok, const char *varname[], const int size, const int total_size, unsigned int varid );
void ReportError(const TOKEN *tok, const char errmsg[]);
const Tokenizer *_tokenizer;

View File

@ -42,7 +42,10 @@ private:
Tokenizer tokenizer;
std::istringstream istr(code);
tokenizer.tokenize( istr, "test.cpp" );
tokenizer.simplifyTokenList();
tokenizer.simplifyTokenList();
// Assign variable ids
tokenizer.setVarId();
// Fill function list
tokenizer.fillFunctionList();
@ -80,7 +83,7 @@ private:
TEST_CASE( buffer_overrun_1 );
TEST_CASE( buffer_overrun_2 );
// TODO TEST_CASE( varid1 );
TEST_CASE( varid1 );
}