mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 21:23:05 +00:00
[WIN32SS][NTGDI] Avoid allocation of zero size in NtGdiGetGlyphIndicesW (#1577)
In NtGdiGetGlyphIndicesW function, allocation of zero size had caused fatal failures. Avoid allocation of zero size in ExAllocatePoolWithTag calls. Optimize for cwc == 0. CORE-12825
This commit is contained in:
parent
ccd95b9880
commit
c52b8288d1
1 changed files with 57 additions and 31 deletions
|
@ -6890,37 +6890,32 @@ NtGdiGetGlyphIndicesW(
|
||||||
PWSTR Safepwc = NULL;
|
PWSTR Safepwc = NULL;
|
||||||
LPCWSTR UnSafepwc = pwc;
|
LPCWSTR UnSafepwc = pwc;
|
||||||
LPWORD UnSafepgi = pgi;
|
LPWORD UnSafepgi = pgi;
|
||||||
|
FT_Face Face;
|
||||||
|
TT_OS2 *pOS2;
|
||||||
|
|
||||||
/* Check for integer overflow */
|
if (cwc < 0)
|
||||||
if (cwc & 0x80000000) // (INT_MAX + 1) == INT_MIN
|
{
|
||||||
|
DPRINT1("cwc < 0\n");
|
||||||
return GDI_ERROR;
|
return GDI_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (!UnSafepwc && !UnSafepgi)
|
if (!UnSafepwc && !UnSafepgi && cwc > 0)
|
||||||
return cwc;
|
{
|
||||||
|
DPRINT1("!UnSafepwc && !UnSafepgi && cwc > 0\n");
|
||||||
|
return GDI_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (!UnSafepwc || !UnSafepgi)
|
if (!UnSafepwc != !UnSafepgi)
|
||||||
{
|
{
|
||||||
DPRINT1("UnSafepwc == %p, UnSafepgi = %p\n", UnSafepwc, UnSafepgi);
|
DPRINT1("UnSafepwc == %p, UnSafepgi = %p\n", UnSafepwc, UnSafepgi);
|
||||||
return GDI_ERROR;
|
return GDI_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Special undocumented case!
|
/* Get FontGDI */
|
||||||
if (!pwc && !pgi && (cwc == 0))
|
|
||||||
{
|
|
||||||
DPRINT1("ERR: NtGdiGetGlyphIndicesW with (!pwc && !pgi && (cwc == 0)) is UNIMPLEMENTED!\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: This is a hack!! (triggered by e.g. Word 2010). See CORE-12825
|
|
||||||
if (cwc == 0)
|
|
||||||
{
|
|
||||||
DPRINT1("ERR: NtGdiGetGlyphIndicesW with (cwc == 0) is UNIMPLEMENTED!\n");
|
|
||||||
return GDI_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
dc = DC_LockDc(hdc);
|
dc = DC_LockDc(hdc);
|
||||||
if (!dc)
|
if (!dc)
|
||||||
{
|
{
|
||||||
|
DPRINT1("!DC_LockDC\n");
|
||||||
return GDI_ERROR;
|
return GDI_ERROR;
|
||||||
}
|
}
|
||||||
pdcattr = dc->pdcattr;
|
pdcattr = dc->pdcattr;
|
||||||
|
@ -6929,29 +6924,43 @@ NtGdiGetGlyphIndicesW(
|
||||||
DC_UnlockDc(dc);
|
DC_UnlockDc(dc);
|
||||||
if (!TextObj)
|
if (!TextObj)
|
||||||
{
|
{
|
||||||
|
DPRINT1("!TextObj\n");
|
||||||
return GDI_ERROR;
|
return GDI_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
FontGDI = ObjToGDI(TextObj->Font, FONT);
|
FontGDI = ObjToGDI(TextObj->Font, FONT);
|
||||||
TEXTOBJ_UnlockText(TextObj);
|
TEXTOBJ_UnlockText(TextObj);
|
||||||
|
|
||||||
|
if (cwc == 0)
|
||||||
|
{
|
||||||
|
if (!UnSafepwc && !UnSafepgi)
|
||||||
|
{
|
||||||
|
Face = FontGDI->SharedFace->Face;
|
||||||
|
return Face->num_glyphs;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
|
goto ErrorRet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Buffer = ExAllocatePoolWithTag(PagedPool, cwc * sizeof(WORD), GDITAG_TEXT);
|
Buffer = ExAllocatePoolWithTag(PagedPool, cwc * sizeof(WORD), GDITAG_TEXT);
|
||||||
if (!Buffer)
|
if (!Buffer)
|
||||||
{
|
{
|
||||||
|
DPRINT1("ExAllocatePoolWithTag\n");
|
||||||
return GDI_ERROR;
|
return GDI_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get DefChar */
|
||||||
if (iMode & GGI_MARK_NONEXISTING_GLYPHS)
|
if (iMode & GGI_MARK_NONEXISTING_GLYPHS)
|
||||||
{
|
{
|
||||||
DefChar = 0xffff;
|
DefChar = 0xffff;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FT_Face Face = FontGDI->SharedFace->Face;
|
Face = FontGDI->SharedFace->Face;
|
||||||
if (FT_IS_SFNT(Face))
|
if (FT_IS_SFNT(Face))
|
||||||
{
|
{
|
||||||
TT_OS2 *pOS2;
|
|
||||||
|
|
||||||
IntLockFreeType();
|
IntLockFreeType();
|
||||||
pOS2 = FT_Get_Sfnt_Table(Face, ft_sfnt_os2);
|
pOS2 = FT_Get_Sfnt_Table(Face, ft_sfnt_os2);
|
||||||
DefChar = (pOS2->usDefaultChar ? get_glyph_index(Face, pOS2->usDefaultChar) : 0);
|
DefChar = (pOS2->usDefaultChar ? get_glyph_index(Face, pOS2->usDefaultChar) : 0);
|
||||||
|
@ -6960,10 +6969,17 @@ NtGdiGetGlyphIndicesW(
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Size = IntGetOutlineTextMetrics(FontGDI, 0, NULL);
|
Size = IntGetOutlineTextMetrics(FontGDI, 0, NULL);
|
||||||
|
if (!Size)
|
||||||
|
{
|
||||||
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
|
DPRINT1("!Size\n");
|
||||||
|
goto ErrorRet;
|
||||||
|
}
|
||||||
potm = ExAllocatePoolWithTag(PagedPool, Size, GDITAG_TEXT);
|
potm = ExAllocatePoolWithTag(PagedPool, Size, GDITAG_TEXT);
|
||||||
if (!potm)
|
if (!potm)
|
||||||
{
|
{
|
||||||
cwc = GDI_ERROR;
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
DPRINT1("!potm\n");
|
||||||
goto ErrorRet;
|
goto ErrorRet;
|
||||||
}
|
}
|
||||||
Size = IntGetOutlineTextMetrics(FontGDI, Size, potm);
|
Size = IntGetOutlineTextMetrics(FontGDI, Size, potm);
|
||||||
|
@ -6973,12 +6989,13 @@ NtGdiGetGlyphIndicesW(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Allocate for Safepwc */
|
||||||
pwcSize = cwc * sizeof(WCHAR);
|
pwcSize = cwc * sizeof(WCHAR);
|
||||||
Safepwc = ExAllocatePoolWithTag(PagedPool, pwcSize, GDITAG_TEXT);
|
Safepwc = ExAllocatePoolWithTag(PagedPool, pwcSize, GDITAG_TEXT);
|
||||||
|
|
||||||
if (!Safepwc)
|
if (!Safepwc)
|
||||||
{
|
{
|
||||||
Status = STATUS_NO_MEMORY;
|
Status = STATUS_NO_MEMORY;
|
||||||
|
DPRINT1("!Safepwc\n");
|
||||||
goto ErrorRet;
|
goto ErrorRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6993,10 +7010,14 @@ NtGdiGetGlyphIndicesW(
|
||||||
}
|
}
|
||||||
_SEH2_END;
|
_SEH2_END;
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status)) goto ErrorRet;
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Status: %08lX\n", Status);
|
||||||
|
goto ErrorRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get glyph indeces */
|
||||||
IntLockFreeType();
|
IntLockFreeType();
|
||||||
|
|
||||||
for (i = 0; i < cwc; i++)
|
for (i = 0; i < cwc; i++)
|
||||||
{
|
{
|
||||||
Buffer[i] = get_glyph_index(FontGDI->SharedFace->Face, Safepwc[i]);
|
Buffer[i] = get_glyph_index(FontGDI->SharedFace->Face, Safepwc[i]);
|
||||||
|
@ -7005,7 +7026,6 @@ NtGdiGetGlyphIndicesW(
|
||||||
Buffer[i] = DefChar;
|
Buffer[i] = DefChar;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IntUnLockFreeType();
|
IntUnLockFreeType();
|
||||||
|
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
|
@ -7020,12 +7040,18 @@ NtGdiGetGlyphIndicesW(
|
||||||
_SEH2_END;
|
_SEH2_END;
|
||||||
|
|
||||||
ErrorRet:
|
ErrorRet:
|
||||||
|
if (Buffer != NULL)
|
||||||
|
{
|
||||||
ExFreePoolWithTag(Buffer, GDITAG_TEXT);
|
ExFreePoolWithTag(Buffer, GDITAG_TEXT);
|
||||||
|
}
|
||||||
if (Safepwc != NULL)
|
if (Safepwc != NULL)
|
||||||
{
|
{
|
||||||
ExFreePoolWithTag(Safepwc, GDITAG_TEXT);
|
ExFreePoolWithTag(Safepwc, GDITAG_TEXT);
|
||||||
}
|
}
|
||||||
if (NT_SUCCESS(Status)) return cwc;
|
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
return cwc;
|
||||||
|
|
||||||
return GDI_ERROR;
|
return GDI_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue