Do not fill in the color table in GetDIBits if lpvBits is NULL, with test

Jeremy White jwhite at codeweavers.com
Wed Jul 11 14:14:45 CDT 2007


Prevents a stack corruption in Dreamweaver 8.
-------------- next part --------------
>From e918443e77529b77fa8b87102aa0e527d78268f5 Mon Sep 17 00:00:00 2001
From: jwhite <jwhite at codeweavers.com>
Date: Wed, 11 Jul 2007 14:05:07 -0500
Subject: Added a test for the case where lpvBits in GetDIBits is NULL and the bitcount is 0;
that's a call intended to just get basic info, we shouldn't fill in the color table.
---
 dlls/gdi32/tests/bitmap.c |   41 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 41 insertions(+), 0 deletions(-)

diff --git a/dlls/gdi32/tests/bitmap.c b/dlls/gdi32/tests/bitmap.c
index 019bb35..566545d 100644
--- a/dlls/gdi32/tests/bitmap.c
+++ b/dlls/gdi32/tests/bitmap.c
@@ -1791,6 +1791,46 @@ static void test_bitmapinfoheadersize(void)
     ReleaseDC(0, hdc);
 }
 
+static void test_get16dibits(void)
+{
+    BYTE bits[4 * (16 / sizeof(BYTE))];
+    HBITMAP hbmp;
+    HDC screen_dc = GetDC(NULL);
+    int ret;
+    BITMAPINFO * info;
+    int info_len = sizeof(BITMAPINFOHEADER) + 1024;
+    BYTE *p;
+    int overwritten_bytes = 0;
+
+    memset(bits, 0, sizeof(bits));
+    hbmp = CreateBitmap(2, 2, 1, 16, bits);
+    ok(hbmp != NULL, "CreateBitmap failed\n");
+
+    info  = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
+    assert(info);
+
+    memset(info, '!', info_len);
+    memset(info, 0, sizeof(info->bmiHeader));
+
+    info->bmiHeader.biSize = sizeof(info->bmiHeader);
+    info->bmiHeader.biWidth = 2;
+    info->bmiHeader.biHeight = 2;
+    info->bmiHeader.biPlanes = 1;
+    info->bmiHeader.biCompression = BI_RGB;
+
+    ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
+    ok(ret != 0, "GetDIBits failed\n");
+
+    for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
+        if (*p != '!')
+            overwritten_bytes++;
+    ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
+
+    DeleteObject(hbmp);
+    ReleaseDC(NULL, screen_dc);
+}
+
+
 START_TEST(bitmap)
 {
     is_win9x = GetWindowLongPtrW(GetDesktopWindow(), GWLP_WNDPROC) == 0;
@@ -1809,4 +1849,5 @@ START_TEST(bitmap)
     test_select_object();
     test_CreateBitmap();
     test_bitmapinfoheadersize();
+    test_get16dibits();
 }
-- 
1.4.4.4

-------------- next part --------------
>From aa5d2998f1745b2f6275d79bba7188f011fc70f6 Mon Sep 17 00:00:00 2001
From: jwhite <jwhite at codeweavers.com>
Date: Wed, 11 Jul 2007 14:11:45 -0500
Subject: Do not fill in the color table if lpvBits is NULL

---
 dlls/gdi32/dib.c |   14 +++++++++++---
 1 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c
index 2a98efb..e1737c5 100644
--- a/dlls/gdi32/dib.c
+++ b/dlls/gdi32/dib.c
@@ -972,11 +972,19 @@ INT WINAPI GetDIBits(
                     break;
                     
                 case 16:
+		    if (bits)
+		    {
+                        /* From MSDN:
+			    If lpvBits is NULL and the bit count member of BITMAPINFO is
+  		   	    initialized to zero, GetDIBits fills in a BITMAPINFOHEADER structure
+  			    or BITMAPCOREHEADER without the color table   */
+
+			((PDWORD)info->bmiColors)[0] = 0xf800;
+			((PDWORD)info->bmiColors)[1] = 0x07e0;
+			((PDWORD)info->bmiColors)[2] = 0x001f;
+                    }
                     info->bmiHeader.biBitCount = 16;
                     info->bmiHeader.biCompression = BI_BITFIELDS;
-                    ((PDWORD)info->bmiColors)[0] = 0xf800;
-                    ((PDWORD)info->bmiColors)[1] = 0x07e0;
-                    ((PDWORD)info->bmiColors)[2] = 0x001f;
                     break;
     
                 default:
-- 
1.4.4.4



More information about the wine-patches mailing list