From 2e5d7a8391ddc605d184b6de152972af682a5dc5 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Sat, 3 Feb 2018 05:10:52 +0100 Subject: [PATCH] Fix #8381: false positives for swprintf_ and stprintf_s (#1080) This fixes false positives because of wrong configuration in windows.cfg. Add tests in testio.cpp and test/cfg/windows.cpp to avoid regression. --- cfg/windows.cfg | 22 +++++------- test/cfg/windows.cpp | 85 ++++++++++++++++++++++++++++++++++++++++++++ test/testio.cpp | 20 +++++++++++ 3 files changed, 113 insertions(+), 14 deletions(-) diff --git a/cfg/windows.cfg b/cfg/windows.cfg index 5413e673e..36983b178 100644 --- a/cfg/windows.cfg +++ b/cfg/windows.cfg @@ -1914,23 +1914,17 @@ + + - + + false + - - - - - - 0: - - - - - - - + diff --git a/test/cfg/windows.cpp b/test/cfg/windows.cpp index c507abae7..d9d561950 100644 --- a/test/cfg/windows.cpp +++ b/test/cfg/windows.cpp @@ -94,6 +94,28 @@ void validCode() pMem = HeapReAlloc(GetProcessHeap(), 0, pMem, 0); HeapFree(GetProcessHeap(), 0, pMem); + char bufC[50]; + sprintf_s(bufC, "Hello"); + printf("%s", bufC); + sprintf_s(bufC, "%s", "test"); + printf("%s", bufC); + sprintf_s(bufC, _countof(bufC), "%s", "test"); + printf("%s", bufC); + wchar_t bufWC[50]; + swprintf_s(bufWC, L"Hello"); + wprintf(L"%s\n", bufWC); + swprintf_s(bufWC, L"%s %d", L"swprintf_s", 3); + wprintf(L"%s\n", bufWC); + swprintf_s(bufWC, _countof(bufWC), L"%s %d", L"swprintf_s", 6); + wprintf(L"%s\n", bufWC); + TCHAR bufTC[50]; + _stprintf(bufTC, TEXT("Hello")); + _tprintf(TEXT("%s"), bufTC); + _stprintf(bufTC, TEXT("%d"), 1); + _tprintf(TEXT("%s"), bufTC); + _stprintf(bufTC, _countof(bufTC), TEXT("%d"), 2); + _tprintf(TEXT("%s"), bufTC); + // Valid Library usage, no leaks, valid arguments HINSTANCE hInstLib = LoadLibrary(L"My.dll"); FreeLibrary(hInstLib); @@ -415,6 +437,69 @@ void uninitvar() SetLastError(dwordUninit); } +void errorPrintf() +{ + char bufC[50]; + // cppcheck-suppress wrongPrintfScanfArgNum + sprintf_s(bufC, _countof(bufC), "%s %d", "sprintf_s"); + printf("%s\n", bufC); + // cppcheck-suppress wrongPrintfScanfArgNum + sprintf_s(bufC, "%s %d", "sprintf_s"); + printf("%s\n", bufC); + // cppcheck-suppress wrongPrintfScanfArgNum + sprintf_s(bufC, _countof(bufC), "test", 0); + printf("%s\n", bufC); + // cppcheck-suppress wrongPrintfScanfArgNum + sprintf_s(bufC, "test", "sprintf_s"); + printf("%s\n", bufC); + // cppcheck-suppress invalidPrintfArgType_s + sprintf_s(bufC, _countof(bufC), "%s", 1); + printf("%s\n", bufC); + // cppcheck-suppress invalidPrintfArgType_s + sprintf_s(bufC, "%s", 1); + printf("%s\n", bufC); + + wchar_t bufWC[50]; + // cppcheck-suppress wrongPrintfScanfArgNum + swprintf_s(bufWC, _countof(bufWC), L"%s %d", L"swprintf_s"); + wprintf(L"%s\n", bufWC); + // cppcheck-suppress wrongPrintfScanfArgNum + swprintf_s(bufWC, L"%s %d", L"swprintf_s"); + wprintf(L"%s\n", bufWC); + // cppcheck-suppress wrongPrintfScanfArgNum + swprintf_s(bufWC, _countof(bufWC), L"test", 0); + wprintf(L"%s\n", bufWC); + // cppcheck-suppress wrongPrintfScanfArgNum + swprintf_s(bufWC, L"test", L"swprintf_s"); + wprintf(L"%s\n", bufWC); + // cppcheck-suppress invalidPrintfArgType_s + swprintf_s(bufWC, _countof(bufWC), L"%s", 1); + wprintf(L"%s\n", bufWC); + // cppcheck-suppress invalidPrintfArgType_s + swprintf_s(bufWC, L"%s", 1); + wprintf(L"%s\n", bufWC); + + TCHAR bufTC[50]; + // cppcheck-suppress wrongPrintfScanfArgNum + _stprintf_s(bufTC, _countof(bufTC), TEXT("%s %d"), TEXT("_stprintf_s")); + _tprintf(L"%s\n", bufTC); + // cppcheck-suppress wrongPrintfScanfArgNum + _stprintf_s(bufTC, TEXT("%s %d"), TEXT("_stprintf_s")); + _tprintf(TEXT("%s\n"), bufTC); + // cppcheck-suppress wrongPrintfScanfArgNum + _stprintf_s(bufTC, _countof(bufTC), TEXT("test"), 0); + _tprintf(TEXT("%s\n"), bufTC); + // cppcheck-suppress wrongPrintfScanfArgNum + _stprintf_s(bufTC, TEXT("test"), TEXT("_stprintf_s")); + _tprintf(TEXT("%s\n"), bufTC); + // cppcheck-suppress invalidPrintfArgType_s + _stprintf_s(bufTC, _countof(bufTC), TEXT("%s"), 1); + _tprintf(TEXT("%s\n"), bufTC); + // cppcheck-suppress invalidPrintfArgType_s + _stprintf_s(bufTC, TEXT("%s"), 1); + _tprintf(TEXT("%s\n"), bufTC); +} + void allocDealloc_GetModuleHandleEx() { // For GetModuleHandleEx it depends on the first argument if FreeLibrary diff --git a/test/testio.cpp b/test/testio.cpp index a4f95e77e..e71134b54 100644 --- a/test/testio.cpp +++ b/test/testio.cpp @@ -4322,6 +4322,16 @@ private: "[test.cpp:5]: (warning) %u in format string (no. 2) requires 'unsigned int' but the argument type is 'signed int'.\n" "[test.cpp:5]: (warning) sprintf_s format string requires 2 parameters but 3 are given.\n", errout.str()); + check("void foo() {\n" + " char str[10];\n" + " int i;\n" + " unsigned int u;\n" + " sprintf_s(str, \"%d %u\", u, i, 0);\n" + "}\n", false, false, Settings::Win32A); + ASSERT_EQUALS("[test.cpp:5]: (warning) %d in format string (no. 1) requires 'int' but the argument type is 'unsigned int'.\n" + "[test.cpp:5]: (warning) %u in format string (no. 2) requires 'unsigned int' but the argument type is 'signed int'.\n" + "[test.cpp:5]: (warning) sprintf_s format string requires 2 parameters but 3 are given.\n", errout.str()); + check("void foo() {\n" " wchar_t str[10];\n" " int i;\n" @@ -4332,6 +4342,16 @@ private: "[test.cpp:5]: (warning) %u in format string (no. 2) requires 'unsigned int' but the argument type is 'signed int'.\n" "[test.cpp:5]: (warning) swprintf_s format string requires 2 parameters but 3 are given.\n", errout.str()); + check("void foo() {\n" + " wchar_t str[10];\n" + " int i;\n" + " unsigned int u;\n" + " swprintf_s(str, L\"%d %u\", u, i, 0);\n" + "}\n", false, false, Settings::Win32W); + ASSERT_EQUALS("[test.cpp:5]: (warning) %d in format string (no. 1) requires 'int' but the argument type is 'unsigned int'.\n" + "[test.cpp:5]: (warning) %u in format string (no. 2) requires 'unsigned int' but the argument type is 'signed int'.\n" + "[test.cpp:5]: (warning) swprintf_s format string requires 2 parameters but 3 are given.\n", errout.str()); + check("void foo() {\n" " TCHAR str[10];\n" " int i;\n"