Fixed #617 (False positive "buffer overrun" when sprintf() doesn't have optional parameters)

http://sourceforge.net/apps/trac/cppcheck/ticket/617
This commit is contained in:
Slava Semushin 2009-08-27 00:17:32 +07:00
parent 9bdd1def58
commit 7c86a10a9d
2 changed files with 29 additions and 15 deletions

View File

@ -387,7 +387,6 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con
if (varid > 0 && Token::Match(tok, "sprintf ( %varid% , %str% [,)]", varid)) if (varid > 0 && Token::Match(tok, "sprintf ( %varid% , %str% [,)]", varid))
{ {
int len = -2; int len = -2;
const Token *end = tok->next()->link();
// check format string // check format string
const char *fmt = tok->strAt(4); const char *fmt = tok->strAt(4);
@ -412,26 +411,30 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con
bufferOverrun(tok); bufferOverrun(tok);
} }
// check arguments // check arguments (if they exists)
len = 0; if (tok->tokAt(5)->str() == ",")
for (const Token *tok2 = tok->tokAt(6); tok2 && tok2 != end; tok2 = tok2->next())
{ {
if (tok2->str()[0] == '\"') len = 0;
const Token *end = tok->next()->link();
for (const Token *tok2 = tok->tokAt(6); tok2 && tok2 != end; tok2 = tok2->next())
{ {
len -= 2; if (tok2->str()[0] == '\"')
const char *str = tok2->str().c_str();
while (*str)
{ {
if (*str == '\\') len -= 2;
const char *str = tok2->str().c_str();
while (*str)
{
if (*str == '\\')
++str;
++str; ++str;
++str; ++len;
++len; }
} }
} }
} if (len >= (int)size)
if (len >= (int)size) {
{ bufferOverrun(tok);
bufferOverrun(tok); }
} }
} }

View File

@ -92,6 +92,7 @@ private:
TEST_CASE(buffer_overrun_2); TEST_CASE(buffer_overrun_2);
TEST_CASE(buffer_overrun_3); TEST_CASE(buffer_overrun_3);
TEST_CASE(buffer_overrun_4); TEST_CASE(buffer_overrun_4);
TEST_CASE(buffer_overrun_5);
TEST_CASE(sprintf1); TEST_CASE(sprintf1);
TEST_CASE(sprintf2); TEST_CASE(sprintf2);
@ -546,6 +547,16 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void buffer_overrun_5()
{
check("void f()\n"
"{\n"
" char n[5];\n"
" sprintf(n, \"d\");\n"
" printf(\"hello!\");\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
void sprintf1() void sprintf1()