From ee3e10ea97f065d52d4f106f723c6c412e8616c7 Mon Sep 17 00:00:00 2001 From: PKEuS Date: Wed, 30 Nov 2011 20:23:29 +0100 Subject: [PATCH] Fixed #3364 (Crash in printf parsing) --- lib/checknullpointer.cpp | 2 ++ lib/checkother.cpp | 5 ++++- test/testnullpointer.cpp | 7 +++++++ test/testother.cpp | 5 ++++- 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index 8581a6aa8..83880a80f 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -177,6 +177,8 @@ void CheckNullPointer::parseFunctionCall(const Token &tok, std::listnextArgument(); ++i; + if (!argListTok || i == formatString.end()) + return; } if ((*i == 'n' || *i == 's' || scan) && (!scan || value == 0)) { diff --git a/lib/checkother.cpp b/lib/checkother.cpp index a49158a2c..3b044097a 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -71,6 +71,7 @@ void CheckOther::clarifyCalculation() { if (!_settings->isEnabled("style")) return; + for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { if (tok->strAt(1) == "?") { // condition @@ -1301,11 +1302,13 @@ void CheckOther::checkWrongPrintfScanfArguments() if (i == formatString.end()) break; } else if (percent) { - while (!std::isalpha(*i)) { + while (!std::isalpha(*i) && i != formatString.end()) { if (*i == '*') numFormat++; ++i; } + if (i == formatString.end()) + break; if (*i != 'm') // %m is a non-standard extension that requires no parameter numFormat++; diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 33f701074..5cb9922ba 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -1526,6 +1526,13 @@ private: " printf(\"text: %*s, %s\", s, 0);\n" "}"); 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() { diff --git a/test/testother.cpp b/test/testother.cpp index 047639fac..196bb3757 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -1965,6 +1965,8 @@ private: " printf(\"%udfd%%dfa%s%d\", 0, bar());\n" " fprintf(stderr,\"%u%s\");\n" " snprintf(str,10,\"%u%s\");\n" + " sprintf(string1, \"%-*.*s\", 32, string2);\n" // #3364 + " sprintf(string1, \"%*\", 32);\n" // #3364 "}\n", "test.cpp", true @@ -1975,7 +1977,8 @@ private: "[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: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" " printf(\"\", 0);\n"