[sfnt] Fix Savannah bug #44184.

* src/sfnt/ttload.c (check_table_dir, tt_face_load_font_dir): No
longer reject `htmx' and `vmtx' tables with invalid length but
sanitize them.
This commit is contained in:
Werner Lemberg 2015-02-07 09:47:23 +01:00
parent 9ada669a2c
commit 92359bd885
2 changed files with 52 additions and 9 deletions

View File

@ -1,3 +1,11 @@
2015-02-07 Werner Lemberg <wl@gnu.org>
[sfnt] Fix Savannah bug #44184.
* src/sfnt/ttload.c (check_table_dir, tt_face_load_font_dir): No
longer reject `htmx' and `vmtx' tables with invalid length but
sanitize them.
2015-02-06 Jon Anderson <jon@websupergoo.com> 2015-02-06 Jon Anderson <jon@websupergoo.com>
[truetype] Fix regression in the incremental glyph loader. [truetype] Fix regression in the incremental glyph loader.

View File

@ -208,12 +208,23 @@
/* we ignore invalid tables */ /* we ignore invalid tables */
/* table.Offset + table.Length > stream->size ? */ if ( table.Offset > stream->size )
if ( table.Length > stream->size ||
table.Offset > stream->size - table.Length )
{
FT_TRACE2(( "check_table_dir: table entry %d invalid\n", nn ));
continue; continue;
else if ( table.Length > stream->size - table.Offset )
{
/* Some tables have such a simple structure that clipping its */
/* contents is harmless. This also makes FreeType less sensitive */
/* to invalid table lengths (which programs like Acroread seem to */
/* ignore in general). */
if ( table.Tag == TTAG_hmtx ||
table.Tag == TTAG_vmtx )
valid_entries++;
else
{
FT_TRACE2(( "check_table_dir: table entry %d invalid\n", nn ));
continue;
}
} }
else else
valid_entries++; valid_entries++;
@ -397,12 +408,36 @@
entry->Offset = FT_GET_ULONG(); entry->Offset = FT_GET_ULONG();
entry->Length = FT_GET_ULONG(); entry->Length = FT_GET_ULONG();
/* ignore invalid tables */ /* ignore invalid tables that can't be sanitized */
/* entry->Offset + entry->Length > stream->size ? */ if ( entry->Offset > stream->size )
if ( entry->Length > stream->size ||
entry->Offset > stream->size - entry->Length )
continue; continue;
else if ( entry->Length > stream->size - entry->Offset )
{
if ( entry->Tag == TTAG_hmtx ||
entry->Tag == TTAG_vmtx )
{
FT_ULong old_length = entry->Length;
/* make metrics table length a multiple of 4 */
entry->Length = ( stream->size - entry->Offset ) & ~3;
FT_TRACE2(( " %c%c%c%c %08lx %08lx %08lx"
" (sanitized; original length %08lx)\n",
(FT_Char)( entry->Tag >> 24 ),
(FT_Char)( entry->Tag >> 16 ),
(FT_Char)( entry->Tag >> 8 ),
(FT_Char)( entry->Tag ),
entry->Offset,
entry->Length,
entry->CheckSum,
old_length ));
entry++;
}
else
continue;
}
else else
{ {
FT_TRACE2(( " %c%c%c%c %08lx %08lx %08lx\n", FT_TRACE2(( " %c%c%c%c %08lx %08lx %08lx\n",