From 18a1a6e1941801578fdf578ff85400b67eb5cc88 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Tue, 4 Jan 2005 20:35:46 +0000 Subject: [PATCH] Prevent crash from invalid last parameter in GetFileVersionInfo. Prevent crash in VerQueryValue when return size not requested. GetFileVersionInfo and VerQueryValue parameter tests added. --- dlls/version/info.c | 16 +++++++-- dlls/version/tests/info.c | 75 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 88 insertions(+), 3 deletions(-) diff --git a/dlls/version/info.c b/dlls/version/info.c index c45ab8470c7..12d3b3c82d0 100644 --- a/dlls/version/info.c +++ b/dlls/version/info.c @@ -582,6 +582,11 @@ BOOL WINAPI GetFileVersionInfoA( LPCSTR filename, DWORD handle, TRACE("(%s,%ld,size=%ld,data=%p)\n", debugstr_a(filename), handle, datasize, data ); + if (!data) + { + SetLastError(ERROR_INVALID_DATA); + return FALSE; + } if(filename) RtlCreateUnicodeStringFromAsciiz(&filenameW, filename); else filenameW.Buffer = NULL; len = VERSION_GetFileVersionInfo_PE(filenameW.Buffer, datasize, data); @@ -628,6 +633,11 @@ BOOL WINAPI GetFileVersionInfoW( LPCWSTR filename, DWORD handle, TRACE("(%s,%ld,size=%ld,data=%p)\n", debugstr_w(filename), handle, datasize, data ); + if (!data) + { + SetLastError(ERROR_INVALID_DATA); + return FALSE; + } len = VERSION_GetFileVersionInfo_PE(filename, datasize, data); /* 0xFFFFFFFF means: file is a PE module, but VERSION_INFO not found */ if (len == 0xFFFFFFFF) @@ -740,7 +750,8 @@ DWORD WINAPI VersionInfo16_QueryValue( VS_VERSION_INFO_STRUCT16 *info, LPCSTR lp /* Return value */ *lplpBuffer = VersionInfo16_Value( info ); - *puLen = info->wValueLength; + if (puLen) + *puLen = info->wValueLength; return TRUE; } @@ -825,7 +836,8 @@ DWORD WINAPI VerQueryValueW( LPVOID pBlock, LPCWSTR lpSubBlock, /* Return value */ *lplpBuffer = VersionInfo32_Value( info ); - *puLen = info->wValueLength; + if (puLen) + *puLen = info->wValueLength; return TRUE; } diff --git a/dlls/version/tests/info.c b/dlls/version/tests/info.c index a24fa23a2a4..3433aac93dc 100644 --- a/dlls/version/tests/info.c +++ b/dlls/version/tests/info.c @@ -17,6 +17,7 @@ */ #include +#include #include "wine/test.h" #include "windef.h" @@ -105,14 +106,86 @@ static void test_info_size(void) ok( !retval, "GetFileVersionInfoSizeA result wrong! 0L expected, got 0x%08lx\n", retval); - ok( (ERROR_FILE_NOT_FOUND == GetLastError()) || + ok( (ERROR_FILE_NOT_FOUND == GetLastError()) || (ERROR_RESOURCE_DATA_NOT_FOUND == GetLastError()) || (MY_LAST_ERROR == GetLastError()), "Last error wrong! ERROR_FILE_NOT_FOUND/ERROR_RESOURCE_DATA_NOT_FOUND " "(XP)/0x%08lx (NT4) expected, got 0x%08lx\n", MY_LAST_ERROR, GetLastError()); } +static void VersionDwordLong2String(DWORDLONG Version, LPSTR lpszVerString) +{ + WORD a, b, c, d; + + a = (WORD)(Version >> 48); + b = (WORD)((Version >> 32) & 0xffff); + c = (WORD)((Version >> 16) & 0xffff); + d = (WORD)(Version & 0xffff); + + sprintf(lpszVerString, "%d.%d.%d.%d", a, b, c, d); + + return; +} + +static void test_info(void) +{ + DWORD hdl, retval; + PVOID pVersionInfo = NULL; + BOOL boolret; + VS_FIXEDFILEINFO *pFixedVersionInfo; + UINT uiLength; + char VersionString[MAX_PATH]; + DWORDLONG dwlVersion; + + hdl = 0x55555555; + SetLastError(MY_LAST_ERROR); + retval = GetFileVersionInfoSizeA( "kernel32.dll", &hdl); + ok( retval, + "GetFileVersionInfoSizeA result wrong! <> 0L expected, got 0x%08lx\n", + retval); + ok((NO_ERROR == GetLastError()) || (MY_LAST_ERROR == GetLastError()), + "Last error wrong! NO_ERROR/0x%08lx (NT4) expected, got 0x%08lx\n", + MY_LAST_ERROR, GetLastError()); + ok( hdl == 0L, + "Handle wrong! 0L expected, got 0x%08lx\n", hdl); + + if ( retval == 0 || hdl != 0) + return; + + pVersionInfo = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, retval ); + ok(pVersionInfo != 0, "HeapAlloc failed\n" ); + if (pVersionInfo == 0) + return; + + boolret = GetFileVersionInfoA( "kernel32.dll", 0, retval, 0); + ok (!boolret, "GetFileVersionInfoA should have failed: GetLastError = 0x%08lx\n", GetLastError()); + ok (GetLastError() == ERROR_INVALID_DATA, + "Last error wrong! ERROR_INVALID_DATA expected, got 0x%08lx\n", + GetLastError()); + + boolret = GetFileVersionInfoA( "kernel32.dll", 0, retval, pVersionInfo ); + ok (boolret, "GetFileVersionInfoA failed: GetLastError = 0x%08lx\n", GetLastError()); + if (!boolret) + return; + + boolret = VerQueryValueA( pVersionInfo, "\\", (LPVOID *)&pFixedVersionInfo, &uiLength ); + ok (boolret, "VerQueryValueA failed: GetLastError = 0x%08lx\n", GetLastError()); + if (!boolret) + return; + + dwlVersion = (((DWORDLONG)pFixedVersionInfo->dwFileVersionMS) << 32) + + pFixedVersionInfo->dwFileVersionLS; + + VersionDwordLong2String(dwlVersion, VersionString); + + trace("kernel32.dll version: %s\n", VersionString); + + boolret = VerQueryValueA( pVersionInfo, "\\", (LPVOID *)&pFixedVersionInfo, 0); + ok (boolret, "VerQueryValue failed: GetLastError = 0x%08lx\n", GetLastError()); +} + START_TEST(info) { test_info_size(); + test_info(); }