зеркало из https://github.com/mozilla/pjs.git
Bug 487549. Do kern table sanity checks on downloaded fonts. r=roc
This commit is contained in:
Родитель
d5b82c2056
Коммит
84c9c97447
|
@ -0,0 +1,23 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Bad kern table - bug 487549</title>
|
||||||
|
<!--
|
||||||
|
The font used here has an invalid 'kern' table that will crash ATSUI
|
||||||
|
if we attempt to use it.
|
||||||
|
See https://bugzilla.mozilla.org/show_bug.cgi?id=487549
|
||||||
|
-->
|
||||||
|
<style>
|
||||||
|
@font-face {
|
||||||
|
font-family: bad-kern-font;
|
||||||
|
src: url(487549-bad_kern_table.ttf) format("truetype");
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: bad-kern-font;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
ABC abc 123
|
||||||
|
</body>
|
||||||
|
</html>
|
Двоичный файл не отображается.
|
@ -50,3 +50,4 @@ load 463307-1.html
|
||||||
load 467873-1.html
|
load 467873-1.html
|
||||||
load 470418-1.html
|
load 470418-1.html
|
||||||
skip-if(MOZ_WIDGET_TOOLKIT=="gtk2") load 441360.html # filed bug 455463 for gtk2
|
skip-if(MOZ_WIDGET_TOOLKIT=="gtk2") load 441360.html # filed bug 455463 for gtk2
|
||||||
|
load 487549-1.html
|
||||||
|
|
|
@ -654,6 +654,32 @@ struct OS2Table {
|
||||||
AutoSwap_PRUint16 usMaxContext;
|
AutoSwap_PRUint16 usMaxContext;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// old 'kern' table, supported on Windows
|
||||||
|
// see http://www.microsoft.com/typography/otspec/kern.htm
|
||||||
|
struct KernTableVersion0 {
|
||||||
|
AutoSwap_PRUint16 version; // 0x0000
|
||||||
|
AutoSwap_PRUint16 nTables;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct KernTableSubtableHeaderVersion0 {
|
||||||
|
AutoSwap_PRUint16 version;
|
||||||
|
AutoSwap_PRUint16 length;
|
||||||
|
AutoSwap_PRUint16 coverage;
|
||||||
|
};
|
||||||
|
|
||||||
|
// newer Mac-only 'kern' table, ignored by Windows
|
||||||
|
// see http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6kern.html
|
||||||
|
struct KernTableVersion1 {
|
||||||
|
AutoSwap_PRUint32 version; // 0x00010000
|
||||||
|
AutoSwap_PRUint32 nTables;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct KernTableSubtableHeaderVersion1 {
|
||||||
|
AutoSwap_PRUint32 length;
|
||||||
|
AutoSwap_PRUint16 coverage;
|
||||||
|
AutoSwap_PRUint16 tupleIndex;
|
||||||
|
};
|
||||||
|
|
||||||
static PRBool
|
static PRBool
|
||||||
IsValidSFNTVersion(PRUint32 version)
|
IsValidSFNTVersion(PRUint32 version)
|
||||||
{
|
{
|
||||||
|
@ -675,6 +701,44 @@ CopySwapUTF16(const PRUint16 *aInBuf, PRUint16 *aOutBuf, PRUint32 aLen)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PRBool
|
||||||
|
ValidateKernTable(const PRUint8 *aKernTable, PRUint32 aKernLength)
|
||||||
|
{
|
||||||
|
// -- kern table can cause crashes if invalid, so do some basic sanity-checking
|
||||||
|
const KernTableVersion0 *kernTable0 = reinterpret_cast<const KernTableVersion0*>(aKernTable);
|
||||||
|
if (aKernLength < sizeof(KernTableVersion0)) {
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
if (PRUint16(kernTable0->version) == 0) {
|
||||||
|
if (aKernLength < sizeof(KernTableVersion0) +
|
||||||
|
PRUint16(kernTable0->nTables) * sizeof(KernTableSubtableHeaderVersion0)) {
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
// at least the table is big enough to contain the subtable headers;
|
||||||
|
// we could go further and check the actual subtable sizes....
|
||||||
|
// for now, assume this is OK
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
const KernTableVersion1 *kernTable1 = reinterpret_cast<const KernTableVersion1*>(aKernTable);
|
||||||
|
if (aKernLength < sizeof(KernTableVersion1)) {
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
if (kernTable1->version == 0x00010000) {
|
||||||
|
if (aKernLength < sizeof(KernTableVersion1) +
|
||||||
|
kernTable1->nTables * sizeof(KernTableSubtableHeaderVersion1)) {
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
// at least the table is big enough to contain the subtable headers;
|
||||||
|
// we could go further and check the actual subtable sizes....
|
||||||
|
// for now, assume this is OK
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// neither the old Windows version nor the newer Apple one; refuse to use it
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
PRBool
|
PRBool
|
||||||
gfxFontUtils::ValidateSFNTHeaders(const PRUint8 *aFontData,
|
gfxFontUtils::ValidateSFNTHeaders(const PRUint8 *aFontData,
|
||||||
PRUint32 aFontDataLength,
|
PRUint32 aFontDataLength,
|
||||||
|
@ -702,8 +766,8 @@ gfxFontUtils::ValidateSFNTHeaders(const PRUint8 *aFontData,
|
||||||
|
|
||||||
// iterate through the table headers to find the head, name and OS/2 tables
|
// iterate through the table headers to find the head, name and OS/2 tables
|
||||||
PRBool foundHead = PR_FALSE, foundOS2 = PR_FALSE, foundName = PR_FALSE;
|
PRBool foundHead = PR_FALSE, foundOS2 = PR_FALSE, foundName = PR_FALSE;
|
||||||
PRBool foundGlyphs = PR_FALSE, foundCFF = PR_FALSE;
|
PRBool foundGlyphs = PR_FALSE, foundCFF = PR_FALSE, foundKern = PR_FALSE;
|
||||||
PRUint32 headOffset, headLen, nameOffset, nameLen;
|
PRUint32 headOffset, headLen, nameOffset, nameLen, kernOffset, kernLen;
|
||||||
PRUint32 i, numTables;
|
PRUint32 i, numTables;
|
||||||
|
|
||||||
numTables = sfntHeader->numTables;
|
numTables = sfntHeader->numTables;
|
||||||
|
@ -749,6 +813,12 @@ gfxFontUtils::ValidateSFNTHeaders(const PRUint8 *aFontData,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TRUETYPE_TAG('k','e','r','n'):
|
||||||
|
foundKern = PR_TRUE;
|
||||||
|
kernOffset = dirEntry->offset;
|
||||||
|
kernLen = dirEntry->length;
|
||||||
|
break;
|
||||||
|
|
||||||
case TRUETYPE_TAG('n','a','m','e'):
|
case TRUETYPE_TAG('n','a','m','e'):
|
||||||
foundName = PR_TRUE;
|
foundName = PR_TRUE;
|
||||||
nameOffset = dirEntry->offset;
|
nameOffset = dirEntry->offset;
|
||||||
|
@ -840,6 +910,14 @@ gfxFontUtils::ValidateSFNTHeaders(const PRUint8 *aFontData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -- sanity-check the kern table, if present (see bug 487549)
|
||||||
|
if (foundKern) {
|
||||||
|
if (!ValidateKernTable(aFontData + kernOffset, kernLen)) {
|
||||||
|
NS_WARNING("invalid font (kern table)");
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// everything seems consistent
|
// everything seems consistent
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче