// Test library configuration for windows.cfg // // Usage: // $ cppcheck --check-library --library=windows --enable=information --error-exitcode=1 --inline-suppr --suppress=missingIncludeSystem test/cfg/windows.cpp // => // No warnings about bad library configuration, unmatched suppressions, etc. exitcode=0 // #include void validCode() { DWORD dwordInit = 0; WORD wordInit = 0; BYTE byteInit = 0; // Valid Semaphore usage, no leaks, valid arguments HANDLE hSemaphore1; hSemaphore1 = CreateSemaphore(NULL, 0, 1, NULL); CloseHandle(hSemaphore1); HANDLE hSemaphore2; hSemaphore2 = CreateSemaphoreEx(NULL, 0, 1, NULL, 0, SEMAPHORE_ALL_ACCESS); CloseHandle(hSemaphore2); HANDLE hSemaphore3; hSemaphore3 = OpenSemaphore(SEMAPHORE_ALL_ACCESS, TRUE, "sem"); CloseHandle(hSemaphore3); // Valid lstrcat usage, but with warning because it is deprecated char buf[30] = "hello world"; // cppcheck-suppress lstrcatCalled lstrcat(buf, "test"); // cppcheck-suppress strlwrCalled strlwr(buf); // cppcheck-suppress struprCalled strupr(buf); // Valid Mutex usage, no leaks, valid arguments HANDLE hMutex1; hMutex1 = CreateMutex(NULL, TRUE, NULL); if (hMutex1) { ReleaseMutex(hMutex); } CloseHandle(hMutex1); HANDLE hMutex2; hMutex2 = CreateMutexEx(NULL, NULL, 0, MUTEX_ALL_ACCESS); CloseHandle(hMutex2); HANDLE hMutex3; hMutex3 = OpenMutex(MUTEX_ALL_ACCESS, FALSE, "sem"); CloseHandle(hMutex3); // Valid Module usage, no leaks, valid arguments HMODULE hModule = GetModuleHandle(L"My.dll"); FreeLibrary(hModule); hModule = GetModuleHandle(TEXT("somedll")); FreeLibrary(hModule); hModule = GetModuleHandle(NULL); FreeLibrary(hModule); // Valid Event usage, no leaks, valid arguments HANDLE event; event = CreateEvent(NULL, FALSE, FALSE, NULL); if (NULL != event) { SetEvent(event); CloseHandle(event); } event = OpenEvent(EVENT_ALL_ACCESS, FALSE, L"testevent"); if (NULL != event) { PulseEvent(event); SetEvent(event); CloseHandle(event); } event = CreateEventEx(NULL, L"testevent3", CREATE_EVENT_INITIAL_SET, EVENT_MODIFY_STATE); if (NULL != event) { ResetEvent(event); CloseHandle(event); } void *pMem1 = _malloca(1); _freea(pMem1); // Memory from _alloca must not be freed void *pMem2 = _alloca(10); memset(pMem2, 0, 10); SYSTEMTIME st; GetSystemTime(&st); DWORD lastError = GetLastError(); SetLastError(lastError); PSID pEveryoneSID = NULL; SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY; AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pEveryoneSID) FreeSid(pEveryoneSID); LPVOID pMem = HeapAlloc(GetProcessHeap(), 0, 10); 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); GetUserName(NULL, &dwordInit); dwordInit = 10; GetUserName(bufTC, _countof(bufTC)); WSADATA wsaData = {0}; WSAStartup(2, &wsaData); SOCKET sock = socket(1, 2, 3); u_long ulongInit = 0; ioctlsocket(sock, FIONBIO, &ulongInit); if (sock != INVALID_SOCKET) { closesocket(sock); } WSACleanup(); wordInit = MAKEWORD(1, 2); dwordInit = MAKELONG(1, 2); // cppcheck-suppress redundantAssignment wordInit = LOWORD(dwordInit); byteInit = LOBYTE(wordInit); wordInit = HIWORD(dwordInit); // cppcheck-suppress redundantAssignment byteInit = HIBYTE(wordInit); if (byteInit) {} bool boolVar; uint8_t byteBuf[5] = {0}; uint8_t byteBuf2[10] = {0}; boolVar = RtlEqualMemory(byteBuf, byteBuf2, sizeof(byteBuf)); if (boolVar) {} boolVar = RtlCompareMemory(byteBuf, byteBuf2, sizeof(byteBuf)); if (boolVar) {} RtlMoveMemory(byteBuf, byteBuf2, sizeof(byteBuf)); RtlCopyMemory(byteBuf, byteBuf2, sizeof(byteBuf)); RtlZeroMemory(byteBuf, sizeof(byteBuf)); ZeroMemory(byteBuf, sizeof(byteBuf)); RtlSecureZeroMemory(byteBuf, sizeof(byteBuf)); SecureZeroMemory(byteBuf, sizeof(byteBuf)); RtlFillMemory(byteBuf, sizeof(byteBuf), 0xff); // Intrinsics __noop(); __noop(1, "test", NULL); __nop(); // Valid Library usage, no leaks, valid arguments HINSTANCE hInstLib = LoadLibrary(L"My.dll"); FreeLibrary(hInstLib); hInstLib = LoadLibraryA("My.dll"); FreeLibrary(hInstLib); hInstLib = LoadLibraryEx(L"My.dll", NULL, 0); FreeLibrary(hInstLib); hInstLib = LoadLibraryExW(L"My.dll", NULL, 0); FreeLibrary(hInstLib); hInstLib = ::LoadLibrary(L"My.dll"); FreeLibraryAndExitThread(hInstLib, 0); // Does not return! Must be at the end! } void bufferAccessOutOfBounds() { wchar_t buf[10]; // Verifying _countof macro configuration // Valid loop over array for (size_t i = 0; i < _countof(buf); ++i) { buf[i] = L'\0'; } // Wrong loop over array accessing one element past the end for (size_t i = 0; i <= _countof(buf); ++i) { // cppcheck-suppress arrayIndexOutOfBounds buf[i] = L'\0'; } uint8_t byteBuf[5] = {0}; uint8_t byteBuf2[10] = {0}; // TODO ticket #8412 cppcheck-suppress ignoredReturnValue // cppcheck-suppress bufferAccessOutOfBounds RtlEqualMemory(byteBuf, byteBuf2, 20); // cppcheck-suppress ignoredReturnValue // cppcheck-suppress bufferAccessOutOfBounds RtlCompareMemory(byteBuf, byteBuf2, 20); // cppcheck-suppress bufferAccessOutOfBounds RtlMoveMemory(byteBuf, byteBuf2, 20); // cppcheck-suppress redundantCopy // cppcheck-suppress bufferAccessOutOfBounds MoveMemory(byteBuf, byteBuf2, 20); // cppcheck-suppress redundantCopy // cppcheck-suppress bufferAccessOutOfBounds RtlCopyMemory(byteBuf, byteBuf2, 20); // cppcheck-suppress redundantCopy // cppcheck-suppress bufferAccessOutOfBounds CopyMemory(byteBuf, byteBuf2, 20); // cppcheck-suppress bufferAccessOutOfBounds RtlZeroMemory(byteBuf, sizeof(byteBuf)+1); // cppcheck-suppress bufferAccessOutOfBounds ZeroMemory(byteBuf, sizeof(byteBuf)+1); // cppcheck-suppress bufferAccessOutOfBounds RtlSecureZeroMemory(byteBuf, sizeof(byteBuf)+1); // cppcheck-suppress bufferAccessOutOfBounds SecureZeroMemory(byteBuf, sizeof(byteBuf)+1); // cppcheck-suppress bufferAccessOutOfBounds RtlFillMemory(byteBuf, sizeof(byteBuf)+1, 0x01); // cppcheck-suppress bufferAccessOutOfBounds FillMemory(byteBuf, sizeof(byteBuf)+1, 0x01); } void nullPointer() { HANDLE hSemaphore; // cppcheck-suppress nullPointer hSemaphore = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, NULL); CloseHandle(hSemaphore); // cppcheck-suppress lstrcatCalled // cppcheck-suppress nullPointer lstrcat(NULL, "test"); char buf[10] = "\0"; // cppcheck-suppress lstrcatCalled // cppcheck-suppress nullPointer lstrcat(buf, NULL); HANDLE hMutex; // cppcheck-suppress nullPointer hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, NULL); CloseHandle(hMutex); //Incorrect: 1. parameter, must not be null // cppcheck-suppress nullPointer FARPROC pAddr = GetProcAddress(NULL, "name"); HMODULE * phModule = NULL; // cppcheck-suppress nullPointer GetModuleHandleEx(0, NULL, phModule); // cppcheck-suppress leakReturnValNotUsed // cppcheck-suppress nullPointer OpenEvent(EVENT_ALL_ACCESS, FALSE, NULL); HANDLE hEvent = NULL; // cppcheck-suppress nullPointer PulseEvent(hEvent); // cppcheck-suppress nullPointer ResetEvent(hEvent); // cppcheck-suppress nullPointer SetEvent(hEvent); char *str = NULL; // cppcheck-suppress strlwrCalled // cppcheck-suppress nullPointer strlwr(str); // cppcheck-suppress struprCalled // cppcheck-suppress nullPointer strupr(str); // cppcheck-suppress nullPointer GetSystemTime(NULL); // cppcheck-suppress nullPointer GetLocalTime(NULL); // TODO: error message: arg1 must not be nullptr if variable pointed to by arg2 is not 0 DWORD dwordInit = 10; GetUserName(NULL, &dwordInit); TCHAR bufTC[10]; // cppcheck-suppress nullPointer GetUserName(bufTC, NULL); SOCKET socketInit = {0}; sockaddr sockaddrUninit; int intInit = 0; int *pIntNull = NULL; char charArray[] = "test"; // cppcheck-suppress nullPointer WSAStartup(1, NULL); // cppcheck-suppress nullPointer bind(socketInit, NULL, 5); // cppcheck-suppress nullPointer getpeername(socketInit, NULL, &intInit); // cppcheck-suppress nullPointer getpeername(socketInit, &sockaddrUninit, pIntNull); // cppcheck-suppress nullPointer getsockopt(sockInit, 1, 2, NULL, &intInit); // cppcheck-suppress nullPointer getsockopt(sockInit, 1, 2, charArray, pIntNull); } void memleak_malloca() { // cppcheck-suppress unreadVariable void *pMem = _malloca(10); // cppcheck-suppress memleak } void memleak_AllocateAndInitializeSid() { PSID pEveryoneSID = NULL; SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY; AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pEveryoneSID) // TODO: enable when #6994 is implemented cppcheck-suppress memleak } void memleak_HeapAlloc() { LPVOID pMem; pMem = HeapAlloc(GetProcessHeap(), 0, 10); HeapValidate(GetProcessHeap(), 0, pMem); // cppcheck-suppress unreadVariable SIZE_T memSize = HeapSize(GetProcessHeap(), 0, pMem); // cppcheck-suppress memleak } void resourceLeak_CreateSemaphoreA() { HANDLE hSemaphore; // cppcheck-suppress unreadVariable hSemaphore = CreateSemaphoreA(NULL, 0, 1, "sem1"); // cppcheck-suppress resourceLeak } void resourceLeak_CreateSemaphoreEx() { HANDLE hSemaphore; // cppcheck-suppress unreadVariable hSemaphore = CreateSemaphoreEx(NULL, 0, 1, NULL, 0, SEMAPHORE_ALL_ACCESS); // cppcheck-suppress resourceLeak } void resourceLeak_OpenSemaphore() { HANDLE hSemaphore; // cppcheck-suppress unreadVariable hSemaphore = OpenSemaphore(SEMAPHORE_ALL_ACCESS, TRUE, "sem"); // cppcheck-suppress resourceLeak } void resourceLeak_CreateMutexA() { HANDLE hMutex; // cppcheck-suppress unreadVariable hMutex = CreateMutexA(NULL, TRUE, "sem1"); // cppcheck-suppress resourceLeak } void resourceLeak_CreateMutexEx() { HANDLE hMutex; // cppcheck-suppress unreadVariable hMutex = CreateMutexEx(NULL, "sem", 0, MUTEX_ALL_ACCESS); // cppcheck-suppress resourceLeak } void resourceLeak_OpenMutex() { HANDLE hMutex; // cppcheck-suppress unreadVariable hMutex = OpenMutex(MUTEX_ALL_ACCESS, TRUE, "sem"); // cppcheck-suppress resourceLeak } void resourceLeak_LoadLibrary() { HINSTANCE hInstLib; hInstLib = ::LoadLibrary(L"My.dll"); typedef BOOL (WINAPI *fpFunc)(); // cppcheck-suppress unreadVariable fpFunc pFunc = GetProcAddress(hInstLib, "name"); // cppcheck-suppress resourceLeak } void resourceLeak_CreateEvent() { HANDLE hEvent; hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); SetEvent(hEvent); // cppcheck-suppress resourceLeak } void resourceLeak_CreateEventExA() { HANDLE hEvent; // cppcheck-suppress unreadVariable hEvent = CreateEventExA(NULL, "test", CREATE_EVENT_INITIAL_SET, EVENT_MODIFY_STATE); // cppcheck-suppress resourceLeak } void resourceLeak_OpenEventW() { HANDLE hEvent; // cppcheck-suppress unreadVariable hEvent = OpenEventW(EVENT_ALL_ACCESS, TRUE, L"testevent"); // cppcheck-suppress resourceLeak } void resourceLeak_socket() { SOCKET sock; // cppcheck-suppress unreadVariable sock = socket(1, 2, 3); // cppcheck-suppress resourceLeak } void ignoredReturnValue() { // cppcheck-suppress leakReturnValNotUsed CreateSemaphoreW(NULL, 0, 1, NULL); // cppcheck-suppress leakReturnValNotUsed CreateSemaphoreExA(NULL, 0, 1, NULL, 0, SEMAPHORE_ALL_ACCESS); // cppcheck-suppress leakReturnValNotUsed OpenSemaphoreA(SEMAPHORE_ALL_ACCESS, TRUE, "sem"); // cppcheck-suppress leakReturnValNotUsed CreateMutexW(NULL, FALSE, NULL); // cppcheck-suppress leakReturnValNotUsed CreateMutexExA(NULL, NULL, 1, MUTEX_ALL_ACCESS); // cppcheck-suppress leakReturnValNotUsed OpenMutexA(MUTEX_ALL_ACCESS, TRUE, "sem"); // cppcheck-suppress leakReturnValNotUsed LoadLibrary(L"My.dll"); // cppcheck-suppress leakReturnValNotUsed LoadLibraryEx(L"My.dll", NULL, 0); HINSTANCE hInstLib = LoadLibrary(L"My.dll"); // cppcheck-suppress ignoredReturnValue GetProcAddress(hInstLib, "name"); FreeLibrary(hInstLib); // cppcheck-suppress leakReturnValNotUsed CreateEvent(NULL, FALSE, FALSE, NULL); // cppcheck-suppress leakReturnValNotUsed OpenEvent(EVENT_ALL_ACCESS, FALSE, L"testevent"); // cppcheck-suppress leakReturnValNotUsed CreateEventEx(NULL, L"test", CREATE_EVENT_INITIAL_SET, EVENT_MODIFY_STATE); // cppcheck-suppress leakReturnValNotUsed _malloca(10); // cppcheck-suppress ignoredReturnValue _alloca(5); // cppcheck-suppress ignoredReturnValue GetLastError(); // cppcheck-suppress ignoredReturnValue GetProcessHeap() // cppcheck-suppress leakReturnValNotUsed HeapAlloc(GetProcessHeap(), 0, 10); // cppcheck-suppress leakReturnValNotUsed HeapReAlloc(GetProcessHeap(), 0, 1, 0); // cppcheck-suppress leakReturnValNotUsed socket(1, 2, 3); // cppcheck-suppress ignoredReturnValue _fileno(stdio); } void invalidFunctionArg() { HANDLE hSemaphore; // cppcheck-suppress invalidFunctionArg hSemaphore = CreateSemaphore(NULL, 0, 0, NULL); CloseHandle(hSemaphore); // cppcheck-suppress invalidFunctionArgBool hSemaphore = CreateSemaphore(NULL, 0, 1, true); CloseHandle(hSemaphore); // cppcheck-suppress invalidFunctionArg hSemaphore = CreateSemaphoreEx(NULL, 0, 0, NULL, 0, SEMAPHORE_ALL_ACCESS); CloseHandle(hSemaphore); // cppcheck-suppress invalidFunctionArg hSemaphore = CreateSemaphoreEx(NULL, 0, 1, NULL, 1, SEMAPHORE_ALL_ACCESS); CloseHandle(hSemaphore); HANDLE hMutex; // cppcheck-suppress invalidFunctionArgBool hMutex = CreateMutex(NULL, TRUE, false); CloseHandle(hMutex); // cppcheck-suppress invalidFunctionArgBool hMutex = CreateMutex(NULL, FALSE, true); CloseHandle(hMutex); // cppcheck-suppress invalidFunctionArg hMutex = CreateMutexEx(NULL, NULL, 3, MUTEX_ALL_ACCESS); CloseHandle(hMutex); //Incorrect: 2. parameter to LoadLibraryEx() must be NULL // cppcheck-suppress invalidFunctionArg HINSTANCE hInstLib = LoadLibraryEx(L"My.dll", 1, 0); FreeLibrary(hInstLib); // cppcheck-suppress invalidFunctionArg void *pMem = _malloca(-1); _freea(pMem); // cppcheck-suppress unreadVariable // cppcheck-suppress invalidFunctionArg pMem = _alloca(-5); } void uninitvar() { HANDLE hSemaphore; // cppcheck-suppress uninitvar CloseHandle(hSemaphore); char buf[10]; // cppcheck-suppress lstrcatCalled // cppcheck-suppress uninitvar lstrcat(buf, "test"); buf[0] = '\0'; char buf2[2]; // cppcheck-suppress lstrcatCalled // cppcheck-suppress uninitvar lstrcat(buf, buf2); HANDLE hMutex; // cppcheck-suppress uninitvar ReleaseMutex(hMutex); // cppcheck-suppress uninitvar CloseHandle(hMutex); HANDLE hEvent; // cppcheck-suppress uninitvar PulseEvent(hEvent); // cppcheck-suppress uninitvar ResetEvent(hEvent); // cppcheck-suppress uninitvar SetEvent(hEvent); // cppcheck-suppress uninitvar CloseHandle(hEvent); char buf_uninit[10]; // cppcheck-suppress strlwrCalled // cppcheck-suppress uninitvar strlwr(buf_uninit); // cppcheck-suppress struprCalled // cppcheck-suppress uninitvar strupr(buf_uninit); DWORD dwordUninit; // cppcheck-suppress uninitvar SetLastError(dwordUninit); DWORD dwordUninit; // cppcheck-suppress uninitvar GetUserName(NULL, &dwordUninit); FILE *pFileUninit; // cppcheck-suppress uninitvar // cppcheck-suppress ignoredReturnValue _fileno(pFileUninit); } 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 // must be called or is not allowed to be called. // If the first argument is GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT // (0x00000002), a call to FreeLibrary is not allowed, otherwise it is // necessary. // Since this is not possible to configure at the moment cppcheck should // accept not calling FreeLibrary and also calling it for the handle. // TODO: Enhance cppcheck to conditionally check for alloc/dealloc issues. // No warning because of correct FreeLibrary on 'hModule' should be issued. HMODULE hModule1; if (GetModuleHandleEx(0, NULL, &hModule1)) { FreeLibrary(hModule1); } //This is a false negative, but it is not detected to avoid false positives. HMODULE hModule2; GetModuleHandleEx(0, NULL, &hModule2); }