Fixed #4920 (Microsoft ATL/MFC CString::Format argument checking)
This commit is contained in:
parent
2de3ebcb1e
commit
44d86e97c0
|
@ -407,6 +407,7 @@ void CheckIO::checkWrongPrintfScanfArguments()
|
|||
{
|
||||
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||
bool warning = _settings->isEnabled("warning");
|
||||
bool windows = _settings->isWindowsPlatform();
|
||||
|
||||
std::size_t functions = symbolDatabase->functionScopes.size();
|
||||
for (std::size_t j = 0; j < functions; ++j) {
|
||||
|
@ -437,7 +438,11 @@ void CheckIO::checkWrongPrintfScanfArguments()
|
|||
|
||||
if (!formatString.empty()) {
|
||||
/* formatstring found in library */
|
||||
} else if (Token::Match(tok, "printf|scanf|wprintf|wscanf ( %str%")) {
|
||||
} else if (Token::Match(tok, "printf|scanf|wprintf|wscanf ( %str%") ||
|
||||
(windows && (Token::Match(tok, "Format|AppendFormat ( %str%") &&
|
||||
Token::Match(tok->tokAt(-2), "%var% .") && tok->tokAt(-2)->variable() &&
|
||||
tok->tokAt(-2)->variable()->typeStartToken()->str() == "CString"))) {
|
||||
|
||||
formatString = tok->strAt(2);
|
||||
if (tok->strAt(3) == ",") {
|
||||
argListTok = tok->tokAt(4);
|
||||
|
|
|
@ -240,6 +240,16 @@ public:
|
|||
|
||||
/** set the platform type for user specified platforms */
|
||||
bool platformFile(const std::string &filename);
|
||||
|
||||
/**
|
||||
* @brief Returns true if platform type is Windows
|
||||
* @return true if Windows platform type.
|
||||
*/
|
||||
bool isWindowsPlatform() const {
|
||||
return platformType == Win32A ||
|
||||
platformType == Win32W ||
|
||||
platformType == Win64;
|
||||
}
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
|
|
@ -49,6 +49,7 @@ private:
|
|||
TEST_CASE(testPosixPrintfScanfParameterPosition); // #4900
|
||||
|
||||
TEST_CASE(testMicrosoftPrintfArgument); // ticket #4902
|
||||
TEST_CASE(testMicrosoftCStringFormatArguments); // ticket #4920
|
||||
|
||||
TEST_CASE(testlibrarycfg); // library configuration
|
||||
}
|
||||
|
@ -2132,6 +2133,33 @@ private:
|
|||
"[test.cpp:17]: (warning) 'I64' in format string (no. 1) is a length modifier and cannot be used without a conversion specifier.\n", errout.str());
|
||||
}
|
||||
|
||||
void testMicrosoftCStringFormatArguments() { // ticket #4920
|
||||
check("void foo() {\n"
|
||||
" unsigned __int32 u32;\n"
|
||||
" String string;\n"
|
||||
" string.Format(\"%I32d\", u32);\n"
|
||||
" string.AppendFormat(\"%I32d\", u32);\n"
|
||||
"}", false, false, Settings::Win32A);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void foo() {\n"
|
||||
" unsigned __int32 u32;\n"
|
||||
" CString string;\n"
|
||||
" string.Format(\"%I32d\", u32);\n"
|
||||
" string.AppendFormat(\"%I32d\", u32);\n"
|
||||
"}", false, false, Settings::Unix32);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void foo() {\n"
|
||||
" unsigned __int32 u32;\n"
|
||||
" CString string;\n"
|
||||
" string.Format(\"%I32d\", u32);\n"
|
||||
" string.AppendFormat(\"%I32d\", u32);\n"
|
||||
"}", false, false, Settings::Win32A);
|
||||
ASSERT_EQUALS("[test.cpp:4]: (warning) %I32d in format string (no. 1) requires a signed integer but the argument type is 'unsigned __int32 {aka unsigned int}'.\n"
|
||||
"[test.cpp:5]: (warning) %I32d in format string (no. 1) requires a signed integer but the argument type is 'unsigned __int32 {aka unsigned int}'.\n", errout.str());
|
||||
}
|
||||
|
||||
void testlibrarycfg() {
|
||||
const char code[] = "void f() {\n"
|
||||
" format(\"%s\");\n"
|
||||
|
|
Loading…
Reference in New Issue