[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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
diff --git a/ChangeLog b/ChangeLog
index 066936a..3ec7f09 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,11 @@
-2013-08-28 Werner Lemberg <wl@gnu.org>
+2013-08-28 Behdad Esfahbod <behdad@google.com>
+
+ [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 <wl@gnu.org>
Behdad Esfahbod <behdad@google.com>
Implement support for WOFF containers.
diff --git a/include/freetype/internal/tttypes.h b/include/freetype/internal/tttypes.h
index 9bb0e7b..f4da3f9 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 e310623..1cf1bf2 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