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…
==============================================================================
--- 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)
{