Cleaned up snprintf hardcoding in CheckBufferOverrun
This commit is contained in:
parent
a6cfd15bde
commit
2d21eb07ba
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
int main()
|
||||
{
|
||||
char str[5];
|
||||
snprintf(str, 10, "%s", "abc");
|
||||
snprintf(str, 10, "%s", "0123456789abcdef");
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue