diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 5f93c86f4..4668c5c8e 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -1066,7 +1066,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const ArrayInfo &arrayInfo // just taking the address? const bool addr(tok2 && (tok2->str() == "&" || - Token::simpleMatch(tok2->previous(), "& ("))); + Token::simpleMatch(tok2->previous(), "& ("))); // taking address of 1 past end? if (addr && totalIndex == totalElements) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 662b10f2a..dedca2dfb 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1229,12 +1229,6 @@ void CheckOther::invalidScanfError(const Token *tok) void CheckOther::checkWrongPrintfScanfArguments() { - // This check is experimental. See #3311, #3313, #3339 - // TODO : fix tickets and remove this condition. When the condition - // is removed the classInfo and getErrorMessages must be updated - if (!_settings->experimental) - return; - if (!_settings->isEnabled("style")) return; @@ -1300,8 +1294,15 @@ void CheckOther::checkWrongPrintfScanfArguments() } if (i == formatString.end()) break; - } else if (percent && std::isalpha(*i)) { - numFormat++; + } else if (percent) { + while (!std::isalpha(*i)) { + if (*i == '*') + numFormat++; + ++i; + } + if (*i != 'm') // %m is a non-standard extension that requires no parameter + numFormat++; + percent = false; } } diff --git a/lib/checkother.h b/lib/checkother.h index e51a55acd..b32c633b1 100644 --- a/lib/checkother.h +++ b/lib/checkother.h @@ -353,7 +353,7 @@ public: c.bitwiseOnBooleanError(0, "varname", "&&"); c.comparisonOfBoolExpressionWithIntError(0); c.SuspiciousSemicolonError(0); - //c.wrongPrintfScanfArgumentsError(0,"printf",3,2); + c.wrongPrintfScanfArgumentsError(0,"printf",3,2); c.cctypefunctionCallError(0, "funname", "value"); } @@ -375,7 +375,7 @@ public: "* sizeof for numeric given as function argument\n" "* incorrect length arguments for 'substr' and 'strncmp'\n" "* invalid usage of output stream. For example: std::cout << std::cout;'\n" - //"* wrong number of arguments given to 'printf' or 'scanf;'\n" + "* wrong number of arguments given to 'printf' or 'scanf;'\n" // style "* C-style pointer cast in cpp file\n" diff --git a/test/testother.cpp b/test/testother.cpp index 06bfa3a82..d13a33c1f 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -1997,6 +1997,9 @@ private: " printf(\"%\"PRId64\"\n\", 123);\n" " fprintf(stderr,\"%\"PRId64\"\n\", 123);\n" " snprintf(str,10,\"%\"PRId64\"\n\", 123);\n" + " fprintf(stderr, \"error: %m\n\");\n" // #3339 + " printf(\"string: %.*s\n\", len, string);\n" // #3311 + " fprintf(stderr, \"%*cText.\n\", indent, ' ');\n" // #3313 "}\n", "test.cpp", true