Refactoring the 'CheckBufferOverrun'
This commit is contained in:
parent
954cccf843
commit
1e379b8ffa
|
@ -33,10 +33,10 @@ static void ReportError(const TOKEN *tok, const char errmsg[])
|
|||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Checking local variables in a scope
|
||||
// Check array usage..
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
static void CheckBufferOverrun_LocalVariable_CheckScope( const TOKEN *tok, const char varname[], const int size, const int total_size )
|
||||
static void CheckBufferOverrun_CheckScope( const TOKEN *tok, const char varname[], const char arrname[], const int size, const int total_size )
|
||||
{
|
||||
int indentlevel = 0;
|
||||
for ( ; tok; tok = tok->next )
|
||||
|
@ -57,9 +57,15 @@ static void CheckBufferOverrun_LocalVariable_CheckScope( const TOKEN *tok, const
|
|||
|
||||
|
||||
// Array index..
|
||||
if (strcmp(tok->str,varname)==0 && match(tok->next,"[ num ]"))
|
||||
if ( match(tok, "var [ num ]") || match(tok, "var . var [ num ]" ) )
|
||||
{
|
||||
const char *str = getstr(tok, 2);
|
||||
if ( strcmp(tok->str, varname) != 0 )
|
||||
continue;
|
||||
|
||||
if ( arrname && strcmp(getstr(tok, 2), arrname) != 0 )
|
||||
continue;
|
||||
|
||||
const char *str = getstr(tok, (arrname ? 4 : 2));
|
||||
if (strtol(str, NULL, 10) >= size)
|
||||
{
|
||||
ReportError(tok, "Array index out of bounds");
|
||||
|
@ -76,21 +82,45 @@ static void CheckBufferOverrun_LocalVariable_CheckScope( const TOKEN *tok, const
|
|||
strcmp(tok->str,"strncpy")==0 ||
|
||||
strcmp(tok->str,"fgets")==0 )
|
||||
{
|
||||
if (match(tok->next,"( var , num , num )") ||
|
||||
match(tok->next,"( var , var , num )") )
|
||||
if (arrname == 0)
|
||||
{
|
||||
const char *var1 = getstr(tok, 2);
|
||||
const char *var2 = getstr(tok, 4);
|
||||
const char *num = getstr(tok, 6);
|
||||
if (match(tok->next,"( var , num , num )") ||
|
||||
match(tok->next,"( var , var , num )") )
|
||||
{
|
||||
const char *var1 = getstr(tok, 2);
|
||||
const char *var2 = getstr(tok, 4);
|
||||
const char *num = getstr(tok, 6);
|
||||
|
||||
if ( atoi(num)>total_size &&
|
||||
(strcmp(var1,varname)==0 ||
|
||||
strcmp(var2,varname)==0 ) )
|
||||
if ( atoi(num)>total_size &&
|
||||
(strcmp(var1,varname)==0 ||
|
||||
strcmp(var2,varname)==0 ) )
|
||||
{
|
||||
ReportError(tok, "Buffer overrun");
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
int pos = 0;
|
||||
|
||||
if ( match(tok->next, "( var . var , var , num )") )
|
||||
pos = 2;
|
||||
|
||||
else if ( match(tok->next, "( var , var . var , num )") )
|
||||
pos = 4;
|
||||
|
||||
else
|
||||
continue;
|
||||
|
||||
if ( strcmp( getstr(tok,pos), varname ) == 0 &&
|
||||
strcmp( getstr(tok,pos+2), arrname ) == 0 &&
|
||||
atoi(getstr(tok,8)) > total_size )
|
||||
{
|
||||
ReportError(tok, "Buffer overrun");
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
|
@ -140,12 +170,27 @@ static void CheckBufferOverrun_LocalVariable_CheckScope( const TOKEN *tok, const
|
|||
break;
|
||||
}
|
||||
|
||||
if ( match( tok2, "var [ var ]" ) &&
|
||||
strcmp(tok2->str,varname)==0 &&
|
||||
strcmp(getstr(tok2,2),strindex)==0 )
|
||||
if ( arrname == 0 )
|
||||
{
|
||||
ReportError(tok2, "Buffer overrun");
|
||||
break;
|
||||
if ( match( tok2, "var [ var ]" ) &&
|
||||
strcmp(tok2->str,varname)==0 &&
|
||||
strcmp(getstr(tok2,2),strindex)==0 )
|
||||
{
|
||||
ReportError(tok2, "Buffer overrun");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if ( match( tok2, "var . var [ var ]" ) &&
|
||||
strcmp(tok2->str,varname)==0 &&
|
||||
strcmp(getstr(tok2,2), arrname) == 0 &&
|
||||
strcmp(getstr(tok2,4), strindex) == 0 )
|
||||
{
|
||||
ReportError(tok2, "Buffer overrun");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tok2 = tok2->next;
|
||||
|
@ -155,33 +200,39 @@ static void CheckBufferOverrun_LocalVariable_CheckScope( const TOKEN *tok, const
|
|||
|
||||
|
||||
// Writing data into array..
|
||||
if (match(tok,"strcpy ( var , "))
|
||||
if ( match(tok,"strcpy ( var ") && strcmp(getstr(tok,2),varname)==0 )
|
||||
{
|
||||
int pos2 = 3;
|
||||
if ( arrname && match(gettok(tok,3),". var ,") && strcmp(getstr(tok,4),arrname)==0 )
|
||||
pos2 = 5;
|
||||
|
||||
// pos2 should point on the ','
|
||||
if ( strcmp( getstr(tok, pos2), "," ) )
|
||||
continue;
|
||||
|
||||
int len = 0;
|
||||
if (strcmp(getstr(tok, 2), varname) == 0)
|
||||
const char *str = getstr(tok, pos2 + 1);
|
||||
if (str[0] == '\"')
|
||||
{
|
||||
const char *str = getstr(tok, 4);
|
||||
if (str[0] == '\"')
|
||||
while (*str)
|
||||
{
|
||||
while (*str)
|
||||
{
|
||||
if (*str=='\\')
|
||||
str++;
|
||||
if (*str=='\\')
|
||||
str++;
|
||||
len++;
|
||||
}
|
||||
str++;
|
||||
len++;
|
||||
}
|
||||
if (len > 2 && len >= (int)size + 2)
|
||||
{
|
||||
ReportError(tok, "Buffer overrun");
|
||||
}
|
||||
}
|
||||
if (len > 2 && len >= (int)size + 2)
|
||||
{
|
||||
ReportError(tok, "Buffer overrun");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// Function call..
|
||||
if ( match( tok, "var (" ) )
|
||||
// Todo: Handle struct member variables..
|
||||
if ( arrname == 0 && match( tok, "var (" ) )
|
||||
{
|
||||
// Don't make recursive checking..
|
||||
if (std::find(CallStack.begin(), CallStack.end(), tok) != CallStack.end())
|
||||
|
@ -254,7 +305,7 @@ static void CheckBufferOverrun_LocalVariable_CheckScope( const TOKEN *tok, const
|
|||
|
||||
// Check variable usage in the function..
|
||||
CallStack.push_back( tok );
|
||||
CheckBufferOverrun_LocalVariable_CheckScope( ftok, parname, size, total_size );
|
||||
CheckBufferOverrun_CheckScope( ftok, parname, 0, size, total_size );
|
||||
CallStack.pop_back();
|
||||
|
||||
// break out..
|
||||
|
@ -268,6 +319,10 @@ static void CheckBufferOverrun_LocalVariable_CheckScope( const TOKEN *tok, const
|
|||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Checking local variables in a scope
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
static void CheckBufferOverrun_LocalVariable()
|
||||
{
|
||||
int indentlevel = 0;
|
||||
|
@ -289,7 +344,7 @@ static void CheckBufferOverrun_LocalVariable()
|
|||
|
||||
// The callstack is empty
|
||||
CallStack.clear();
|
||||
CheckBufferOverrun_LocalVariable_CheckScope( gettok(tok,5), varname, size, total_size );
|
||||
CheckBufferOverrun_CheckScope( gettok(tok,5), varname, 0, size, total_size );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -300,28 +355,6 @@ static void CheckBufferOverrun_LocalVariable()
|
|||
// Checking member variables of structs..
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
static void CheckBufferOverrun_StructVariable_CheckVar( const TOKEN *tok1, const char varname[], const char arrname[], const int arrsize )
|
||||
{
|
||||
const char *badpattern[] = {"varname",".","arrname","[","","]",NULL};
|
||||
badpattern[0] = varname;
|
||||
badpattern[2] = arrname;
|
||||
const TOKEN *tok2 = findtoken( tok1, badpattern );
|
||||
while (tok2)
|
||||
{
|
||||
if ( IsNumber( getstr(tok2, 4) ) )
|
||||
{
|
||||
if ( atoi( getstr(tok2, 4) ) >= arrsize )
|
||||
{
|
||||
std::ostringstream errmsg;
|
||||
errmsg << FileLine(tok2) << ": Array index out of bounds";
|
||||
ReportErr(errmsg.str());
|
||||
}
|
||||
}
|
||||
tok2 = findtoken( tok2->next, badpattern );
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
static void CheckBufferOverrun_StructVariable()
|
||||
{
|
||||
const char *declstruct_pattern[] = {"struct","","{",0};
|
||||
|
@ -346,7 +379,10 @@ static void CheckBufferOverrun_StructVariable()
|
|||
if ( match(tok2->next, "var var [ num ] ;") )
|
||||
{
|
||||
const char *arrname = getstr(tok2, 2);
|
||||
const char *arrsize = getstr(tok2, 4);
|
||||
int arrsize = atoi(getstr(tok2, 4));
|
||||
int total_size = arrsize * SizeOfType(tok2->next->str);
|
||||
if (total_size == 0)
|
||||
continue;
|
||||
|
||||
for ( const TOKEN *tok3 = tokens; tok3; tok3 = tok3->next )
|
||||
{
|
||||
|
@ -357,14 +393,14 @@ static void CheckBufferOverrun_StructVariable()
|
|||
if ( match( tok3->next, "var ;" ) )
|
||||
{
|
||||
const char *varname = tok3->next->str;
|
||||
CheckBufferOverrun_StructVariable_CheckVar( tok3, varname, arrname, atoi(arrsize) );
|
||||
CheckBufferOverrun_CheckScope( tok3, varname, arrname, arrsize, total_size );
|
||||
}
|
||||
|
||||
// Declare pointer: Fred *fred1
|
||||
else if ( match(tok3->next, "* var") && tok3->next->next->next && strchr(",);=", tok3->next->next->next->str[0]) )
|
||||
{
|
||||
const char *varname = tok3->next->next->str;
|
||||
CheckBufferOverrun_StructVariable_CheckVar( tok3, varname, arrname, atoi(arrsize) );
|
||||
CheckBufferOverrun_CheckScope( tok3, varname, arrname, arrsize, total_size );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue