Fix #730 (False positive, buffer overrun with strncpy)

http://sourceforge.net/apps/trac/cppcheck/ticket/730
This commit is contained in:
Reijo Tomperi 2009-09-25 23:32:18 +03:00
parent 6db95cd01c
commit 6a63742dde
2 changed files with 54 additions and 12 deletions

View File

@ -172,21 +172,18 @@ void CheckBufferOverrun::checkScope(const Token *tok, const char *varname[], con
// memset, memcmp, memcpy, strncpy, fgets..
if (varid > 0)
{
if (Token::Match(tok, "memset|memcpy|memmove|memcmp|strncpy|fgets"))
if (Token::Match(tok, "memset|memcpy|memmove|memcmp|strncpy|fgets ( %varid% , %any% , %any% )", varid) ||
Token::Match(tok, "memset|memcpy|memmove|memcmp|fgets ( %var% , %varid% , %any% )", varid))
{
if (Token::Match(tok->next(), "( %varid% , %any% , %any% )", varid) ||
Token::Match(tok->next(), "( %var% , %varid% , %any% )", varid))
const Token *tokSz = tok->tokAt(6);
if (tokSz->str()[0] == '\'')
sizeArgumentAsChar(tok);
else if (tokSz->isNumber())
{
const Token *tokSz = tok->tokAt(6);
if (tokSz->str()[0] == '\'')
sizeArgumentAsChar(tok);
else if (tokSz->isNumber())
const char *num = tok->strAt(6);
if (std::atoi(num) > total_size)
{
const char *num = tok->strAt(6);
if (std::atoi(num) > total_size)
{
bufferOverrun(tok);
}
bufferOverrun(tok);
}
}
}

View File

@ -119,6 +119,7 @@ private:
TEST_CASE(memset1);
TEST_CASE(counter_test);
TEST_CASE(strncpy1);
}
@ -794,6 +795,50 @@ private:
ASSERT_EQUALS(11, CheckBufferOverrun::count(str2));
ASSERT_EQUALS(8, CheckBufferOverrun::count(str3));
}
void strncpy1()
{
check("void f()\n"
"{\n"
" char a[6];\n"
" char c[7];\n"
" strcpy(a,\"hello\");\n"
" strncpy(c,a,sizeof(c));\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("void f()\n"
"{\n"
" char a[6];\n"
" char c[6];\n"
" strcpy(a,\"hello\");\n"
" strncpy(c,a,sizeof(c));\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("void f()\n"
"{\n"
" char a[6];\n"
" char c[5];\n"
" strcpy(a,\"hello\");\n"
" strncpy(c,a,sizeof(c)+1);\n"
"}\n");
ASSERT_EQUALS("[test.cpp:6]: (possible error) Buffer overrun\n", errout.str());
check("void f()\n"
"{\n"
" char c[6];\n"
" strncpy(c,\"hello!\",sizeof(c));\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("void f()\n"
"{\n"
" char c[6];\n"
" strncpy(c,\"hello!\",sizeof(c)+1);\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (possible error) Buffer overrun\n", errout.str());
}
};
REGISTER_TEST(TestBufferOverrun)