Author: tfaber
Date: Sat Mar 30 11:17:54 2013
New Revision: 58614
URL:
http://svn.reactos.org/svn/reactos?rev=58614&view=rev
Log:
[USER32]
- Apply Wine commit 84075591 (user32: Don't access past the file size when loading a
cursor/icon) by Alexandre Julliard.
- Add a few consts (also from Wine).
CORE-7027 #comment Ldr and Mm are doing everything right. UPX in fact broke the resource
section, and LoadImage is just not handling that correctly. #resolve
Modified:
trunk/reactos/win32ss/user/user32/windows/cursoricon.c
Modified: trunk/reactos/win32ss/user/user32/windows/cursoricon.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/user32/window…
==============================================================================
--- trunk/reactos/win32ss/user/user32/windows/cursoricon.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/user32/windows/cursoricon.c [iso-8859-1] Sat Mar 30
11:17:54 2013
@@ -260,7 +260,7 @@
* The following macro functions account for the irregularities of
* accessing cursor and icon resources in files and resource entries.
*/
-typedef BOOL (*fnGetCIEntry)( LPVOID dir, int n,
+typedef BOOL (*fnGetCIEntry)( LPCVOID dir, DWORD size, int n,
int *width, int *height, int *bits );
/**********************************************************************
@@ -268,7 +268,7 @@
*
* Find the icon closest to the requested size and bit depth.
*/
-static int CURSORICON_FindBestIcon( LPVOID dir, fnGetCIEntry get_entry,
+static int CURSORICON_FindBestIcon( LPCVOID dir, DWORD size, fnGetCIEntry get_entry,
int width, int height, int depth )
{
int i, cx, cy, bits, bestEntry = -1;
@@ -278,7 +278,7 @@
/* Find Best Fit */
iTotalDiff = 0xFFFFFFFF;
iColorDiff = 0xFFFFFFFF;
- for ( i = 0; get_entry( dir, i, &cx, &cy, &bits ); i++ )
+ for ( i = 0; get_entry( dir, size, i, &cx, &cy, &bits ); i++ )
{
iTempXDiff = abs(width - cx);
iTempYDiff = abs(height - cy);
@@ -292,7 +292,7 @@
}
/* Find Best Colors for Best Fit */
- for ( i = 0; get_entry( dir, i, &cx, &cy, &bits ); i++ )
+ for ( i = 0; get_entry( dir, size, i, &cx, &cy, &bits ); i++ )
{
if(abs(width - cx) == iXDiff && abs(height - cy) == iYDiff)
{
@@ -308,13 +308,15 @@
return bestEntry;
}
-static BOOL CURSORICON_GetResIconEntry( LPVOID dir, int n,
+static BOOL CURSORICON_GetResIconEntry( LPCVOID dir, DWORD size, int n,
int *width, int *height, int *bits )
{
- CURSORICONDIR *resdir = dir;
- ICONRESDIR *icon;
+ const CURSORICONDIR *resdir = dir;
+ const ICONRESDIR *icon;
if ( resdir->idCount <= n )
+ return FALSE;
+ if ((const char *)&resdir->idEntries[n + 1] - (const char *)dir > size)
return FALSE;
icon = &resdir->idEntries[n].ResInfo.icon;
*width = icon->bWidth;
@@ -330,7 +332,7 @@
*
* FIXME: parameter 'color' ignored.
*/
-static int CURSORICON_FindBestCursor( LPVOID dir, fnGetCIEntry get_entry,
+static int CURSORICON_FindBestCursor( LPCVOID dir, DWORD size, fnGetCIEntry get_entry,
int width, int height, int depth )
{
int i, maxwidth, maxheight, cx, cy, bits, bestEntry = -1;
@@ -342,7 +344,7 @@
/* First find the largest one smaller than or equal to the requested size*/
maxwidth = maxheight = 0;
- for ( i = 0; get_entry( dir, i, &cx, &cy, &bits ); i++ )
+ for ( i = 0; get_entry( dir, size, i, &cx, &cy, &bits ); i++ )
{
if ((cx <= width) && (cy <= height) &&
(cx > maxwidth) && (cy > maxheight))
@@ -357,7 +359,7 @@
/* Now find the smallest one larger than the requested size */
maxwidth = maxheight = 255;
- for ( i = 0; get_entry( dir, i, &cx, &cy, &bits ); i++ )
+ for ( i = 0; get_entry( dir, size, i, &cx, &cy, &bits ); i++ )
{
if (((cx < maxwidth) && (cy < maxheight)) || (bestEntry == -1))
{
@@ -370,13 +372,15 @@
return bestEntry;
}
-static BOOL CURSORICON_GetResCursorEntry( LPVOID dir, int n,
+static BOOL CURSORICON_GetResCursorEntry( LPCVOID dir, DWORD size, int n,
int *width, int *height, int *bits )
{
- CURSORICONDIR *resdir = dir;
- CURSORDIR *cursor;
+ const CURSORICONDIR *resdir = dir;
+ const CURSORDIR *cursor;
if ( resdir->idCount <= n )
+ return FALSE;
+ if ((const char *)&resdir->idEntries[n + 1] - (const char *)dir > size)
return FALSE;
cursor = &resdir->idEntries[n].ResInfo.cursor;
*width = cursor->wWidth;
@@ -385,60 +389,62 @@
return TRUE;
}
-static CURSORICONDIRENTRY *CURSORICON_FindBestIconRes( CURSORICONDIR * dir,
- int width, int height, int depth )
+static CURSORICONDIRENTRY *CURSORICON_FindBestIconRes( CURSORICONDIR * dir, DWORD size,
+ int width, int height, int depth
)
{
int n;
- n = CURSORICON_FindBestIcon( dir, CURSORICON_GetResIconEntry,
+ n = CURSORICON_FindBestIcon( dir, size, CURSORICON_GetResIconEntry,
width, height, depth );
if ( n < 0 )
return NULL;
return &dir->idEntries[n];
}
-static CURSORICONDIRENTRY *CURSORICON_FindBestCursorRes( CURSORICONDIR *dir,
- int width, int height, int depth )
-{
- int n = CURSORICON_FindBestCursor( dir, CURSORICON_GetResCursorEntry,
+static CURSORICONDIRENTRY *CURSORICON_FindBestCursorRes( CURSORICONDIR *dir, DWORD size,
+ int width, int height, int depth
)
+{
+ int n = CURSORICON_FindBestCursor( dir, size, CURSORICON_GetResCursorEntry,
width, height, depth );
if ( n < 0 )
return NULL;
return &dir->idEntries[n];
}
-static BOOL CURSORICON_GetFileEntry( LPVOID dir, int n,
+static BOOL CURSORICON_GetFileEntry( LPCVOID dir, DWORD size, int n,
int *width, int *height, int *bits )
{
- CURSORICONFILEDIR *filedir = dir;
- CURSORICONFILEDIRENTRY *entry;
- BITMAPINFOHEADER *info;
+ const CURSORICONFILEDIR *filedir = dir;
+ const CURSORICONFILEDIRENTRY *entry;
+ const BITMAPINFOHEADER *info;
if ( filedir->idCount <= n )
return FALSE;
+ if ((const char *)&filedir->idEntries[n + 1] - (const char *)dir > size)
+ return FALSE;
entry = &filedir->idEntries[n];
- /* FIXME: check against file size */
- info = (BITMAPINFOHEADER *)((char *)dir + entry->dwDIBOffset);
+ info = (const BITMAPINFOHEADER *)((const char *)dir + entry->dwDIBOffset);
+ if ((const char *)(info + 1) - (const char *)dir > size) return FALSE;
*width = entry->bWidth;
*height = entry->bHeight;
*bits = info->biBitCount;
return TRUE;
}
-static CURSORICONFILEDIRENTRY *CURSORICON_FindBestCursorFile( CURSORICONFILEDIR *dir,
- int width, int height, int depth )
-{
- int n = CURSORICON_FindBestCursor( dir, CURSORICON_GetFileEntry,
+static CURSORICONFILEDIRENTRY *CURSORICON_FindBestCursorFile( CURSORICONFILEDIR *dir,
DWORD size,
+ int width, int height, int
depth )
+{
+ int n = CURSORICON_FindBestCursor( dir, size, CURSORICON_GetFileEntry,
width, height, depth );
if ( n < 0 )
return NULL;
return &dir->idEntries[n];
}
-static CURSORICONFILEDIRENTRY *CURSORICON_FindBestIconFile( CURSORICONFILEDIR *dir,
- int width, int height, int depth )
-{
- int n = CURSORICON_FindBestIcon( dir, CURSORICON_GetFileEntry,
+static CURSORICONFILEDIRENTRY *CURSORICON_FindBestIconFile( CURSORICONFILEDIR *dir, DWORD
size,
+ int width, int height, int
depth )
+{
+ int n = CURSORICON_FindBestIcon( dir, size, CURSORICON_GetFileEntry,
width, height, depth );
if ( n < 0 )
return NULL;
@@ -747,7 +753,8 @@
icon_data = fram_chunk.data + (2 * sizeof(DWORD));
entry = CURSORICON_FindBestIconFile( (CURSORICONFILEDIR *) icon_data,
- width, height, depth );
+ bits + bits_size - icon_data,
+ width, height, depth );
frame_bits = HeapAlloc( GetProcessHeap(), 0, entry->dwDIBSize );
memcpy( frame_bits, icon_data + entry->dwDIBOffset, entry->dwDIBSize );
@@ -850,9 +857,9 @@
goto end;
if ( fCursor )
- entry = CURSORICON_FindBestCursorFile( dir, width, height, depth );
+ entry = CURSORICON_FindBestCursorFile( dir, filesize, width, height, depth );
else
- entry = CURSORICON_FindBestIconFile( dir, width, height, depth );
+ entry = CURSORICON_FindBestIconFile( dir, filesize, width, height, depth );
if ( !entry )
goto end;
@@ -887,6 +894,7 @@
HICON hIcon = 0;
HRSRC hRsrc;
//HRSRC hGroupRsrc;
+ DWORD size;
CURSORICONDIR *dir;
CURSORICONDIRENTRY *dirEntry;
LPBYTE bits;
@@ -915,10 +923,11 @@
if (!(handle = LoadResource( hInstance, hRsrc ))) return 0;
if (!(dir = LockResource( handle ))) return 0;
+ size = SizeofResource( hInstance, hRsrc );
if (fCursor)
- dirEntry = CURSORICON_FindBestCursorRes( dir, width, height, depth );
+ dirEntry = CURSORICON_FindBestCursorRes( dir, size, width, height, depth );
else
- dirEntry = CURSORICON_FindBestIconRes( dir, width, height, depth );
+ dirEntry = CURSORICON_FindBestIconRes( dir, size, width, height, depth );
if (!dirEntry) return 0;
wResId = dirEntry->wResId;
dwBytesInRes = dirEntry->dwBytesInRes;
@@ -1285,9 +1294,9 @@
ReleaseDC(0, hdc);
if( bIcon )
- entry = CURSORICON_FindBestIconRes( dir, width, height, depth );
+ entry = CURSORICON_FindBestIconRes( dir, ~0u, width, height, depth );
else
- entry = CURSORICON_FindBestCursorRes( dir, width, height, depth );
+ entry = CURSORICON_FindBestCursorRes( dir, ~0u, width, height, depth );
if( entry ) retVal = entry->wResId;
}