Commit 12696dcf9bf614fef816bb768ed7c21b8eeee959

Werner Lemberg 2019-09-30T07:27:55

[woff2] Reject fonts without `head' table. Also fix memory deallocation in case of error. `head' problem reported as https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=17820 * src/sfnt/sfwoff2.c (reconstruct_glyf): Don't use `stream_close'. Abort if `head_table' is NULL. Don't free `transformed_buf' in case of error. (woff2_open_font): Don't set `uncompressed_buf' to NULL.

diff --git a/ChangeLog b/ChangeLog
index f0ffdd9..bbf2e1b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2019-09-30  Werner Lemberg  <wl@gnu.org>
+
+	[woff2] Reject fonts without `head' table.
+
+	Also fix memory deallocation in case of error.
+
+	`head' problem reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=17820
+
+	* src/sfnt/sfwoff2.c (reconstruct_glyf): Don't use `stream_close'.
+	Abort if `head_table' is NULL.
+	Don't free `transformed_buf' in case of error.
+	(woff2_open_font): Don't set `uncompressed_buf' to NULL.
+
 2019-09-29  Werner Lemberg  <wl@gnu.org>
 
 	[woff2] Fix compiler warnings.
diff --git a/src/sfnt/sfwoff2.c b/src/sfnt/sfwoff2.c
index ca602d1..2d85ef5 100644
--- a/src/sfnt/sfwoff2.c
+++ b/src/sfnt/sfwoff2.c
@@ -1478,6 +1478,8 @@
                     FT_ULong*     sfnt_size,
                     FT_Memory     memory )
   {
+    /* Memory management of `transformed_buf' is handled by the caller. */
+
     FT_Error   error       = FT_Err_Ok;
     FT_Stream  stream      = NULL;
     FT_Byte*   buf_cursor  = NULL;
@@ -1534,8 +1536,6 @@
     if ( FT_NEW( stream ) )
       return FT_THROW( Invalid_Table );
     FT_Stream_OpenMemory( stream, transformed_buf, transformed_buf_size );
-    stream->memory = memory;
-    stream->close  = stream_close;
 
     FT_ASSERT( FT_STREAM_POS() == 0 );
 
@@ -1675,12 +1675,15 @@
 
     /* Update `head' checkSumAdjustment. */
     head_table = find_table( indices, num_tables, TTAG_head );
-    if ( head_table )
+    if ( !head_table )
     {
-      if ( head_table->dst_length < 12 )
-        goto Fail;
+      FT_ERROR(( "`head' table is missing.\n" ));
+      goto Fail;
     }
 
+    if ( head_table->dst_length < 12 )
+      goto Fail;
+
     buf_cursor    = sfnt + head_table->dst_offset + 8;
     font_checksum = 0xB1B0AFBA - font_checksum;
 
@@ -1706,7 +1709,6 @@
     FT_FREE( table_entry );
     FT_Stream_Close( stream );
     FT_FREE( stream );
-    FT_FREE( transformed_buf );
 
     return error;
   }
@@ -2198,8 +2200,6 @@
                               &sfnt_size,
                               memory );
 
-    uncompressed_buf = NULL;
-
     if ( error )
       goto Exit;