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() {