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..
|
// Buffer overrun..
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
void CheckBufferOverrun()
|
static void CheckBufferOverrun_LocalVariable()
|
||||||
{
|
{
|
||||||
_DynamicData();
|
_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
|
// test5: constant array index
|
||||||
// test6: calculated array index that is out of bounds
|
// test6: calculated array index that is out of bounds
|
||||||
// test7: unknown string length
|
// test7: unknown string length
|
||||||
|
// test8: struct member..
|
||||||
|
|
||||||
const char test1[] = "void f()\n"
|
const char test1[] = "void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -380,9 +381,23 @@ static void buffer_overrun()
|
||||||
check( CheckBufferOverrun, __LINE__, test7, err7 );
|
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
|
// TODO
|
||||||
/*
|
/*
|
||||||
const char test8[] = "class Fred\n"
|
const char test[] = "class Fred\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
"private:\n"
|
"private:\n"
|
||||||
" char str[10];\n"
|
" char str[10];\n"
|
||||||
|
@ -393,8 +408,9 @@ static void buffer_overrun()
|
||||||
"{\n"
|
"{\n"
|
||||||
" str[10] = 0;\n"
|
" str[10] = 0;\n"
|
||||||
"}\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