CheckBufferOverrun : Using variable id to check local array variables
This commit is contained in:
parent
a44c21da08
commit
6383b9d2bd
|
@ -64,7 +64,7 @@ void CheckBufferOverrunClass::ReportError(const TOKEN *tok, const char errmsg[])
|
||||||
// Check array usage..
|
// 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;
|
unsigned int varc = 1;
|
||||||
while ( varname[varc] )
|
while ( varname[varc] )
|
||||||
|
@ -72,8 +72,19 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope( const TOKEN *tok, c
|
||||||
varc = 2 * ( varc - 1 );
|
varc = 2 * ( varc - 1 );
|
||||||
|
|
||||||
|
|
||||||
// Array index..
|
// Array index..
|
||||||
if ( TOKEN::Match(tok, "%var1% [ %num% ]", varname) )
|
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);
|
const char *num = tok->strAt(2 + varc);
|
||||||
if (strtol(num, NULL, 10) >= size)
|
if (strtol(num, NULL, 10) >= size)
|
||||||
|
@ -97,9 +108,20 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope( const TOKEN *tok, c
|
||||||
if ( indentlevel < 0 )
|
if ( indentlevel < 0 )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Array index..
|
// Array index..
|
||||||
if ( !tok->isName() && !TOKEN::Match(tok,"[.&]") && TOKEN::Match(tok->next(), "%var1% [ %num% ]", varname) )
|
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);
|
const char *num = tok->next()->strAt(2 + varc);
|
||||||
if (strtol(num, NULL, 10) >= size)
|
if (strtol(num, NULL, 10) >= size)
|
||||||
|
@ -288,7 +310,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope( const TOKEN *tok, c
|
||||||
|
|
||||||
// Check variable usage in the function..
|
// Check variable usage in the function..
|
||||||
_callStack.push_back( tok );
|
_callStack.push_back( tok );
|
||||||
CheckBufferOverrun_CheckScope( ftok, parname, size, total_size );
|
CheckBufferOverrun_CheckScope( ftok, parname, size, total_size, 0 );
|
||||||
_callStack.pop_back();
|
_callStack.pop_back();
|
||||||
|
|
||||||
// break out..
|
// break out..
|
||||||
|
@ -321,19 +343,22 @@ void CheckBufferOverrunClass::CheckBufferOverrun_LocalVariable()
|
||||||
{
|
{
|
||||||
const char *varname[2] = {0};
|
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;
|
||||||
|
|
||||||
if (TOKEN::Match(tok, "%type% %var% [ %num% ] ;"))
|
if (TOKEN::Match(tok, "%type% %var% [ %num% ] ;"))
|
||||||
{
|
{
|
||||||
varname[0] = tok->strAt(1);
|
varname[0] = tok->strAt(1);
|
||||||
size = strtoul(tok->strAt(3), NULL, 10);
|
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% ]"))
|
else if (indentlevel > 0 && TOKEN::Match(tok, "[*;{}] %var% = new %type% [ %num% ]"))
|
||||||
{
|
{
|
||||||
varname[0] = tok->strAt(1);
|
varname[0] = tok->strAt(1);
|
||||||
size = strtoul(tok->strAt(6), NULL, 10);
|
size = strtoul(tok->strAt(6), NULL, 10);
|
||||||
type = tok->strAt(4);
|
type = tok->strAt(4);
|
||||||
|
varid = tok->tokAt(1)->varId();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -346,7 +371,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_LocalVariable()
|
||||||
|
|
||||||
// The callstack is empty
|
// The callstack is empty
|
||||||
_callStack.clear();
|
_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, ") {") )
|
if ( TOKEN::Match(tok4, ") {") )
|
||||||
{
|
{
|
||||||
const char *names[2] = {varname[1], 0};
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -470,7 +495,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_StructVariable()
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Check variable usage..
|
// Check variable usage..
|
||||||
CheckBufferOverrun_CheckScope( CheckTok, varname, arrsize, total_size );
|
CheckBufferOverrun_CheckScope( CheckTok, varname, arrsize, total_size, 0 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ public:
|
||||||
private:
|
private:
|
||||||
void CheckBufferOverrun_StructVariable();
|
void CheckBufferOverrun_StructVariable();
|
||||||
void CheckBufferOverrun_LocalVariable();
|
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[]);
|
void ReportError(const TOKEN *tok, const char errmsg[]);
|
||||||
|
|
||||||
const Tokenizer *_tokenizer;
|
const Tokenizer *_tokenizer;
|
||||||
|
|
|
@ -42,7 +42,10 @@ private:
|
||||||
Tokenizer tokenizer;
|
Tokenizer tokenizer;
|
||||||
std::istringstream istr(code);
|
std::istringstream istr(code);
|
||||||
tokenizer.tokenize( istr, "test.cpp" );
|
tokenizer.tokenize( istr, "test.cpp" );
|
||||||
tokenizer.simplifyTokenList();
|
tokenizer.simplifyTokenList();
|
||||||
|
|
||||||
|
// Assign variable ids
|
||||||
|
tokenizer.setVarId();
|
||||||
|
|
||||||
// Fill function list
|
// Fill function list
|
||||||
tokenizer.fillFunctionList();
|
tokenizer.fillFunctionList();
|
||||||
|
@ -80,7 +83,7 @@ private:
|
||||||
TEST_CASE( buffer_overrun_1 );
|
TEST_CASE( buffer_overrun_1 );
|
||||||
TEST_CASE( buffer_overrun_2 );
|
TEST_CASE( buffer_overrun_2 );
|
||||||
|
|
||||||
// TODO TEST_CASE( varid1 );
|
TEST_CASE( varid1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue