- Patch by Jeffrey Morlan: Fix bounds checking and change NtGdiDoPalette to use a temporary kmode buffer. See Bug 3383.

svn path=/trunk/; revision=34934
This commit is contained in:
James Tabor 2008-07-29 18:11:18 +00:00
parent 4c985ce93a
commit a9cd7fec76

View file

@ -436,18 +436,16 @@ IntGetSystemPaletteEntries(HDC hDC,
{ {
if (pe != NULL) if (pe != NULL)
{ {
UINT CopyEntries; if (StartIndex >= palGDI->NumColors)
Entries = 0;
if (StartIndex + Entries < palGDI->NumColors) else if (Entries > palGDI->NumColors - StartIndex)
CopyEntries = StartIndex + Entries; Entries = palGDI->NumColors - StartIndex;
else
CopyEntries = palGDI->NumColors - StartIndex;
memcpy(pe, memcpy(pe,
palGDI->IndexedColors + StartIndex, palGDI->IndexedColors + StartIndex,
CopyEntries * sizeof(pe[0])); Entries * sizeof(pe[0]));
Ret = CopyEntries; Ret = Entries;
} }
else else
{ {
@ -837,6 +835,7 @@ NtGdiDoPalette(
IN BOOL bInbound) IN BOOL bInbound)
{ {
LONG ret; LONG ret;
LPVOID pEntries = NULL;
/* FIXME: Handle bInbound correctly */ /* FIXME: Handle bInbound correctly */
@ -846,58 +845,76 @@ NtGdiDoPalette(
return 0; return 0;
} }
_SEH_TRY if (pUnsafeEntries)
{ {
switch(iFunc) pEntries = ExAllocatePool(PagedPool, cEntries * sizeof(PALETTEENTRY));
if (!pEntries)
return 0;
if (bInbound)
{ {
case GdiPalAnimate: _SEH_TRY
{
ProbeForRead(pUnsafeEntries, cEntries * sizeof(PALETTEENTRY), 1); ProbeForRead(pUnsafeEntries, cEntries * sizeof(PALETTEENTRY), 1);
ret = IntAnimatePalette((HPALETTE)hObj, iStart, cEntries, pUnsafeEntries); memcpy(pEntries, pUnsafeEntries, cEntries * sizeof(PALETTEENTRY));
break; }
_SEH_HANDLE
case GdiPalSetEntries: {
ProbeForRead(pUnsafeEntries, cEntries * sizeof(PALETTEENTRY), 1); ExFreePool(pEntries);
ret = IntSetPaletteEntries((HPALETTE)hObj, iStart, cEntries, pUnsafeEntries); _SEH_YIELD(return 0);
break; }
_SEH_END
case GdiPalGetEntries:
if (pUnsafeEntries)
{
ProbeForWrite(pUnsafeEntries, cEntries * sizeof(PALETTEENTRY), 1);
}
ret = IntGetPaletteEntries((HPALETTE)hObj, iStart, cEntries, pUnsafeEntries);
break;
case GdiPalGetSystemEntries:
if (pUnsafeEntries)
{
ProbeForWrite(pUnsafeEntries, cEntries * sizeof(PALETTEENTRY), 1);
}
ret = IntGetSystemPaletteEntries((HDC)hObj, iStart, cEntries, pUnsafeEntries);
break;
case GdiPalSetColorTable:
ProbeForRead(pUnsafeEntries, cEntries * sizeof(PALETTEENTRY), 1);
ret = IntSetDIBColorTable((HDC)hObj, iStart, cEntries, (RGBQUAD*)pUnsafeEntries);
break;
case GdiPalGetColorTable:
if (pUnsafeEntries)
{
ProbeForWrite(pUnsafeEntries, cEntries * sizeof(PALETTEENTRY), 1);
}
ret = IntGetDIBColorTable((HDC)hObj, iStart, cEntries, (RGBQUAD*)pUnsafeEntries);
break;
default:
ret = 0;
} }
} }
_SEH_HANDLE
ret = 0;
switch(iFunc)
{ {
ret = 0; case GdiPalAnimate:
if (pEntries)
ret = IntAnimatePalette((HPALETTE)hObj, iStart, cEntries, pEntries);
break;
case GdiPalSetEntries:
if (pEntries)
ret = IntSetPaletteEntries((HPALETTE)hObj, iStart, cEntries, pEntries);
break;
case GdiPalGetEntries:
ret = IntGetPaletteEntries((HPALETTE)hObj, iStart, cEntries, pEntries);
break;
case GdiPalGetSystemEntries:
ret = IntGetSystemPaletteEntries((HDC)hObj, iStart, cEntries, pEntries);
break;
case GdiPalSetColorTable:
if (pEntries)
ret = IntSetDIBColorTable((HDC)hObj, iStart, cEntries, (RGBQUAD*)pEntries);
break;
case GdiPalGetColorTable:
if (pEntries)
ret = IntGetDIBColorTable((HDC)hObj, iStart, cEntries, (RGBQUAD*)pEntries);
break;
}
if (pEntries)
{
if (!bInbound)
{
_SEH_TRY
{
ProbeForWrite(pUnsafeEntries, cEntries * sizeof(PALETTEENTRY), 1);
memcpy(pUnsafeEntries, pEntries, cEntries * sizeof(PALETTEENTRY));
}
_SEH_HANDLE
{
ret = 0;
}
_SEH_END
}
ExFreePool(pEntries);
} }
_SEH_END
return ret; return ret;
} }