Handling pointers in 'CheckBufferOverrun_StructVariable'
This commit is contained in:
parent
0a86992806
commit
13f681879f
|
@ -323,6 +323,29 @@ static void CheckBufferOverrun_LocalVariable()
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
static void CheckBufferOverrun_StructVariable_CheckVar( TOKEN *tok1, const char varname[], const char dot[], const char arrname[], const int arrsize )
|
||||||
|
{
|
||||||
|
const char *badpattern[] = {"varname",".","arrname","[","","]",NULL};
|
||||||
|
badpattern[0] = varname;
|
||||||
|
badpattern[1] = dot;
|
||||||
|
badpattern[2] = arrname;
|
||||||
|
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()
|
static void CheckBufferOverrun_StructVariable()
|
||||||
{
|
{
|
||||||
const char *declstruct_pattern[] = {"struct","","{",0};
|
const char *declstruct_pattern[] = {"struct","","{",0};
|
||||||
|
@ -340,45 +363,33 @@ static void CheckBufferOverrun_StructVariable()
|
||||||
{
|
{
|
||||||
if ( tok2->str[0] == '}' )
|
if ( tok2->str[0] == '}' )
|
||||||
break;
|
break;
|
||||||
if ( strchr( ";{", tok2->str[0] ) )
|
|
||||||
{
|
|
||||||
const char *arrname = 0;
|
|
||||||
const char *arrsize = 0;
|
|
||||||
|
|
||||||
|
if ( strchr( ";{,(", tok2->str[0] ) )
|
||||||
|
{
|
||||||
// Declare array..
|
// Declare array..
|
||||||
if ( match(tok2->next, "var var [ num ] ;") )
|
if ( match(tok2->next, "var var [ num ] ;") )
|
||||||
{
|
{
|
||||||
arrname = getstr(tok2, 2);
|
const char *arrname = getstr(tok2, 2);
|
||||||
arrsize = getstr(tok2, 4);
|
const char *arrsize = getstr(tok2, 4);
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! arrname )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for ( TOKEN *tok3 = tokens; tok3; tok3 = tok3->next )
|
for ( TOKEN *tok3 = tokens; tok3; tok3 = tok3->next )
|
||||||
{
|
{
|
||||||
if ( strcmp(tok3->str, structname) )
|
if ( strcmp(tok3->str, structname) )
|
||||||
continue;
|
continue;
|
||||||
if ( ! match( tok3->next, "var ;" ) )
|
|
||||||
continue;
|
|
||||||
const char *varname = tok3->next->str;
|
|
||||||
|
|
||||||
const char *badpattern[] = {"varname",".","arrname","[","","]",NULL};
|
// Declare variable: Fred fred1;
|
||||||
badpattern[0] = varname;
|
if ( match( tok3->next, "var ;" ) )
|
||||||
badpattern[2] = arrname;
|
|
||||||
TOKEN *tok4 = findtoken( tok3, badpattern );
|
|
||||||
while (tok4)
|
|
||||||
{
|
{
|
||||||
if ( IsNumber( getstr(tok4, 4) ) )
|
const char *varname = tok3->next->str;
|
||||||
{
|
CheckBufferOverrun_StructVariable_CheckVar( tok3, varname, ".", arrname, atoi(arrsize) );
|
||||||
if ( atoi( getstr(tok4,4) ) >= atoi(arrsize) )
|
|
||||||
{
|
|
||||||
std::ostringstream errmsg;
|
|
||||||
errmsg << FileLine(tok4) << ": Buffer overrun";
|
|
||||||
ReportErr(errmsg.str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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) );
|
||||||
}
|
}
|
||||||
tok4 = findtoken( tok4->next, badpattern );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
32
tests.cpp
32
tests.cpp
|
@ -391,9 +391,36 @@ static void buffer_overrun()
|
||||||
" struct ABC abc;\n"
|
" struct ABC abc;\n"
|
||||||
" abc.str[10] = 0;\n"
|
" abc.str[10] = 0;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
check( CheckBufferOverrun, __LINE__, test8, "[test.cpp:9]: Buffer overrun\n" );
|
check( CheckBufferOverrun, __LINE__, test8, "[test.cpp:9]: Array index out of bounds\n" );
|
||||||
|
|
||||||
|
|
||||||
|
const char test9[] = "const int SIZE = 10;\n"
|
||||||
|
"\n"
|
||||||
|
"struct ABC\n"
|
||||||
|
"{\n"
|
||||||
|
" char str[SIZE];\n"
|
||||||
|
"};\n"
|
||||||
|
"\n"
|
||||||
|
"static void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" struct ABC abc;\n"
|
||||||
|
" abc.str[SIZE] = 0;\n"
|
||||||
|
"}\n";
|
||||||
|
check( CheckBufferOverrun, __LINE__, test9, "[test.cpp:11]: Array index out of bounds\n" );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const char test10[] = "struct ABC\n"
|
||||||
|
"{\n"
|
||||||
|
" char str[10];\n"
|
||||||
|
"};\n"
|
||||||
|
"\n"
|
||||||
|
"static void f(ABC *abc)\n"
|
||||||
|
"{\n"
|
||||||
|
" abc->str[10] = 0;\n"
|
||||||
|
"}\n";
|
||||||
|
check( CheckBufferOverrun, __LINE__, test10, "[test.cpp:8]: Array index out of bounds\n" );
|
||||||
|
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
/*
|
/*
|
||||||
|
@ -725,6 +752,7 @@ static void division()
|
||||||
|
|
||||||
static void unused_variable()
|
static void unused_variable()
|
||||||
{
|
{
|
||||||
|
/* TODO
|
||||||
// Unused private member variable...
|
// Unused private member variable...
|
||||||
const char test1[] = "class Fred\n"
|
const char test1[] = "class Fred\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -737,7 +765,7 @@ static void unused_variable()
|
||||||
"{\n"
|
"{\n"
|
||||||
" i = 0;\n"
|
" i = 0;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
*/
|
||||||
|
|
||||||
// Scope of variable..
|
// Scope of variable..
|
||||||
const char test2[] = "void f()\n"
|
const char test2[] = "void f()\n"
|
||||||
|
|
Loading…
Reference in New Issue