diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index 7dd38d0f5..1df01b469 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -62,12 +62,6 @@ void CheckNullPointer::parseFunctionCall(const Token &tok, std::list args = getArguments(&tok); - const Token* firstParam = args.size() > 0 ? args[0] : nullptr; - const Token* secondParam = args.size() > 1 ? args[1] : nullptr; - - // 1st parameter.. - if (Token::Match(&tok, "snprintf|vsnprintf|fnprintf|vfnprintf") && secondParam && secondParam->str() != "0") // Only if length (second parameter) is not zero - var.push_back(firstParam); if (library || tok.function() != nullptr) { for (int argnr = 1; argnr <= args.size(); ++argnr) { @@ -82,30 +76,23 @@ void CheckNullPointer::parseFunctionCall(const Token &tok, std::listformatstr_function(&tok)) { + const int formatStringArgNr = library->formatstr_argno(&tok); + if (formatStringArgNr < 0 || formatStringArgNr >= args.size()) + return; - if (Token::Match(&tok, "printf|scanf|wprintf|wscanf ( %str%")) { - formatString = firstParam->strValue(); - argnr = 1; - } else if (Token::Match(&tok, "sprintf|fprintf|sscanf|fscanf|fwprintf|fwscanf|swscanf")) { - const Token* formatStringTok = secondParam; // Find second parameter (format string) - if (formatStringTok && formatStringTok->tokType() == Token::eString) { - argnr = 2; // third parameter (first argument of va_args) - formatString = formatStringTok->strValue(); - } - } else if (Token::Match(&tok, "snprintf|fnprintf|swprintf") && secondParam) { - const Token* formatStringTok = args.size() > 2 ? args[2] : nullptr; // third parameter (format string) - if (formatStringTok && formatStringTok->tokType() == Token::eString) { - argnr = 3; // fourth parameter (first argument of va_args) - formatString = formatStringTok->strValue(); - } - } + // 1st parameter.. + if (Token::Match(&tok, "snprintf|vsnprintf|fnprintf|vfnprintf") && args.size() > 1 && !(args[1] && args[1]->hasKnownIntValue() && args[1]->getKnownIntValue() == 0)) // Only if length (second parameter) is not zero + var.push_back(args[0]); + + if (args[formatStringArgNr]->tokType() != Token::eString) + return; + const std::string &formatString = args[formatStringArgNr]->strValue(); + int argnr = formatStringArgNr + 1; + const bool scan = library->formatstr_scan(&tok); bool percent = false; - for (std::string::iterator i = formatString.begin(); i != formatString.end(); ++i) { + for (std::string::const_iterator i = formatString.begin(); i != formatString.end(); ++i) { if (*i == '%') { percent = !percent; } else if (percent) { diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index d70d8a719..4f9a1c36b 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -40,19 +40,7 @@ private: Settings settings; void run() OVERRIDE { - // Load std.cfg configuration - { - const char xmldata[] = "\n" - "\n" - " \n" - " \n" - " \n" - " \n" - ""; - tinyxml2::XMLDocument doc; - doc.Parse(xmldata, sizeof(xmldata)); - settings.library.load(doc); - } + LOAD_LIB_2(settings.library, "std.cfg"); settings.addEnabled("warning"); TEST_CASE(nullpointerAfterLoop);