From 85a7fdf3c6f0403fc4c090161477e4f23d3a0cb8 Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Thu, 29 Aug 2013 21:03:05 +0200 Subject: [PATCH] [sfnt] Fix frame access while reading WOFF table directory. * src/sfnt/sfobjs.c (woff_open_font): Using single memory frame while reading the directory entries for the whole loop. --- ChangeLog | 9 ++++++++- include/freetype/internal/tttypes.h | 4 ++++ src/sfnt/sfobjs.c | 22 +++++++++++----------- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 066936a47..3ec7f0957 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,11 @@ -2013-08-28 Werner Lemberg +2013-08-28 Behdad Esfahbod + + [sfnt] Fix frame access while reading WOFF table directory. + + * src/sfnt/sfobjs.c (woff_open_font): Using single memory frame + while reading the directory entries for the whole loop. + +2013-08-29 Werner Lemberg Behdad Esfahbod Implement support for WOFF containers. diff --git a/include/freetype/internal/tttypes.h b/include/freetype/internal/tttypes.h index 9bb0e7bf6..f4da3f956 100644 --- a/include/freetype/internal/tttypes.h +++ b/include/freetype/internal/tttypes.h @@ -189,6 +189,10 @@ FT_BEGIN_HEADER /* */ /* CheckSum :: The table checksum. This value can be ignored. */ /* */ + /* OrigOffset :: The uncompressed table file offset. This value gets */ + /* computed while constructing the (uncompressed) SFNT */ + /* header. It is not contained in the WOFF file. */ + /* */ typedef struct WOFF_TableRec_ { FT_ULong Tag; /* table ID */ diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c index e3106234b..1cf1bf20b 100644 --- a/src/sfnt/sfobjs.c +++ b/src/sfnt/sfobjs.c @@ -371,7 +371,7 @@ *(p)++ = (v) >> 8; \ *(p)++ = (v) >> 0; \ \ - } while (0) + } while ( 0 ) static void @@ -409,7 +409,7 @@ /* Replace `face->root.stream' with a stream containing the extracted */ - /* sfnt of a woff font. */ + /* SFNT of a WOFF font. */ static FT_Error woff_open_font( FT_Stream stream, @@ -462,7 +462,7 @@ if ( FT_STREAM_READ_FIELDS( woff_header_fields, &woff ) ) return error; - /* Make sure we don't recurse back here or hit ttc code. */ + /* Make sure we don't recurse back here or hit TTC code. */ if ( woff.flavor == TTAG_wOFF || woff.flavor == TTAG_ttcf ) return FT_THROW( Invalid_Table ); @@ -520,23 +520,19 @@ " tag offset compLen origLen checksum\n" " -------------------------------------------\n" )); + if ( FT_FRAME_ENTER( 20L * woff.num_tables ) ) + goto Exit; + for ( nn = 0; nn < woff.num_tables; nn++ ) { WOFF_Table table = tables + nn; - - if ( FT_STREAM_SEEK( 44 + nn * 20 ) || - FT_FRAME_ENTER( 20L ) ) - goto Exit; - table->Tag = FT_GET_TAG4(); table->Offset = FT_GET_ULONG(); table->CompLength = FT_GET_ULONG(); table->OrigLength = FT_GET_ULONG(); table->CheckSum = FT_GET_ULONG(); - FT_FRAME_EXIT(); - FT_TRACE2(( " %c%c%c%c %08lx %08lx %08lx %08lx\n", (FT_Char)( table->Tag >> 24 ), (FT_Char)( table->Tag >> 16 ), @@ -549,6 +545,7 @@ if ( table->Tag <= old_tag ) { + FT_FRAME_EXIT(); error = FT_THROW( Invalid_Table ); goto Exit; } @@ -557,6 +554,8 @@ indices[nn] = table; } + FT_FRAME_EXIT(); + /* Sort by offset. */ ft_qsort( indices, @@ -699,7 +698,7 @@ face->root.stream, ( face->root.face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 ); - stream = face->root.stream = sfnt_stream; + face->root.stream = sfnt_stream; face->root.face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM; @@ -717,6 +716,7 @@ return error; } + #undef WRITE_BYTE #undef WRITE_USHORT #undef WRITE_ULONG