mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 08:55:19 +00:00
[WIN32K]
- Pass bitmap buffer size to SURFACE_AllocSurface and validate it - Fix arithmetic overflow checks by using RtlULongMult - GreExtTextOutW: do not allocate / blit zero sized bitmaps - NtGdiStretchDIBitsInternal: do not pass negative y size to GreCreateBitmapEx - DIB_CreateDIBSection: use calculated bitmap size, instead of biSizeImage when calculating the section view size and as size parameter to GreCreateBitmapEx CORE-9245 #resolve svn path=/trunk/; revision=66611
This commit is contained in:
parent
15f19bca32
commit
ff14566384
8 changed files with 116 additions and 72 deletions
|
@ -1078,6 +1078,7 @@ IntEngMaskBlt(
|
||||||
psoDest->iBitmapFormat,
|
psoDest->iBitmapFormat,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
0,
|
||||||
NULL);
|
NULL);
|
||||||
if (psurfTemp == NULL)
|
if (psurfTemp == NULL)
|
||||||
{
|
{
|
||||||
|
|
|
@ -120,6 +120,7 @@ SURFACE_AllocSurface(
|
||||||
_In_ ULONG iFormat,
|
_In_ ULONG iFormat,
|
||||||
_In_ ULONG fjBitmap,
|
_In_ ULONG fjBitmap,
|
||||||
_In_opt_ ULONG cjWidth,
|
_In_opt_ ULONG cjWidth,
|
||||||
|
_In_opt_ ULONG cjBufSize,
|
||||||
_In_opt_ PVOID pvBits)
|
_In_opt_ PVOID pvBits)
|
||||||
{
|
{
|
||||||
ULONG cBitsPixel, cjBits, cjObject;
|
ULONG cBitsPixel, cjBits, cjObject;
|
||||||
|
@ -127,7 +128,9 @@ SURFACE_AllocSurface(
|
||||||
SURFOBJ *pso;
|
SURFOBJ *pso;
|
||||||
PVOID pvSection;
|
PVOID pvSection;
|
||||||
|
|
||||||
ASSERT(!pvBits || (iType == STYPE_BITMAP));
|
NT_ASSERT(!pvBits || (iType == STYPE_BITMAP));
|
||||||
|
NT_ASSERT((iFormat <= BMF_32BPP) || (cjBufSize != 0));
|
||||||
|
NT_ASSERT((LONG)cy > 0);
|
||||||
|
|
||||||
/* Verify format */
|
/* Verify format */
|
||||||
if ((iFormat < BMF_1BPP) || (iFormat > BMF_PNG))
|
if ((iFormat < BMF_1BPP) || (iFormat > BMF_PNG))
|
||||||
|
@ -151,8 +154,35 @@ SURFACE_AllocSurface(
|
||||||
cjWidth = WIDTH_BYTES_ALIGN32(cx, cBitsPixel);
|
cjWidth = WIDTH_BYTES_ALIGN32(cx, cBitsPixel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate the bitmap size in bytes */
|
/* Is this an uncompressed format? */
|
||||||
cjBits = cjWidth * cy;
|
if (iFormat <= BMF_32BPP)
|
||||||
|
{
|
||||||
|
/* Calculate the correct bitmap size in bytes */
|
||||||
|
if (!NT_SUCCESS(RtlULongMult(cjWidth, cy, &cjBits)))
|
||||||
|
{
|
||||||
|
DPRINT1("Overflow calculating size: cjWidth %lu, cy %lu\n",
|
||||||
|
cjWidth, cy);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Did we get a buffer and size? */
|
||||||
|
if ((pvBits != NULL) && (cjBufSize != 0))
|
||||||
|
{
|
||||||
|
/* Make sure the buffer is large enough */
|
||||||
|
if (cjBufSize < cjBits)
|
||||||
|
{
|
||||||
|
DPRINT1("Buffer is too small, required: %lu, got %lu\n",
|
||||||
|
cjBits, cjBufSize);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Compressed format, use the provided size */
|
||||||
|
NT_ASSERT(cjBufSize != 0);
|
||||||
|
cjBits = cjBufSize;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if we need an extra large object */
|
/* Check if we need an extra large object */
|
||||||
if ((iType == STYPE_BITMAP) && (pvBits == NULL) &&
|
if ((iType == STYPE_BITMAP) && (pvBits == NULL) &&
|
||||||
|
@ -168,9 +198,10 @@ SURFACE_AllocSurface(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for arithmetic overflow */
|
/* Check for arithmetic overflow */
|
||||||
if ((cjBits < cjWidth) || (cjObject < sizeof(SURFACE)))
|
if (cjObject < sizeof(SURFACE))
|
||||||
{
|
{
|
||||||
/* Fail! */
|
/* Fail! */
|
||||||
|
DPRINT1("Overflow calculating cjObject: cjBits %lu\n", cjBits);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,6 +320,7 @@ EngCreateBitmap(
|
||||||
iFormat,
|
iFormat,
|
||||||
fl,
|
fl,
|
||||||
lWidth,
|
lWidth,
|
||||||
|
0,
|
||||||
pvBits);
|
pvBits);
|
||||||
if (!psurf)
|
if (!psurf)
|
||||||
{
|
{
|
||||||
|
@ -327,6 +359,7 @@ EngCreateDeviceBitmap(
|
||||||
iFormat,
|
iFormat,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
0,
|
||||||
NULL);
|
NULL);
|
||||||
if (!psurf)
|
if (!psurf)
|
||||||
{
|
{
|
||||||
|
@ -365,6 +398,7 @@ EngCreateDeviceSurface(
|
||||||
iFormat,
|
iFormat,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
0,
|
||||||
NULL);
|
NULL);
|
||||||
if (!psurf)
|
if (!psurf)
|
||||||
{
|
{
|
||||||
|
|
|
@ -123,6 +123,7 @@ SURFACE_AllocSurface(
|
||||||
_In_ ULONG iFormat,
|
_In_ ULONG iFormat,
|
||||||
_In_ ULONG fjBitmap,
|
_In_ ULONG fjBitmap,
|
||||||
_In_opt_ ULONG cjWidth,
|
_In_opt_ ULONG cjWidth,
|
||||||
|
_In_opt_ ULONG cjBits,
|
||||||
_In_opt_ PVOID pvBits);
|
_In_opt_ PVOID pvBits);
|
||||||
|
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
|
|
|
@ -1453,6 +1453,7 @@ NtGdiGetPixel(
|
||||||
BMF_32BPP,
|
BMF_32BPP,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
0,
|
||||||
&ulRGBColor);
|
&ulRGBColor);
|
||||||
if (psurfDest)
|
if (psurfDest)
|
||||||
{
|
{
|
||||||
|
|
|
@ -103,6 +103,7 @@ GreCreateBitmapEx(
|
||||||
pvCompressedBits = pvBits;
|
pvCompressedBits = pvBits;
|
||||||
pvBits = NULL;
|
pvBits = NULL;
|
||||||
iFormat = (iFormat == BMF_4RLE) ? BMF_4BPP : BMF_8BPP;
|
iFormat = (iFormat == BMF_4RLE) ? BMF_4BPP : BMF_8BPP;
|
||||||
|
cjSizeImage = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate a surface */
|
/* Allocate a surface */
|
||||||
|
@ -112,6 +113,7 @@ GreCreateBitmapEx(
|
||||||
iFormat,
|
iFormat,
|
||||||
fjBitmap,
|
fjBitmap,
|
||||||
cjWidthBytes,
|
cjWidthBytes,
|
||||||
|
cjSizeImage,
|
||||||
pvBits);
|
pvBits);
|
||||||
if (!psurf)
|
if (!psurf)
|
||||||
{
|
{
|
||||||
|
@ -207,6 +209,7 @@ NtGdiCreateBitmap(
|
||||||
iFormat,
|
iFormat,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
0,
|
||||||
NULL);
|
NULL);
|
||||||
if (!psurf)
|
if (!psurf)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1090,7 +1090,7 @@ NtGdiGetDIBitsInternal(
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
/* Copy the data back */
|
/* Copy the data back */
|
||||||
cjMaxInfo = min(cjMaxInfo, DIB_BitmapInfoSize(pbmi, (WORD)iUsage));
|
cjMaxInfo = min(cjMaxInfo, (UINT)DIB_BitmapInfoSize(pbmi, (WORD)iUsage));
|
||||||
ProbeForWrite(pbmiUser, cjMaxInfo, 1);
|
ProbeForWrite(pbmiUser, cjMaxInfo, 1);
|
||||||
RtlCopyMemory(pbmiUser, pbmi, cjMaxInfo);
|
RtlCopyMemory(pbmiUser, pbmi, cjMaxInfo);
|
||||||
}
|
}
|
||||||
|
@ -1228,7 +1228,7 @@ NtGdiStretchDIBitsInternal(
|
||||||
RECTL_vOffsetRect(&rcDst, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
|
RECTL_vOffsetRect(&rcDst, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
|
||||||
|
|
||||||
hbmTmp = GreCreateBitmapEx(pbmi->bmiHeader.biWidth,
|
hbmTmp = GreCreateBitmapEx(pbmi->bmiHeader.biWidth,
|
||||||
pbmi->bmiHeader.biHeight,
|
abs(pbmi->bmiHeader.biHeight),
|
||||||
0,
|
0,
|
||||||
BitmapFormat(pbmi->bmiHeader.biBitCount,
|
BitmapFormat(pbmi->bmiHeader.biBitCount,
|
||||||
pbmi->bmiHeader.biCompression),
|
pbmi->bmiHeader.biCompression),
|
||||||
|
@ -1652,7 +1652,7 @@ DIB_CreateDIBSection(
|
||||||
|
|
||||||
// Get storage location for DIB bits. Only use biSizeImage if it's valid and
|
// Get storage location for DIB bits. Only use biSizeImage if it's valid and
|
||||||
// we're dealing with a compressed bitmap. Otherwise, use width * height.
|
// we're dealing with a compressed bitmap. Otherwise, use width * height.
|
||||||
totalSize = bi->biSizeImage && bi->biCompression != BI_RGB && bi->biCompression != BI_BITFIELDS
|
totalSize = (bi->biSizeImage && (bi->biCompression != BI_RGB) && (bi->biCompression != BI_BITFIELDS))
|
||||||
? bi->biSizeImage : (ULONG)(bm.bmWidthBytes * effHeight);
|
? bi->biSizeImage : (ULONG)(bm.bmWidthBytes * effHeight);
|
||||||
|
|
||||||
if (section)
|
if (section)
|
||||||
|
@ -1674,7 +1674,7 @@ DIB_CreateDIBSection(
|
||||||
}
|
}
|
||||||
|
|
||||||
mapOffset = offset - (offset % Sbi.AllocationGranularity);
|
mapOffset = offset - (offset % Sbi.AllocationGranularity);
|
||||||
mapSize = bi->biSizeImage + (offset - mapOffset);
|
mapSize = totalSize + (offset - mapOffset);
|
||||||
|
|
||||||
SectionOffset.LowPart = mapOffset;
|
SectionOffset.LowPart = mapOffset;
|
||||||
SectionOffset.HighPart = 0;
|
SectionOffset.HighPart = 0;
|
||||||
|
@ -1724,7 +1724,7 @@ DIB_CreateDIBSection(
|
||||||
BitmapFormat(bi->biBitCount * bi->biPlanes, bi->biCompression),
|
BitmapFormat(bi->biBitCount * bi->biPlanes, bi->biCompression),
|
||||||
BMF_DONTCACHE | BMF_USERMEM | BMF_NOZEROINIT |
|
BMF_DONTCACHE | BMF_USERMEM | BMF_NOZEROINIT |
|
||||||
((bi->biHeight < 0) ? BMF_TOPDOWN : 0),
|
((bi->biHeight < 0) ? BMF_TOPDOWN : 0),
|
||||||
bi->biSizeImage,
|
totalSize,
|
||||||
bm.bmBits,
|
bm.bmBits,
|
||||||
0);
|
0);
|
||||||
if (!res)
|
if (!res)
|
||||||
|
|
|
@ -3662,7 +3662,6 @@ GreExtTextOutW(
|
||||||
ROP4_FROM_INDEX(R3_OPINDEX_PATCOPY));
|
ROP4_FROM_INDEX(R3_OPINDEX_PATCOPY));
|
||||||
MouseSafetyOnDrawEnd(dc->ppdev);
|
MouseSafetyOnDrawEnd(dc->ppdev);
|
||||||
BackgroundLeft = DestRect.right;
|
BackgroundLeft = DestRect.right;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DestRect.left = ((TextLeft + 32) >> 6) + realglyph->left;
|
DestRect.left = ((TextLeft + 32) >> 6) + realglyph->left;
|
||||||
|
@ -3675,6 +3674,9 @@ GreExtTextOutW(
|
||||||
MaskRect.right = realglyph->bitmap.width;
|
MaskRect.right = realglyph->bitmap.width;
|
||||||
MaskRect.bottom = realglyph->bitmap.rows;
|
MaskRect.bottom = realglyph->bitmap.rows;
|
||||||
|
|
||||||
|
/* Check if the bitmap has any pixels */
|
||||||
|
if ((bitSize.cx != 0) && (bitSize.cy != 0))
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* We should create the bitmap out of the loop at the biggest possible
|
* We should create the bitmap out of the loop at the biggest possible
|
||||||
* glyph size. Then use memset with 0 to clear it and sourcerect to
|
* glyph size. Then use memset with 0 to clear it and sourcerect to
|
||||||
|
@ -3686,7 +3688,7 @@ GreExtTextOutW(
|
||||||
realglyph->bitmap.buffer);
|
realglyph->bitmap.buffer);
|
||||||
if ( !HSourceGlyph )
|
if ( !HSourceGlyph )
|
||||||
{
|
{
|
||||||
DPRINT1("WARNING: EngLockSurface() failed!\n");
|
DPRINT1("WARNING: EngCreateBitmap() failed!\n");
|
||||||
// FT_Done_Glyph(realglyph);
|
// FT_Done_Glyph(realglyph);
|
||||||
IntUnLockFreeType;
|
IntUnLockFreeType;
|
||||||
DC_vFinishBlit(dc, NULL);
|
DC_vFinishBlit(dc, NULL);
|
||||||
|
@ -3740,6 +3742,7 @@ GreExtTextOutW(
|
||||||
|
|
||||||
EngUnlockSurface(SourceGlyphSurf);
|
EngUnlockSurface(SourceGlyphSurf);
|
||||||
EngDeleteSurface((HSURF)HSourceGlyph);
|
EngDeleteSurface((HSURF)HSourceGlyph);
|
||||||
|
}
|
||||||
|
|
||||||
if (DoBreak)
|
if (DoBreak)
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <ndk/psfuncs.h>
|
#include <ndk/psfuncs.h>
|
||||||
#include <ndk/rtlfuncs.h>
|
#include <ndk/rtlfuncs.h>
|
||||||
#include <ntstrsafe.h>
|
#include <ntstrsafe.h>
|
||||||
|
#include <ntintsafe.h>
|
||||||
#include <ntddkbd.h>
|
#include <ntddkbd.h>
|
||||||
|
|
||||||
/* Win32 headers */
|
/* Win32 headers */
|
||||||
|
|
Loading…
Reference in a new issue