Author: tkreuzer
Date: Tue May 10 10:16:10 2011
New Revision: 51662
URL:
http://svn.reactos.org/svn/reactos?rev=51662&view=rev
Log:
[GDI FONT DRIVER]
- Fix size of the inverse lookup table
- Add more pointer checks to FtfdInitKerningPairs
- sort the FD_KERNINGPAIR array
Modified:
branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/font.c
branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/tttables.c
Modified: branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/font.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/GdiFontDriver/drivers…
==============================================================================
--- branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/font.c [iso-8859-1]
(original)
+++ branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/font.c [iso-8859-1] Tue May
10 10:16:10 2011
@@ -268,7 +268,8 @@
TRACE("FtfdInitGlyphSet()\n");
/* Allocate an array of WCHARs */
- pwcReverseTable = EngAllocMem(0, pface->ftface->num_glyphs, 'dftF');
+ cjSize = pface->cGlyphs * sizeof(WCHAR);
+ pwcReverseTable = EngAllocMem(0, cjSize, 'dftF');
if (!pwcReverseTable)
{
WARN("EngAllocMem() failed.\n");
@@ -303,6 +304,7 @@
for (i = 0, cRuns = 0; i < pface->cMappings && index; i++)
{
/* Create an entry in the reverse lookup table */
+ ASSERT(index < pface->cGlyphs);
pwcReverseTable[index] = wcCurrent;
/* Use index as glyph handle */
@@ -355,6 +357,8 @@
return FMT_UNKNOWN;
}
+static
+ULONG
FtfdGetFileFormat(
PFTFD_FILE pfile)
{
Modified: branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/tttables.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/GdiFontDriver/drivers…
==============================================================================
--- branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/tttables.c [iso-8859-1]
(original)
+++ branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/tttables.c [iso-8859-1] Tue
May 10 10:16:10 2011
@@ -407,6 +407,21 @@
return nPairs;
}
+INT
+__cdecl
+CompareKernPair(
+ FD_KERNINGPAIR *pkp1,
+ FD_KERNINGPAIR *pkp2)
+{
+ ULONG ul1, ul2;
+ ul1 = pkp1->wcFirst + 65536 * pkp1->wcSecond;
+ ul2 = pkp2->wcFirst + 65536 * pkp2->wcSecond;
+ if (ul1 < ul2) return -1;
+ if (ul1 > ul2) return 1;
+ return 0;
+}
+
+
VOID
NTAPI
FtfdInitKerningPairs(
@@ -415,33 +430,65 @@
PFTFD_FILE pfile = pface->pfile;
PTT_KERNING_TABLE pKernTable;
PTT_KERNING_SUBTABLE pSubTable;
- ULONG i, j, cPairs = 0;
+ ULONG cjSize, i, j, cPairs = 0;
FD_KERNINGPAIR *pKernPair;
HGLYPH hgLeft, hgRight;
-
-__debugbreak();
+ USHORT nTables;
+ ULONG_PTR ulLastAddress;
+
+//__debugbreak();
/* Get the kern table for the face */
pKernTable = FtfdFindTrueTypeTable(pfile->pvView,
- pfile->cjView,
- pface->iFace,
- 'nrek',
- NULL);
-
- if (!pKernTable || pKernTable->usVersion != 0)
- {
- TRACE("Couldn't find kerning table\n");
+ pfile->cjView,
+ pface->iFace,
+ 'nrek',
+ &cjSize);
+
+ if (!pKernTable || cjSize < sizeof(TT_KERNING_TABLE) ||
+ pKernTable->usVersion != 0)
+ {
+ TRACE("Couldn't find a valid kerning table\n");
return;
}
- // FIXME: do an overflow check
+ nTables = GETW(&pKernTable->nTables);
+ ulLastAddress = (ULONG_PTR)pKernTable + cjSize;
+
+
/* Loop all subtables */
pSubTable = &pKernTable->subtable;
- for (i = 0; i < pKernTable->nTables; i++)
- {
- /* Only type 0 is interesting */
+ for (i = 0; i < nTables; i++)
+ {
+ /* Check if the subtable is accessible */
+ if ((ULONG_PTR)pSubTable + sizeof(TT_KERNING_SUBTABLE) > ulLastAddress)
+ {
+ __debugbreak();
+ return;
+ }
+
+ /* Get the table size and check if its valid */
+ cjSize = GETW(&pSubTable->usLength);
+ if ((ULONG_PTR)pSubTable + cjSize > ulLastAddress)
+ {
+ __debugbreak();
+ return;
+ }
+
+ /* Check version */
if (GETW(&pSubTable->usVersion) == 0)
+ {
+ /* Get number of kerning pairs and check id its valid */
cPairs += GETW(&pSubTable->format0.nPairs);
+ if ((ULONG_PTR)&pSubTable->format0.akernpair[cPairs] >
ulLastAddress)
+ {
+ __debugbreak();
+ return;
+ }
+ }
+
+ /* Go to next subtable */
+ pSubTable = (PVOID)((PCHAR)pSubTable + cjSize);
}
if (cPairs == 0)
@@ -450,7 +497,7 @@
}
/* Allocate an FD_KERNINGPAIR array */
- pKernPair = EngAllocMem(0, (cPairs + 1) * sizeof(FD_KERNINGPAIR), '1234');
+ pKernPair = EngAllocMem(0, (cPairs + 1) * sizeof(FD_KERNINGPAIR), 'dftF');
pface->pKerningPairs = pKernPair;
if (!pKernPair)
{
@@ -460,34 +507,46 @@
/* Loop all subtables again */
pSubTable = &pKernTable->subtable;
- for (i = 0; i < pKernTable->nTables; i++)
- {
- /* Only type 0 is interesting */
- if (GETW(&pSubTable->usVersion) != 0) continue;
-
- /* Loop all kern pairs in the table */
- for (j = 0; j < GETW(&pSubTable->format0.nPairs); j++)
- {
- /* Get the glyph handles for the kerning */
- hgLeft = GETW(&pSubTable->format0.akernpair[j].usLeft);
- hgRight = GETW(&pSubTable->format0.akernpair[j].usRight);
-
- /* Windows wants WCHARs, convert them */
- pKernPair->wcFirst = pface->pwcReverseTable[hgLeft];
- pKernPair->wcSecond = pface->pwcReverseTable[hgLeft];
- pKernPair->fwdKern =
GETW(&pSubTable->format0.akernpair[j].fwdValue);
- pKernPair++;
+ for (i = 0; i < nTables; i++)
+ {
+ /* Check version */
+ if (GETW(&pSubTable->usVersion) == 0)
+ {
+ /* Loop all kern pairs in the table */
+ for (j = 0; j < GETW(&pSubTable->format0.nPairs); j++)
+ {
+ /* Get the glyph handles for the kerning */
+ hgLeft = GETW(&pSubTable->format0.akernpair[j].usLeft);
+ hgRight = GETW(&pSubTable->format0.akernpair[j].usRight);
+
+ /* Make sure we are inside the range */
+ if (hgLeft >= pface->cGlyphs) hgLeft = 0;
+ if (hgRight >= pface->cGlyphs) hgRight = 0;
+
+ /* Windows wants WCHARs, convert them */
+ pKernPair->wcFirst = pface->pwcReverseTable[hgLeft];
+ pKernPair->wcSecond = pface->pwcReverseTable[hgLeft];
+ pKernPair->fwdKern =
GETW(&pSubTable->format0.akernpair[j].fwdValue);
+ pKernPair++;
+ }
}
/* Go to next subtable */
- pSubTable = (PVOID)((PCHAR)pSubTable + pSubTable->usLength);
- }
-
- /* Zero terminate last FD_KERNINGPAIR entry */
+ pSubTable = (PVOID)((PCHAR)pSubTable + GETW(&pSubTable->usLength));
+ }
+
+ /* Zero terminate array */
pKernPair->wcFirst = 0;
pKernPair->wcSecond = 0;
pKernPair->fwdKern = 0;
+ /* Sort the array */
+ EngSort((PBYTE)pface->pKerningPairs,
+ sizeof(FD_KERNINGPAIR),
+ cPairs,
+ (SORTCOMP)CompareKernPair);
+
+ /* Set the number of kernpairs in the IFIMETRICS */
pface->ifiex.ifi.cKerningPairs = cPairs;
}