- Assume that the provided buffer size is maximal in GetDIBits
[WIN32K]
 - Probe buffer before writing to it
 - Fail DIB Section creation if palette creation failed


svn path=/trunk/; revision=57535
This commit is contained in:
Jérôme Gardou 2012-10-10 23:05:38 +00:00
parent 833bace73a
commit 79ff1e973a
2 changed files with 20 additions and 12 deletions

View file

@ -13,7 +13,7 @@
* 11/16/1999 (RJJ) lifted from wine * 11/16/1999 (RJJ) lifted from wine
*/ */
INT FASTCALL DIB_BitmapInfoSize(const BITMAPINFO * info, WORD coloruse) INT FASTCALL DIB_BitmapInfoSize(const BITMAPINFO * info, WORD coloruse, BOOL max)
{ {
unsigned int colors, size, masks = 0; unsigned int colors, size, masks = 0;
@ -26,7 +26,7 @@ INT FASTCALL DIB_BitmapInfoSize(const BITMAPINFO * info, WORD coloruse)
} }
else /* assume BITMAPINFOHEADER */ else /* assume BITMAPINFOHEADER */
{ {
colors = info->bmiHeader.biClrUsed; colors = max ? 1 << info->bmiHeader.biBitCount : info->bmiHeader.biClrUsed;
if (colors > 256) colors = 256; if (colors > 256) colors = 256;
if (!colors && (info->bmiHeader.biBitCount <= 8)) if (!colors && (info->bmiHeader.biBitCount <= 8))
colors = 1 << info->bmiHeader.biBitCount; colors = 1 << info->bmiHeader.biBitCount;
@ -409,7 +409,8 @@ GetDIBits(
} }
cjBmpScanSize = DIB_BitmapMaxBitsSize(lpbmi, cScanLines); cjBmpScanSize = DIB_BitmapMaxBitsSize(lpbmi, cScanLines);
cjInfoSize = DIB_BitmapInfoSize(lpbmi, uUsage); /* Caller must provide maximum size possible */
cjInfoSize = DIB_BitmapInfoSize(lpbmi, uUsage, TRUE);
if ( lpvBits ) if ( lpvBits )
{ {

View file

@ -1038,7 +1038,7 @@ NtGdiGetDIBitsInternal(
_SEH2_TRY _SEH2_TRY
{ {
/* Probe and copy the BITMAPINFO */ /* Probe and copy the BITMAPINFO */
ProbeForWrite(pbmiUser, cjMaxInfo, 1); ProbeForRead(pbmiUser, cjMaxInfo, 1);
RtlCopyMemory(pbmi, pbmiUser, cjMaxInfo); RtlCopyMemory(pbmi, pbmiUser, cjMaxInfo);
} }
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
@ -1082,7 +1082,8 @@ NtGdiGetDIBitsInternal(
/* Use SEH to copy back to user mode */ /* Use SEH to copy back to user mode */
_SEH2_TRY _SEH2_TRY
{ {
/* Buffer is already probed, copy the data back */ /* Copy the data back */
ProbeForWrite(pbmiUser, cjMaxInfo, 1);
RtlCopyMemory(pbmiUser, pbmi, cjMaxInfo); RtlCopyMemory(pbmiUser, pbmi, cjMaxInfo);
} }
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
@ -1551,7 +1552,7 @@ DIB_CreateDIBSection(
HBITMAP res = 0; HBITMAP res = 0;
SURFACE *bmp = NULL; SURFACE *bmp = NULL;
void *mapBits = NULL; void *mapBits = NULL;
PPALETTE ppalDIB; PPALETTE ppalDIB = NULL;
// Fill BITMAP32 structure with DIB data // Fill BITMAP32 structure with DIB data
CONST BITMAPINFOHEADER *bi = &bmi->bmiHeader; CONST BITMAPINFOHEADER *bi = &bmi->bmiHeader;
@ -1685,15 +1686,10 @@ DIB_CreateDIBSection(
/* Create a palette for the DIB */ /* Create a palette for the DIB */
ppalDIB = CreateDIBPalette(bmi, dc, usage); ppalDIB = CreateDIBPalette(bmi, dc, usage);
if (ppalDIB)
{
SURFACE_vSetPalette(bmp, ppalDIB);
PALETTE_ShareUnlockPalette(ppalDIB);
}
// Clean up in case of errors // Clean up in case of errors
cleanup: cleanup:
if (!res || !bmp || !bm.bmBits) if (!res || !bmp || !bm.bmBits || !ppalDIB)
{ {
DPRINT("Got an error res=%p, bmp=%p, bm.bmBits=%p\n", res, bmp, bm.bmBits); DPRINT("Got an error res=%p, bmp=%p, bm.bmBits=%p\n", res, bmp, bm.bmBits);
if (bm.bmBits) if (bm.bmBits)
@ -1709,17 +1705,28 @@ cleanup:
} }
if (bmp) if (bmp)
{
SURFACE_ShareUnlockSurface(bmp);
bmp = NULL; bmp = NULL;
}
if (res) if (res)
{ {
GreDeleteObject(res); GreDeleteObject(res);
res = 0; res = 0;
} }
if(ppalDIB)
{
PALETTE_ShareUnlockPalette(ppalDIB);
}
} }
if (bmp) if (bmp)
{ {
/* If we're here, everything went fine */
SURFACE_vSetPalette(bmp, ppalDIB);
PALETTE_ShareUnlockPalette(ppalDIB);
SURFACE_ShareUnlockSurface(bmp); SURFACE_ShareUnlockSurface(bmp);
} }