Commit 82973cfb authored by Huw Davies's avatar Huw Davies Committed by Alexandre Julliard

gdi32: Allocate the bitmap bits during CreateBitmapIndirect() to catch out-of-memory errors.

parent 3bf32809
...@@ -145,6 +145,8 @@ HBITMAP WINAPI CreateBitmapIndirect( const BITMAP *bmp ) ...@@ -145,6 +145,8 @@ HBITMAP WINAPI CreateBitmapIndirect( const BITMAP *bmp )
BITMAP bm; BITMAP bm;
BITMAPOBJ *bmpobj; BITMAPOBJ *bmpobj;
HBITMAP hbitmap; HBITMAP hbitmap;
INT dib_stride;
SIZE_T size;
if (!bmp || bmp->bmType) if (!bmp || bmp->bmType)
{ {
...@@ -194,10 +196,13 @@ HBITMAP WINAPI CreateBitmapIndirect( const BITMAP *bmp ) ...@@ -194,10 +196,13 @@ HBITMAP WINAPI CreateBitmapIndirect( const BITMAP *bmp )
/* Windows ignores the provided bm.bmWidthBytes */ /* Windows ignores the provided bm.bmWidthBytes */
bm.bmWidthBytes = get_bitmap_stride( bm.bmWidth, bm.bmBitsPixel ); bm.bmWidthBytes = get_bitmap_stride( bm.bmWidth, bm.bmBitsPixel );
/* XP doesn't allow creating bitmaps larger than 128 MB */
if (bm.bmHeight > 128 * 1024 * 1024 / bm.bmWidthBytes) dib_stride = get_dib_stride( bm.bmWidth, bm.bmBitsPixel );
size = dib_stride * bm.bmHeight;
/* Check for overflow (dib_stride itself must be ok because of the constraint on bm.bmWidth above). */
if (dib_stride != size / bm.bmHeight)
{ {
SetLastError( ERROR_NOT_ENOUGH_MEMORY ); SetLastError( ERROR_INVALID_PARAMETER );
return 0; return 0;
} }
...@@ -209,10 +214,17 @@ HBITMAP WINAPI CreateBitmapIndirect( const BITMAP *bmp ) ...@@ -209,10 +214,17 @@ HBITMAP WINAPI CreateBitmapIndirect( const BITMAP *bmp )
} }
bmpobj->dib.dsBm = bm; bmpobj->dib.dsBm = bm;
bmpobj->dib.dsBm.bmBits = NULL; bmpobj->dib.dsBm.bmBits = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size );
if (!bmpobj->dib.dsBm.bmBits)
{
HeapFree( GetProcessHeap(), 0, bmpobj );
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return 0;
}
if (!(hbitmap = alloc_gdi_handle( bmpobj, OBJ_BITMAP, &bitmap_funcs ))) if (!(hbitmap = alloc_gdi_handle( bmpobj, OBJ_BITMAP, &bitmap_funcs )))
{ {
HeapFree( GetProcessHeap(), 0, bmpobj->dib.dsBm.bmBits );
HeapFree( GetProcessHeap(), 0, bmpobj ); HeapFree( GetProcessHeap(), 0, bmpobj );
return 0; return 0;
} }
......
...@@ -168,13 +168,6 @@ BOOL init_dib_info_from_bitmapobj(dib_info *dib, BITMAPOBJ *bmp) ...@@ -168,13 +168,6 @@ BOOL init_dib_info_from_bitmapobj(dib_info *dib, BITMAPOBJ *bmp)
BITMAPINFO info; BITMAPINFO info;
get_ddb_bitmapinfo( bmp, &info ); get_ddb_bitmapinfo( bmp, &info );
if (!bmp->dib.dsBm.bmBits)
{
int width_bytes = get_dib_stride( bmp->dib.dsBm.bmWidth, bmp->dib.dsBm.bmBitsPixel );
bmp->dib.dsBm.bmBits = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
bmp->dib.dsBm.bmHeight * width_bytes );
if (!bmp->dib.dsBm.bmBits) return FALSE;
}
init_dib_info_from_bitmapinfo( dib, &info, bmp->dib.dsBm.bmBits ); init_dib_info_from_bitmapinfo( dib, &info, bmp->dib.dsBm.bmBits );
} }
else init_dib_info( dib, &bmp->dib.dsBmih, bmp->dib.dsBm.bmWidthBytes, else init_dib_info( dib, &bmp->dib.dsBmih, bmp->dib.dsBm.bmWidthBytes,
......
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