Check for buffer overruns for struct members (only numeric)
This commit is contained in:
parent
c8038d52fd
commit
0a86992806
|
@ -156,7 +156,7 @@ static void _DynamicData()
|
|||
// Buffer overrun..
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void CheckBufferOverrun()
|
||||
static void CheckBufferOverrun_LocalVariable()
|
||||
{
|
||||
_DynamicData();
|
||||
|
||||
|
@ -323,6 +323,76 @@ void CheckBufferOverrun()
|
|||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
static void CheckBufferOverrun_StructVariable()
|
||||
{
|
||||
const char *declstruct_pattern[] = {"struct","","{",0};
|
||||
for ( TOKEN * tok = findtoken( tokens, declstruct_pattern );
|
||||
tok;
|
||||
tok = findtoken( tok->next, declstruct_pattern ) )
|
||||
{
|
||||
const char *structname = tok->next->str;
|
||||
|
||||
if ( ! IsName( structname ) )
|
||||
continue;
|
||||
|
||||
// Found a struct declaration. Search for arrays..
|
||||
for ( TOKEN * tok2 = tok->next->next; tok2; tok2 = tok2->next )
|
||||
{
|
||||
if ( tok2->str[0] == '}' )
|
||||
break;
|
||||
if ( strchr( ";{", tok2->str[0] ) )
|
||||
{
|
||||
const char *arrname = 0;
|
||||
const char *arrsize = 0;
|
||||
|
||||
// Declare array..
|
||||
if ( match(tok2->next, "var var [ num ] ;") )
|
||||
{
|
||||
arrname = getstr(tok2, 2);
|
||||
arrsize = getstr(tok2, 4);
|
||||
}
|
||||
|
||||
if ( ! arrname )
|
||||
continue;
|
||||
|
||||
for ( TOKEN *tok3 = tokens; tok3; tok3 = tok3->next )
|
||||
{
|
||||
if ( strcmp(tok3->str, structname) )
|
||||
continue;
|
||||
if ( ! match( tok3->next, "var ;" ) )
|
||||
continue;
|
||||
const char *varname = tok3->next->str;
|
||||
|
||||
const char *badpattern[] = {"varname",".","arrname","[","","]",NULL};
|
||||
badpattern[0] = varname;
|
||||
badpattern[2] = arrname;
|
||||
TOKEN *tok4 = findtoken( tok3, badpattern );
|
||||
while (tok4)
|
||||
{
|
||||
if ( IsNumber( getstr(tok4, 4) ) )
|
||||
{
|
||||
if ( atoi( getstr(tok4,4) ) >= atoi(arrsize) )
|
||||
{
|
||||
std::ostringstream errmsg;
|
||||
errmsg << FileLine(tok4) << ": Buffer overrun";
|
||||
ReportErr(errmsg.str());
|
||||
}
|
||||
}
|
||||
tok4 = findtoken( tok4->next, badpattern );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void CheckBufferOverrun()
|
||||
{
|
||||
CheckBufferOverrun_LocalVariable();
|
||||
CheckBufferOverrun_StructVariable();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
|
20
tests.cpp
20
tests.cpp
|
@ -289,6 +289,7 @@ static void buffer_overrun()
|
|||
// test5: constant array index
|
||||
// test6: calculated array index that is out of bounds
|
||||
// test7: unknown string length
|
||||
// test8: struct member..
|
||||
|
||||
const char test1[] = "void f()\n"
|
||||
"{\n"
|
||||
|
@ -380,9 +381,23 @@ static void buffer_overrun()
|
|||
check( CheckBufferOverrun, __LINE__, test7, err7 );
|
||||
|
||||
|
||||
const char test8[] = "struct ABC\n"
|
||||
"{\n"
|
||||
" char str[10];\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"static void f()\n"
|
||||
"{\n"
|
||||
" struct ABC abc;\n"
|
||||
" abc.str[10] = 0;\n"
|
||||
"}\n";
|
||||
check( CheckBufferOverrun, __LINE__, test8, "[test.cpp:9]: Buffer overrun\n" );
|
||||
|
||||
|
||||
|
||||
// TODO
|
||||
/*
|
||||
const char test8[] = "class Fred\n"
|
||||
const char test[] = "class Fred\n"
|
||||
"{\n"
|
||||
"private:\n"
|
||||
" char str[10];\n"
|
||||
|
@ -393,8 +408,9 @@ static void buffer_overrun()
|
|||
"{\n"
|
||||
" str[10] = 0;\n"
|
||||
"}\n";
|
||||
check( CheckBufferOverrun, __LINE__, test8, "[test.cpp:5]: Array index out of bounds\n" );
|
||||
check( CheckBufferOverrun, __LINE__, test, "[test.cpp:5]: Array index out of bounds\n" );
|
||||
*/
|
||||
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
|
Loading…
Reference in New Issue