Check for buffer overruns for struct members (only numeric)

This commit is contained in:
Daniel Marjamäki 2008-03-21 17:25:25 +00:00
parent c8038d52fd
commit 0a86992806
2 changed files with 89 additions and 3 deletions

View File

@ -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();
}
//---------------------------------------------------------------------------

View File

@ -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" );
*/
}
//---------------------------------------------------------------------------