Fixed #3364 (Crash in printf parsing)

This commit is contained in:
PKEuS 2011-11-30 20:23:29 +01:00 committed by Daniel Marjamäki
parent d0247f3a8d
commit ee3e10ea97
4 changed files with 17 additions and 2 deletions

View File

@ -177,6 +177,8 @@ void CheckNullPointer::parseFunctionCall(const Token &tok, std::list<const Token
if (*i == '*') if (*i == '*')
argListTok = argListTok->nextArgument(); argListTok = argListTok->nextArgument();
++i; ++i;
if (!argListTok || i == formatString.end())
return;
} }
if ((*i == 'n' || *i == 's' || scan) && (!scan || value == 0)) { if ((*i == 'n' || *i == 's' || scan) && (!scan || value == 0)) {

View File

@ -71,6 +71,7 @@ void CheckOther::clarifyCalculation()
{ {
if (!_settings->isEnabled("style")) if (!_settings->isEnabled("style"))
return; return;
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
if (tok->strAt(1) == "?") { if (tok->strAt(1) == "?") {
// condition // condition
@ -1301,11 +1302,13 @@ void CheckOther::checkWrongPrintfScanfArguments()
if (i == formatString.end()) if (i == formatString.end())
break; break;
} else if (percent) { } else if (percent) {
while (!std::isalpha(*i)) { while (!std::isalpha(*i) && i != formatString.end()) {
if (*i == '*') if (*i == '*')
numFormat++; numFormat++;
++i; ++i;
} }
if (i == formatString.end())
break;
if (*i != 'm') // %m is a non-standard extension that requires no parameter if (*i != 'm') // %m is a non-standard extension that requires no parameter
numFormat++; numFormat++;

View File

@ -1526,6 +1526,13 @@ private:
" printf(\"text: %*s, %s\", s, 0);\n" " printf(\"text: %*s, %s\", s, 0);\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:2]: (error) Null pointer dereference\n", errout.str()); ASSERT_EQUALS("[test.cpp:2]: (error) Null pointer dereference\n", errout.str());
// Ticket #3364
check("void f() {\n"
" printf(\"%-*.*s\", s, 0);\n"
" sprintf(\"%*\", s);\n"
"}");
ASSERT_EQUALS("", errout.str());
} }
void scanf_with_invalid_va_argument() { void scanf_with_invalid_va_argument() {

View File

@ -1965,6 +1965,8 @@ private:
" printf(\"%udfd%%dfa%s%d\", 0, bar());\n" " printf(\"%udfd%%dfa%s%d\", 0, bar());\n"
" fprintf(stderr,\"%u%s\");\n" " fprintf(stderr,\"%u%s\");\n"
" snprintf(str,10,\"%u%s\");\n" " snprintf(str,10,\"%u%s\");\n"
" sprintf(string1, \"%-*.*s\", 32, string2);\n" // #3364
" sprintf(string1, \"%*\", 32);\n" // #3364
"}\n", "}\n",
"test.cpp", "test.cpp",
true true
@ -1975,7 +1977,8 @@ private:
"[test.cpp:5]: (error) printf format string has 3 parameters but only 2 are given\n" "[test.cpp:5]: (error) printf format string has 3 parameters but only 2 are given\n"
"[test.cpp:6]: (error) printf format string has 3 parameters but only 2 are given\n" "[test.cpp:6]: (error) printf format string has 3 parameters but only 2 are given\n"
"[test.cpp:7]: (error) fprintf format string has 2 parameters but only 0 are given\n" "[test.cpp:7]: (error) fprintf format string has 2 parameters but only 0 are given\n"
"[test.cpp:8]: (error) snprintf format string has 2 parameters but only 0 are given\n", errout.str()); "[test.cpp:8]: (error) snprintf format string has 2 parameters but only 0 are given\n"
"[test.cpp:9]: (error) sprintf format string has 3 parameters but only 2 are given\n", errout.str());
check("void foo(char *str) {\n" check("void foo(char *str) {\n"
" printf(\"\", 0);\n" " printf(\"\", 0);\n"