Author: khornicek
Date: Sat Mar  4 10:37:00 2017
New Revision: 74046

URL: http://svn.reactos.org/svn/reactos?rev=74046&view=rev
Log:
[WIN32K]
- GreGetDIBitsInternal:
- Prevent an access violation in DIB_FreeConvertedBitmapInfo by initializing 
the bit count before calling DIB_ConvertBitmapInfo and setting clrUsed.
- Validate input parameters and return correct values - only return number of 
scan lines if bits are not null and bpp is not zero. Otherwise return 1 on 
success.
- We now pass more gdi32:GetDIBits and gdi32:bitmap tests.
CORE-9270

Modified:
    trunk/reactos/win32ss/gdi/ntgdi/dibobj.c

Modified: trunk/reactos/win32ss/gdi/ntgdi/dibobj.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/dibobj.c?rev=74046&r1=74045&r2=74046&view=diff
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/dibobj.c    [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/dibobj.c    [iso-8859-1] Sat Mar  4 
10:37:00 2017
@@ -719,6 +719,21 @@
     if ((Usage && Usage != DIB_PAL_COLORS) || !Info || !hBitmap)
         return 0;
 
+    pDC = DC_LockDc(hDC);
+    if (pDC == NULL || pDC->dctype == DC_TYPE_INFO)
+    {
+        ScanLines = 0;
+        goto done;
+    }
+
+    /* Get a pointer to the source bitmap object */
+    psurf = SURFACE_ShareLockSurface(hBitmap);
+    if (psurf == NULL)
+    {
+        ScanLines = 0;
+        goto done;
+    }
+
     colorPtr = (LPBYTE)Info + Info->bmiHeader.biSize;
     rgbQuads = colorPtr;
 
@@ -733,36 +748,47 @@
     {
         DPRINT("Wrong bitmap format\n");
         EngSetLastError(ERROR_INVALID_PARAMETER);
-        return 0;
+        ScanLines = 0;
+        goto done;
     }
     else if(bitmap_type == 0)
     {
         /* We need a BITMAPINFO to create a DIB, but we have to fill
          * the BITMAPCOREINFO we're provided */
         pbmci = (BITMAPCOREINFO*)Info;
+        /* fill in the the bit count, so we can calculate the right ColorsSize 
during the conversion */
+        pbmci->bmciHeader.bcBitCount = 
BitsPerFormat(psurf->SurfObj.iBitmapFormat);
         Info = DIB_ConvertBitmapInfo((BITMAPINFO*)pbmci, Usage);
         if(Info == NULL)
         {
             DPRINT1("Error, could not convert the BITMAPCOREINFO!\n");
-            return 0;
+            ScanLines = 0;
+            goto done;
         }
         rgbQuads = Info->bmiColors;
     }
 
-    pDC = DC_LockDc(hDC);
-    if (pDC == NULL || pDC->dctype == DC_TYPE_INFO)
+    /* Validate input:
+       - negative width is always an invalid value
+       - non-null Bits and zero bpp is an invalid combination
+       - only check the rest of the input params if either bpp is non-zero or 
Bits are set */
+    if (width < 0 || (bpp == 0 && Bits))
     {
         ScanLines = 0;
         goto done;
     }
 
-    /* Get a pointer to the source bitmap object */
-    psurf = SURFACE_ShareLockSurface(hBitmap);
-    if (psurf == NULL)
-    {
-        ScanLines = 0;
-        goto done;
-    }
+    if (Bits || bpp)
+    {
+        if ((height == 0 || planes < 0 || width == 0) || (compr && compr != 
BI_BITFIELDS && compr != BI_RGB))
+        {
+            ScanLines = 0;
+            goto done;
+        }
+    }
+
+    Info->bmiHeader.biClrUsed = 0;
+    Info->bmiHeader.biClrImportant = 0;
 
     /* Fill in the structure */
     switch(bpp)
@@ -777,27 +803,21 @@
         Info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes( 
Info->bmiHeader.biWidth,
                                       Info->bmiHeader.biHeight,
                                       Info->bmiHeader.biBitCount);
-
-        if ((Info->bmiHeader.biBitCount == 16) ||
-            (Info->bmiHeader.biBitCount == 32))
-        {
-            Info->bmiHeader.biCompression = BI_BITFIELDS;
-        }
-        else
-        {
-            Info->bmiHeader.biCompression = BI_RGB;
-        }
+        Info->bmiHeader.biCompression = (Info->bmiHeader.biBitCount == 16 || 
Info->bmiHeader.biBitCount == 32) ? 
+                                        BI_BITFIELDS : BI_RGB;
         Info->bmiHeader.biXPelsPerMeter = 0;
         Info->bmiHeader.biYPelsPerMeter = 0;
-        Info->bmiHeader.biClrUsed = 0;
-        Info->bmiHeader.biClrImportant = 0;
-        ScanLines = abs(Info->bmiHeader.biHeight);
+
+        if (Info->bmiHeader.biBitCount <= 8 && Info->bmiHeader.biClrUsed == 0)
+            Info->bmiHeader.biClrUsed = 1 << Info->bmiHeader.biBitCount;
+
+        ScanLines = 1;
         goto done;
 
     case 1:
     case 4:
     case 8:
-        Info->bmiHeader.biClrUsed = 0;
+        Info->bmiHeader.biClrUsed = 1 << bpp;
 
         /* If the bitmap is a DIB section and has the same format as what
          * is requested, go ahead! */
@@ -931,8 +951,14 @@
             }
         }
         break;
-    }
+
+    default:
+        ScanLines = 0;
+        goto done;
+    }
+
     Info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(width, height, bpp);
+    Info->bmiHeader.biPlanes = 1;
 
     if(Bits && ScanLines)
     {
@@ -1019,13 +1045,22 @@
         GreDeleteObject(hBmpDest);
         EXLATEOBJ_vCleanup(&exlo);
     }
-    else ScanLines = abs(height);
+    else
+    {
+        /* Signals success and not the actual number of scan lines*/
+        ScanLines = 1;
+    }
 
 done:
 
-    if(pDC) DC_UnlockDc(pDC);
-    if(psurf) SURFACE_ShareUnlockSurface(psurf);
-    if(pbmci) DIB_FreeConvertedBitmapInfo(Info, (BITMAPINFO*)pbmci, Usage);
+    if (pbmci)
+        DIB_FreeConvertedBitmapInfo(Info, (BITMAPINFO*)pbmci, Usage);
+
+    if (psurf)
+        SURFACE_ShareUnlockSurface(psurf);
+
+    if (pDC)
+        DC_UnlockDc(pDC);
 
     return ScanLines;
 }
@@ -2074,6 +2109,7 @@
     pNewBmi->bmiHeader.biSizeImage = 
DIB_GetDIBImageBytes(pNewBmi->bmiHeader.biWidth,
                                      pNewBmi->bmiHeader.biHeight,
                                      pNewBmi->bmiHeader.biBitCount);
+    pNewBmi->bmiHeader.biClrUsed = numColors;
 
     if(Usage == DIB_PAL_COLORS)
     {


Reply via email to