Cleaned up snprintf hardcoding in CheckBufferOverrun

This commit is contained in:
Daniel Marjamäki 2015-02-13 06:44:38 +01:00
parent a6cfd15bde
commit 2d21eb07ba
6 changed files with 13 additions and 109 deletions

View File

@ -5298,6 +5298,11 @@
<noreturn>false</noreturn>
<leak-ignore/>
<formatstr/>
<arg nr="1">
<not-null/>
<minsize type="argvalue" arg="2"/>
<minsize type="strlen" arg="3"/>
</arg>
<arg nr="2">
<not-uninit/>
</arg>

View File

@ -692,14 +692,6 @@ void CheckBufferOverrun::checkScope(const Token *tok, const std::vector<std::str
}
}
// snprintf..
const std::string snprintfPattern = declarationId > 0 ? std::string("snprintf ( %varid% , %num% ,") : ("snprintf ( " + varnames + " , %num% ,");
if (Token::Match(tok, snprintfPattern.c_str(), declarationId)) {
const MathLib::bigint n = MathLib::toLongNumber(tok->strAt(4 + varcount));
if (n > total_size)
outOfBoundsError(tok->tokAt(4 + varcount), "snprintf size", true, n, total_size);
}
// Check function call..
if (Token::Match(tok, "%name% (")) {
// No varid => function calls are not handled
@ -973,13 +965,6 @@ void CheckBufferOverrun::checkScope(const Token *tok, const ArrayInfo &arrayInfo
tok2 = tok2->tokAt(7);
}
}
// snprintf..
if (total_size > 0 && Token::Match(tok, "snprintf ( %varid% , %num% ,", declarationId)) {
const MathLib::bigint n = MathLib::toLongNumber(tok->strAt(4));
if (n > total_size)
outOfBoundsError(tok->tokAt(4), "snprintf size", true, n, total_size);
}
}
}
}

View File

@ -2,5 +2,5 @@
int main()
{
char str[5];
snprintf(str, 10, "%s", "abc");
snprintf(str, 10, "%s", "0123456789abcdef");
}

View File

@ -1 +1 @@
[samples\outOfBounds\bad.c:5]: (error) snprintf size is out of bounds: Supplied size 10 is larger than actual size 5.
[samples\outOfBounds\bad.c:5]: (error) Buffer is accessed out of bounds: str

View File

@ -16,6 +16,12 @@ void bufferAccessOutOf(void) {
fgets(a,5,stdin);
// cppcheck-suppress bufferAccessOutOfBounds
fgets(a,6,stdin);
sprintf(a, "ab%s", "cd");
// cppcheck-suppress bufferAccessOutOfBounds
sprintf(a, "ab%s", "cde");
snprintf(a, 5, "abcde%i", 1);
// cppcheck-suppress bufferAccessOutOfBounds
snprintf(a, 6, "abcde%i", 1);
strcpy(a,"abcd");
// cppcheck-suppress bufferAccessOutOfBounds
strcpy(a, "abcde");

View File

@ -209,13 +209,6 @@ private:
TEST_CASE(pointer_out_of_bounds_2);
TEST_CASE(pointer_out_of_bounds_sub);
TEST_CASE(snprintf1);
TEST_CASE(snprintf2);
TEST_CASE(snprintf4);
TEST_CASE(snprintf5);
TEST_CASE(snprintf6);
TEST_CASE(snprintf7);
TEST_CASE(strncat1);
TEST_CASE(strncat2);
TEST_CASE(strncat3);
@ -2893,91 +2886,6 @@ private:
ASSERT_EQUALS("[test.cpp:4]: (portability) Undefined behaviour, when 'i' is -20 the pointer arithmetic 'x-i' is out of bounds.\n", errout.str());
}
void snprintf1() {
check("void f()\n"
"{\n"
" char str[5];\n"
" snprintf(str, 10, \"%s\", \"abc\");\n"
"}");
ASSERT_EQUALS("[test.cpp:4]: (error) snprintf size is out of bounds: Supplied size 10 is larger than actual size 5.\n", errout.str());
}
void snprintf2() {
check("void f()\n"
"{\n"
" char str[5];\n"
" snprintf(str, 5, \"%s\", \"abc\");\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void snprintf4() {
check("void f(int x)\n"
"{\n"
" char str[5];\n"
" snprintf(str, 8 - x, \"abcdefghijkl\");\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void snprintf5() {
check("struct Foo { char a[1]; };\n"
"void f()\n"
"{\n"
" struct Foo x;\n"
" snprintf(x.a, 2, \"aa\");\n"
"}");
ASSERT_EQUALS("[test.cpp:5]: (error) snprintf size is out of bounds: Supplied size 2 is larger than actual size 1.\n", errout.str());
// This is out of bounds if 'sizeof(ABC)' is 1 (No padding)
check("struct Foo { char a[1]; };\n"
"void f()\n"
"{\n"
" struct Foo *x = malloc(sizeof(Foo));\n"
" snprintf(x.a, 2, \"aa\");\n"
" free(x);\n"
"}");
TODO_ASSERT_EQUALS("error", "", errout.str());
check("struct Foo { char a[1]; };\n"
"void f()\n"
"{\n"
" struct Foo *x = malloc(sizeof(Foo) + 10);\n"
" snprintf(x.a, 2, \"aa\");\n"
" free(x);\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void snprintf6() {
check("struct Foo { char a[3]; };\n"
"void f()\n"
"{\n"
" struct Foo x;\n"
" snprintf(x.a, 2, \"aa\");\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void snprintf7() {
check("void x() {\n"
" sal_Char pString[1024];\n"
" snprintf(pString, 1024, \"ab\");\n"
"}");
ASSERT_EQUALS("", errout.str());
// #6141 FP: Unknown type is assumed to have size 0
check("typedef struct {\n"
" CHAR s[42];\n"
"} sct_t;\n"
"void foo() {\n"
" sct_t p;\n"
" snprintf(p.s, 42, \"abcdef\");\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
void strncat1() {
checkstd("void f(char *a, char *b) {\n"
" char str[16];\n"