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

Huw Davies huw at codeweavers.com
Tue Jan 23 03:44:23 CST 2018


Signed-off-by: Huw Davies <huw at codeweavers.com>
---
 dlls/gdi32/bitmap.c    | 20 ++++++++++++++++----
 dlls/gdi32/dibdrv/dc.c |  7 -------
 2 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/dlls/gdi32/bitmap.c b/dlls/gdi32/bitmap.c
index c16793d82b..0ae5b20052 100644
--- a/dlls/gdi32/bitmap.c
+++ b/dlls/gdi32/bitmap.c
@@ -145,6 +145,8 @@ HBITMAP WINAPI CreateBitmapIndirect( const BITMAP *bmp )
     BITMAP bm;
     BITMAPOBJ *bmpobj;
     HBITMAP hbitmap;
+    INT dib_stride;
+    SIZE_T size;
 
     if (!bmp || bmp->bmType)
     {
@@ -194,10 +196,13 @@ HBITMAP WINAPI CreateBitmapIndirect( const BITMAP *bmp )
 
     /* Windows ignores the provided bm.bmWidthBytes */
     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;
     }
 
@@ -209,10 +214,17 @@ HBITMAP WINAPI CreateBitmapIndirect( const BITMAP *bmp )
     }
 
     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 )))
     {
+        HeapFree( GetProcessHeap(), 0, bmpobj->dib.dsBm.bmBits );
         HeapFree( GetProcessHeap(), 0, bmpobj );
         return 0;
     }
diff --git a/dlls/gdi32/dibdrv/dc.c b/dlls/gdi32/dibdrv/dc.c
index aee305fda8..2447093921 100644
--- a/dlls/gdi32/dibdrv/dc.c
+++ b/dlls/gdi32/dibdrv/dc.c
@@ -168,13 +168,6 @@ BOOL init_dib_info_from_bitmapobj(dib_info *dib, BITMAPOBJ *bmp)
         BITMAPINFO 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 );
     }
     else init_dib_info( dib, &bmp->dib.dsBmih, bmp->dib.dsBm.bmWidthBytes,
-- 
2.12.0




More information about the wine-devel mailing list