Dmitry Timoshkov : gdi32: Do not allow to create too large device dependent bitmaps like Windows does .

Alexandre Julliard julliard at winehq.org
Tue Jan 15 07:47:12 CST 2008


Module: wine
Branch: master
Commit: d5456de058da12e06d6b96b129bf699bae380ff6
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=d5456de058da12e06d6b96b129bf699bae380ff6

Author: Dmitry Timoshkov <dmitry at codeweavers.com>
Date:   Tue Jan 15 18:45:17 2008 +0800

gdi32: Do not allow to create too large device dependent bitmaps like Windows does.

---

 dlls/gdi32/bitmap.c       |  118 +++++++++++++++++++++++----------------------
 dlls/gdi32/tests/bitmap.c |   18 +++++++
 2 files changed, 79 insertions(+), 57 deletions(-)

diff --git a/dlls/gdi32/bitmap.c b/dlls/gdi32/bitmap.c
index 3355541..55b3236 100644
--- a/dlls/gdi32/bitmap.c
+++ b/dlls/gdi32/bitmap.c
@@ -136,79 +136,71 @@ HBITMAP WINAPI CreateCompatibleBitmap( HDC hdc, INT width, INT height)
 
     TRACE("(%p,%d,%d) =\n", hdc, width, height);
 
-    if ((width >= 0x10000) || (height >= 0x10000))
+    if (!(dc = DC_GetDCPtr(hdc))) return 0;
+
+    if (GDIMAGIC( dc->header.wMagic ) != MEMORY_DC_MAGIC)
     {
-        FIXME("got bad width %d or height %d, please look for reason\n",
-              width, height);
+        hbmpRet = CreateBitmap(width, height,
+                               GetDeviceCaps(hdc, PLANES),
+                               GetDeviceCaps(hdc, BITSPIXEL),
+                               NULL);
     }
