diff --git a/cfg/windows.cfg b/cfg/windows.cfg index 50ea2b6af..7ee2fd616 100644 --- a/cfg/windows.cfg +++ b/cfg/windows.cfg @@ -1310,6 +1310,26 @@ true + + + false + + + + + + + + + + false + + + + + + + false diff --git a/lib/checkio.cpp b/lib/checkio.cpp index e2d14850d..368e2277f 100644 --- a/lib/checkio.cpp +++ b/lib/checkio.cpp @@ -505,29 +505,16 @@ void CheckIO::checkWrongPrintfScanfArguments() bool scanf_s = false; int formatStringArgNo = -1; - if (tok->strAt(1) == "(" && _settings->library.formatstr_function(tok->str())) { - const std::map& argumentChecks = _settings->library.argumentChecks.at(tok->str()); - for (std::map::const_iterator i = argumentChecks.cbegin(); i != argumentChecks.cend(); ++i) { - if (i->second.formatstr) { - formatStringArgNo = i->first - 1; - break; - } - } - - scan = _settings->library.formatstr_scan(tok->str()); - scanf_s = _settings->library.formatstr_secure(tok->str()); + if (tok->strAt(1) == "(" && _settings->library.formatstr_function(tok)) { + formatStringArgNo = _settings->library.formatstr_argno(tok); + scan = _settings->library.formatstr_scan(tok); + scanf_s = _settings->library.formatstr_secure(tok); } if (formatStringArgNo >= 0) { // formatstring found in library. Find format string and first argument belonging to format string. if (!findFormat(static_cast(formatStringArgNo), tok->tokAt(2), &formatStringTok, &argListTok)) continue; - } else if (isWindows && Token::Match(tok, "Format|AppendFormat (") && - Token::Match(tok->tokAt(-2), "%var% .") && tok->tokAt(-2)->variable() && - tok->tokAt(-2)->variable()->typeStartToken()->str() == "CString") { - // Find second parameter and format string - if (!findFormat(0, tok->tokAt(2), &formatStringTok, &argListTok)) - continue; } else if (Token::simpleMatch(tok, "swprintf (") && Token::Match(tok->tokAt(2)->nextArgument(), "%str%")) { // Find third parameter and format string if (!findFormat(1, tok->tokAt(2), &formatStringTok, &argListTok)) diff --git a/lib/library.cpp b/lib/library.cpp index 711fe44a4..faa87a783 100644 --- a/lib/library.cpp +++ b/lib/library.cpp @@ -934,6 +934,33 @@ const Library::WarnInfo* Library::getWarnInfo(const Token* ftok) const return &i->second; } +bool Library::formatstr_function(const Token* ftok) const +{ + return (!isNotLibraryFunction(ftok) && + _formatstr.find(functionName(ftok)) != _formatstr.cend()); +} + +int Library::formatstr_argno(const Token* ftok) const +{ + const std::map& argumentChecksFunc = argumentChecks.at(functionName(ftok)); + for (std::map::const_iterator i = argumentChecksFunc.cbegin(); i != argumentChecksFunc.cend(); ++i) { + if (i->second.formatstr) { + return i->first - 1; + } + } + return -1; +} + +bool Library::formatstr_scan(const Token* ftok) const +{ + return _formatstr.at(functionName(ftok)).first; +} + +bool Library::formatstr_secure(const Token* ftok) const +{ + return _formatstr.at(functionName(ftok)).second; +} + bool Library::isUseRetVal(const Token* ftok) const { return (!isNotLibraryFunction(ftok) && diff --git a/lib/library.h b/lib/library.h index 02c965365..8607978e7 100644 --- a/lib/library.h +++ b/lib/library.h @@ -137,17 +137,13 @@ public: return ((func->groupId > 0) && ((func->groupId & 1) == 1)); } - bool formatstr_function(const std::string& funcname) const { - return _formatstr.find(funcname) != _formatstr.cend(); - } + bool formatstr_function(const Token* ftok) const; - bool formatstr_scan(const std::string& funcname) const { - return _formatstr.at(funcname).first; - } + int formatstr_argno(const Token* ftok) const; - bool formatstr_secure(const std::string& funcname) const { - return _formatstr.at(funcname).second; - } + bool formatstr_scan(const Token* ftok) const; + + bool formatstr_secure(const Token* ftok) const; std::set use; std::set leakignore; diff --git a/test/testio.cpp b/test/testio.cpp index a683cb82c..6d24f7d7e 100644 --- a/test/testio.cpp +++ b/test/testio.cpp @@ -2474,9 +2474,11 @@ private: " CString string;\n" " string.Format(\"%I32d\", u32);\n" " string.AppendFormat(\"%I32d\", u32);\n" + " CString::Format(\"%I32d\", u32);\n" "}", false, false, Settings::Win32A); ASSERT_EQUALS("[test.cpp:4]: (warning) %I32d in format string (no. 1) requires '__int32' but the argument type is 'unsigned __int32 {aka unsigned int}'.\n" - "[test.cpp:5]: (warning) %I32d in format string (no. 1) requires '__int32' but the argument type is 'unsigned __int32 {aka unsigned int}'.\n", errout.str()); + "[test.cpp:5]: (warning) %I32d in format string (no. 1) requires '__int32' but the argument type is 'unsigned __int32 {aka unsigned int}'.\n" + "[test.cpp:6]: (warning) %I32d in format string (no. 1) requires '__int32' but the argument type is 'unsigned __int32 {aka unsigned int}'.\n", errout.str()); } void testMicrosoftSecurePrintfArgument() {