From debe525f3fa8a5e80994dc9fca46d88f6db49e79 Mon Sep 17 00:00:00 2001 From: Andrew Nguyen Date: Wed, 16 Jun 2010 07:35:57 -0500 Subject: [PATCH] setupapi: Validate the cabinet filename parameter in SetupIterateCabinetW. --- dlls/setupapi/setupcab.c | 8 ++- dlls/setupapi/tests/setupcab.c | 112 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+), 2 deletions(-) diff --git a/dlls/setupapi/setupcab.c b/dlls/setupapi/setupcab.c index 185fe1753c8..4a54ae48471 100644 --- a/dlls/setupapi/setupcab.c +++ b/dlls/setupapi/setupcab.c @@ -622,7 +622,7 @@ BOOL WINAPI SetupIterateCabinetW(PCWSTR CabinetFile, DWORD Reserved, UINT len; SC_HSC_W my_hsc; ERF erf; - WCHAR pszCabPathW[MAX_PATH], *p; + WCHAR pszCabPathW[MAX_PATH], *p = NULL; DWORD fpnsize; BOOL ret; @@ -632,7 +632,11 @@ BOOL WINAPI SetupIterateCabinetW(PCWSTR CabinetFile, DWORD Reserved, if (!LoadCABINETDll()) return FALSE; - if (!CabinetFile) return FALSE; + if (!CabinetFile) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } fpnsize = GetFullPathNameW(CabinetFile, MAX_PATH, pszCabPathW, &p); if (fpnsize > MAX_PATH) { diff --git a/dlls/setupapi/tests/setupcab.c b/dlls/setupapi/tests/setupcab.c index 6e211ce599b..3c126c95e34 100644 --- a/dlls/setupapi/tests/setupcab.c +++ b/dlls/setupapi/tests/setupcab.c @@ -40,6 +40,17 @@ static void create_source_fileA(LPSTR filename, const BYTE *data, DWORD size) CloseHandle(handle); } +static void create_source_fileW(LPWSTR filename, const BYTE *data, DWORD size) +{ + HANDLE handle; + DWORD written; + + handle = CreateFileW(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, NULL); + WriteFile(handle, data, size, &written, NULL); + CloseHandle(handle); +} + static UINT CALLBACK dummy_callbackA(PVOID Context, UINT Notification, UINT_PTR Param1, UINT_PTR Param2) { @@ -48,6 +59,14 @@ static UINT CALLBACK dummy_callbackA(PVOID Context, UINT Notification, return 0; } +static UINT CALLBACK dummy_callbackW(PVOID Context, UINT Notification, + UINT_PTR Param1, UINT_PTR Param2) +{ + ok(0, "Received unexpected notification (%p, %u, %lu, %lu)\n", Context, + Notification, Param1, Param2); + return 0; +} + static void test_invalid_parametersA(void) { BOOL ret; @@ -115,7 +134,100 @@ static void test_invalid_parametersA(void) DeleteFileA(source); } +static void test_invalid_parametersW(void) +{ + static const WCHAR nonexistentW[] = {'c',':','\\','n','o','n','e','x','i','s','t','e','n','t','.','c','a','b',0}; + static const WCHAR docW[] = {'d','o','c',0}; + static const WCHAR emptyW[] = {0}; + + BOOL ret; + WCHAR source[MAX_PATH], temp[MAX_PATH]; + int i; + + const struct + { + PCWSTR CabinetFile; + PSP_FILE_CALLBACK MsgHandler; + DWORD expected_lasterror; + int todo_lasterror; + } invalid_parameters[] = + { + {nonexistentW, NULL, ERROR_FILE_NOT_FOUND}, + {nonexistentW, dummy_callbackW, ERROR_FILE_NOT_FOUND}, + {source, NULL, ERROR_INVALID_DATA, 1}, + {source, dummy_callbackW, ERROR_INVALID_DATA, 1}, + }; + + ret = SetupIterateCabinetW(NULL, 0, NULL, NULL); + if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) + { + win_skip("SetupIterateCabinetW is not available\n"); + return; + } + + GetTempPathW(sizeof(temp)/sizeof(WCHAR), temp); + GetTempFileNameW(temp, docW, 0, source); + + create_source_fileW(source, NULL, 0); + + for (i = 0; i < sizeof(invalid_parameters)/sizeof(invalid_parameters[0]); i++) + { + SetLastError(0xdeadbeef); + ret = SetupIterateCabinetW(invalid_parameters[i].CabinetFile, 0, + invalid_parameters[i].MsgHandler, NULL); + ok(!ret, "[%d] Expected SetupIterateCabinetW to return 0, got %d\n", i, ret); + if (invalid_parameters[i].todo_lasterror) + { + todo_wine + ok(GetLastError() == invalid_parameters[i].expected_lasterror, + "[%d] Expected GetLastError() to return %u, got %u\n", + i, invalid_parameters[i].expected_lasterror, GetLastError()); + } + else + { + ok(GetLastError() == invalid_parameters[i].expected_lasterror, + "[%d] Expected GetLastError() to return %u, got %u\n", + i, invalid_parameters[i].expected_lasterror, GetLastError()); + } + } + + SetLastError(0xdeadbeef); + ret = SetupIterateCabinetW(NULL, 0, NULL, NULL); + ok(!ret, "Expected SetupIterateCabinetW to return 0, got %d\n", ret); + ok(GetLastError() == ERROR_INVALID_PARAMETER || + GetLastError() == ERROR_NOT_ENOUGH_MEMORY, /* Vista/Win2k8 */ + "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", + GetLastError()); + + SetLastError(0xdeadbeef); + ret = SetupIterateCabinetW(NULL, 0, dummy_callbackW, NULL); + ok(!ret, "Expected SetupIterateCabinetW to return 0, got %d\n", ret); + ok(GetLastError() == ERROR_INVALID_PARAMETER || + GetLastError() == ERROR_NOT_ENOUGH_MEMORY, /* Vista/Win2k8 */ + "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %u\n", + GetLastError()); + + SetLastError(0xdeadbeef); + ret = SetupIterateCabinetW(emptyW, 0, NULL, NULL); + ok(!ret, "Expected SetupIterateCabinetW to return 0, got %d\n", ret); + ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY || + GetLastError() == ERROR_FILE_NOT_FOUND, /* NT4/Win2k */ + "Expected GetLastError() to return ERROR_NOT_ENOUGH_MEMORY, got %u\n", + GetLastError()); + + SetLastError(0xdeadbeef); + ret = SetupIterateCabinetW(emptyW, 0, dummy_callbackW, NULL); + ok(!ret, "Expected SetupIterateCabinetW to return 0, got %d\n", ret); + ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY || + GetLastError() == ERROR_FILE_NOT_FOUND, /* NT4/Win2k */ + "Expected GetLastError() to return ERROR_NOT_ENOUGH_MEMORY, got %u\n", + GetLastError()); + + DeleteFileW(source); +} + START_TEST(setupcab) { test_invalid_parametersA(); + test_invalid_parametersW(); } -- 2.11.4.GIT