-    else
+    else  /* Memory DC */
     {
-        if (!(dc = DC_GetDCPtr(hdc))) return 0;
+        BITMAPOBJ *bmp = GDI_GetObjPtr( dc->hBitmap, BITMAP_MAGIC );
 
-        if (GDIMAGIC( dc->header.wMagic ) != MEMORY_DC_MAGIC)
+        if (!bmp->dib)
         {
+            /* A device-dependent bitmap is selected in the DC */
             hbmpRet = CreateBitmap(width, height,
-                                   GetDeviceCaps(hdc, PLANES),
-                                   GetDeviceCaps(hdc, BITSPIXEL),
+                                   bmp->bitmap.bmPlanes,
+                                   bmp->bitmap.bmBitsPixel,
                                    NULL);
         }
-        else  /* Memory DC */
+        else
         {
-            BITMAPOBJ *bmp = GDI_GetObjPtr( dc->hBitmap, BITMAP_MAGIC );
-
-            if (!bmp->dib)
-            {
-                /* A device-dependent bitmap is selected in the DC */
-                hbmpRet = CreateBitmap(width, height,
-                                       bmp->bitmap.bmPlanes,
-                                       bmp->bitmap.bmBitsPixel,
-                                       NULL);
-            }
-            else
-            {
-                /* A DIB section is selected in the DC */
-                BITMAPINFO *bi;
-                void *bits;
+            /* A DIB section is selected in the DC */
+            BITMAPINFO *bi;
+            void *bits;
 
-                /* Allocate memory for a BITMAPINFOHEADER structure and a
-                   color table. The maximum number of colors in a color table
-                   is 256 which corresponds to a bitmap with depth 8.
-                   Bitmaps with higher depths don't have color tables. */
-                bi = HeapAlloc(GetProcessHeap(), 0, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
+            /* Allocate memory for a BITMAPINFOHEADER structure and a
+               color table. The maximum number of colors in a color table
+               is 256 which corresponds to a bitmap with depth 8.
+               Bitmaps with higher depths don't have color tables. */
+            bi = HeapAlloc(GetProcessHeap(), 0, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
 
-                if (bi)
+            if (bi)
+            {
+                bi->bmiHeader.biSize          = sizeof(bi->bmiHeader);
+                bi->bmiHeader.biWidth         = width;
+                bi->bmiHeader.biHeight        = height;
+                bi->bmiHeader.biPlanes        = bmp->dib->dsBmih.biPlanes;
+                bi->bmiHeader.biBitCount      = bmp->dib->dsBmih.biBitCount;
+                bi->bmiHeader.biCompression   = bmp->dib->dsBmih.biCompression;
+                bi->bmiHeader.biSizeImage     = 0;
+                bi->bmiHeader.biXPelsPerMeter = bmp->dib->dsBmih.biXPelsPerMeter;
+                bi->bmiHeader.biYPelsPerMeter = bmp->dib->dsBmih.biYPelsPerMeter;
+                bi->bmiHeader.biClrUsed       = bmp->dib->dsBmih.biClrUsed;
+                bi->bmiHeader.biClrImportant  = bmp->dib->dsBmih.biClrImportant;
+
+                if (bi->bmiHeader.biCompression == BI_BITFIELDS)
+                {
+                    /* Copy the color masks */
+                    CopyMemory(bi->bmiColors, bmp->dib->dsBitfields, 3 * sizeof(DWORD));
+                }
+                else if (bi->bmiHeader.biBitCount <= 8)
                 {
-                    bi->bmiHeader.biSize          = sizeof(bi->bmiHeader);
-                    bi->bmiHeader.biWidth         = width;
-                    bi->bmiHeader.biHeight        = height;
-                    bi->bmiHeader.biPlanes        = bmp->dib->dsBmih.biPlanes;
-                    bi->bmiHeader.biBitCount      = bmp->dib->dsBmih.biBitCount;
-                    bi->bmiHeader.biCompression   = bmp->dib->dsBmih.biCompression;
-                    bi->bmiHeader.biSizeImage     = 0;
-                    bi->bmiHeader.biXPelsPerMeter = bmp->dib->dsBmih.biXPelsPerMeter;
-                    bi->bmiHeader.biYPelsPerMeter = bmp->dib->dsBmih.biYPelsPerMeter;
-                    bi->bmiHeader.biClrUsed       = bmp->dib->dsBmih.biClrUsed;
-                    bi->bmiHeader.biClrImportant  = bmp->dib->dsBmih.biClrImportant;
-
-                    if (bi->bmiHeader.biCompression == BI_BITFIELDS)
-                    {
-                        /* Copy the color masks */
-                        CopyMemory(bi->bmiColors, bmp->dib->dsBitfields, 3 * sizeof(DWORD));
-                    }
-                    else if (bi->bmiHeader.biBitCount <= 8)
-                    {
-                        /* Copy the color table */
-                        GetDIBColorTable(hdc, 0, 256, bi->bmiColors);
-                    }
-
-                    hbmpRet = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
-                    HeapFree(GetProcessHeap(), 0, bi);
+                    /* Copy the color table */
+                    GetDIBColorTable(hdc, 0, 256, bi->bmiColors);
                 }
+
+                hbmpRet = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
+                HeapFree(GetProcessHeap(), 0, bi);
             }
-            GDI_ReleaseObj(dc->hBitmap);
         }
-        DC_ReleaseDCPtr( dc );
+        GDI_ReleaseObj(dc->hBitmap);
     }
+    DC_ReleaseDCPtr( dc );
 
     TRACE("\t\t%p\n", hbmpRet);
     return hbmpRet;
@@ -242,6 +234,12 @@ HBITMAP WINAPI CreateBitmapIndirect( const BITMAP *bmp )
         return NULL;
     }
 
+    if (bmp->bmWidth > 0x7ffffff || bmp->bmHeight > 0x7ffffff)
+    {
+        SetLastError( ERROR_INVALID_PARAMETER );
+        return 0;
+    }
+
     bm = *bmp;
 
     if (!bm.bmWidth || !bm.bmHeight)
@@ -278,6 +276,12 @@ HBITMAP WINAPI CreateBitmapIndirect( const BITMAP *bmp )
 
     /* Windows ignores the provided bm.bmWidthBytes */
     bm.bmWidthBytes = BITMAP_GetWidthBytes( bm.bmWidth, bm.bmBitsPixel );
+    /* XP doesn't allow to create bitmaps larger than 128 Mb */
+    if (bm.bmHeight * bm.bmWidthBytes > 128 * 1024 * 1024)
+    {
+        SetLastError( ERROR_NOT_ENOUGH_MEMORY );
+        return 0;
+    }
 
       /* Create the BITMAPOBJ */
     bmpobj = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC,
diff --git a/dlls/gdi32/tests/bitmap.c b/dlls/gdi32/tests/bitmap.c
index eb6c09d..573fe56 100644
--- a/dlls/gdi32/tests/bitmap.c
+++ b/dlls/gdi32/tests/bitmap.c
@@ -25,6 +25,7 @@
 
 #include "windef.h"
 #include "winbase.h"
+#include "winerror.h"
 #include "wingdi.h"
 #include "winuser.h"
 #include "mmsystem.h"
@@ -966,6 +967,23 @@ static void test_bitmap(void)
     hdc = CreateCompatibleDC(0);
     assert(hdc != 0);
 
+    SetLastError(0xdeadbeef);
+    hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
+    ok(hbmp != 0, "CreateBitmap should not fail\n");
+    DeleteObject(hbmp);
+
+    SetLastError(0xdeadbeef);
+    hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
+    ok(!hbmp, "CreateBitmap should fail\n");
+    ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY,
+       "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
+
+    SetLastError(0xdeadbeef);
+    hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
+    ok(!hbmp, "CreateBitmap should fail\n");
+    ok(GetLastError() == ERROR_INVALID_PARAMETER,
+       "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
+
     hbmp = CreateBitmap(15, 15, 1, 1, NULL);
     assert(hbmp != NULL);
 




More information about the wine-cvs mailing list