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();
|
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||||
bool warning = _settings->isEnabled("warning");
|
bool warning = _settings->isEnabled("warning");
|
||||||
|
bool windows = _settings->isWindowsPlatform();
|
||||||
|
|
||||||
std::size_t functions = symbolDatabase->functionScopes.size();
|
std::size_t functions = symbolDatabase->functionScopes.size();
|
||||||
for (std::size_t j = 0; j < functions; ++j) {
|
for (std::size_t j = 0; j < functions; ++j) {
|
||||||
|
@ -437,7 +438,11 @@ void CheckIO::checkWrongPrintfScanfArguments()
|
||||||
|
|
||||||
if (!formatString.empty()) {
|
if (!formatString.empty()) {
|
||||||
/* formatstring found in library */
|
/* 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);
|
formatString = tok->strAt(2);
|
||||||
if (tok->strAt(3) == ",") {
|
if (tok->strAt(3) == ",") {
|
||||||
argListTok = tok->tokAt(4);
|
argListTok = tok->tokAt(4);
|
||||||
|
|
|
@ -240,6 +240,16 @@ public:
|
||||||
|
|
||||||
/** set the platform type for user specified platforms */
|
/** set the platform type for user specified platforms */
|
||||||
bool platformFile(const std::string &filename);
|
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(testPosixPrintfScanfParameterPosition); // #4900
|
||||||
|
|
||||||
TEST_CASE(testMicrosoftPrintfArgument); // ticket #4902
|
TEST_CASE(testMicrosoftPrintfArgument); // ticket #4902
|
||||||
|
TEST_CASE(testMicrosoftCStringFormatArguments); // ticket #4920
|
||||||
|
|
||||||
TEST_CASE(testlibrarycfg); // library configuration
|
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());
|
"[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() {
|
void testlibrarycfg() {
|
||||||
const char code[] = "void f() {\n"
|
const char code[] = "void f() {\n"
|
||||||
" format(\"%s\");\n"
|
" format(\"%s\");\n"
|
||||||
|
|
Loading…
Reference in New Issue