Commit 18a1a6e1 authored by Robert Reif's avatar Robert Reif Committed by Alexandre Julliard

Prevent crash from invalid last parameter in GetFileVersionInfo.

Prevent crash in VerQueryValue when return size not requested. GetFileVersionInfo and VerQueryValue parameter tests added.
parent fbe94efc
......@@ -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;
}
......@@ -17,6 +17,7 @@
*/
#include <stdarg.h>
#include <stdio.h>
#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();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment