summaryrefslogtreecommitdiffstats
path: root/src/sfnt/ttload.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sfnt/ttload.c')
-rw-r--r--src/sfnt/ttload.c55
1 files changed, 49 insertions, 6 deletions
diff --git a/src/sfnt/ttload.c b/src/sfnt/ttload.c
index 0a3cd29..ad2975d 100644
--- a/src/sfnt/ttload.c
+++ b/src/sfnt/ttload.c
@@ -5,7 +5,7 @@
/* Load the basic TrueType tables, i.e., tables that can be either in */
/* TTF or OTF fonts (body). */
/* */
-/* Copyright 1996-2010, 2012, 2013 by */
+/* Copyright 1996-2015 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -207,10 +207,24 @@
}
/* we ignore invalid tables */
- if ( table.Offset + table.Length > stream->size )
- {
- FT_TRACE2(( "check_table_dir: table entry %d invalid\n", nn ));
+
+ if ( table.Offset > stream->size )
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
valid_entries++;
@@ -394,9 +408,38 @@
entry->Offset = FT_GET_ULONG();
entry->Length = FT_GET_ULONG();
- /* ignore invalid tables */
- if ( entry->Offset + entry->Length > stream->size )
+ /* ignore invalid tables that can't be sanitized */
+
+ if ( entry->Offset > stream->size )
continue;
+ else if ( entry->Length > stream->size - entry->Offset )
+ {
+ if ( entry->Tag == TTAG_hmtx ||
+ entry->Tag == TTAG_vmtx )
+ {
+#ifdef FT_DEBUG_LEVEL_TRACE
+ FT_ULong old_length = entry->Length;
+#endif
+
+
+ /* make metrics table length a multiple of 4 */
+ entry->Length = ( stream->size - entry->Offset ) & ~3U;
+
+ 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
{
FT_TRACE2(( " %c%c%c%c %08lx %08lx %08lx\n",