Commit 112527dd44edc388137fdf6809ddeb9cf1a9c51f

Werner Lemberg 2022-01-22T11:45:30

[sfnt] Reject malformed SVG tables. * src/sfnt/ttsvg.c (SVG_TABLE_HEADER_SIZE, SVG_DOCUMENT_RECORD_SIZE, SVG_DOCUMENT_LIST_MINIMUM_SIZE, SVG_MINIMUM_SIZE): New macros. (tt_face_load_svg): Check offsets. Check table and record sizes. Reported as https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=43918

diff --git a/src/sfnt/ttsvg.c b/src/sfnt/ttsvg.c
index 75f8e36..781a88b 100644
--- a/src/sfnt/ttsvg.c
+++ b/src/sfnt/ttsvg.c
@@ -38,6 +38,14 @@
 #include "ttsvg.h"
 
 
+  /* NOTE: These table sizes are given by the specification. */
+#define SVG_TABLE_HEADER_SIZE           10U
+#define SVG_DOCUMENT_RECORD_SIZE        12U
+#define SVG_DOCUMENT_LIST_MINIMUM_SIZE  2U + SVG_DOCUMENT_RECORD_SIZE
+#define SVG_MINIMUM_SIZE                SVG_TABLE_HEADER_SIZE +        \
+                                        SVG_DOCUMENT_LIST_MINIMUM_SIZE
+
+
   typedef struct  Svg_
   {
     FT_UShort  version;                 /* table version (starting at 0)  */
@@ -79,6 +87,9 @@
     if ( error )
       goto NoSVG;
 
+    if ( table_size < SVG_MINIMUM_SIZE )
+      goto InvalidTable;
+
     if ( FT_FRAME_EXTRACT( table_size, table ) )
       goto NoSVG;
 
@@ -90,7 +101,9 @@
     svg->version            = FT_NEXT_USHORT( p );
     offsetToSVGDocumentList = FT_NEXT_ULONG( p );
 
-    if ( offsetToSVGDocumentList == 0 )
+    if ( offsetToSVGDocumentList < SVG_TABLE_HEADER_SIZE            ||
+         offsetToSVGDocumentList > table_size -
+                                     SVG_DOCUMENT_LIST_MINIMUM_SIZE )
       goto InvalidTable;
 
     svg->svg_doc_list = (FT_Byte*)( table + offsetToSVGDocumentList );
@@ -101,6 +114,10 @@
     FT_TRACE3(( "version: %d\n", svg->version ));
     FT_TRACE3(( "number of entries: %d\n", svg->num_entries ));
 
+    if ( offsetToSVGDocumentList +
+           svg->num_entries * SVG_DOCUMENT_RECORD_SIZE > table_size )
+      goto InvalidTable;
+
     svg->table      = table;
     svg->table_size = table_size;