cppcheck/test/cfg/windows.cpp

587 lines
18 KiB
C++

// 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 <windows.h>
void validCode()
{
// 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);
DWORD dwordInit = 0;
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();
// 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';
}
}
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);
}