Commit 7f8a1edd3aa8586a1c1b220f9767e234adef2955

Dominik Röttsches 2021-04-16T12:35:29

[sfnt] Safeguard 'COLR' v1 layer extraction * src/sfnt/ttcolr.c (tt_face_get_paint_layers): Do not output layer pointer to iterator if it is outside the 'COLR' table. (read_paint): Do not attempt to read layers that are outside the table.

diff --git a/ChangeLog b/ChangeLog
index 6e11b2a..27144e8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2021-04-16  Dominik Röttsches  <drott@chromium.org>
+
+	[sfnt] Safeguard 'COLR' v1 layer extraction
+
+	* src/sfnt/ttcolr.c (tt_face_get_paint_layers): Do not output
+	layer pointer to iterator if it is outside the 'COLR' table.
+	(read_paint): Do not attempt to read layers that are outside the
+	table.
+
 2021-04-02  Ben Wagner  <bungeman@chromium.org>
 
 	[base] Complete `ft_glyphslot_clear`.
diff --git a/src/sfnt/ttcolr.c b/src/sfnt/ttcolr.c
index 2f1ae52..617ba93 100644
--- a/src/sfnt/ttcolr.c
+++ b/src/sfnt/ttcolr.c
@@ -388,6 +388,9 @@
     if ( !p || !colr || !colr->table )
       return 0;
 
+    if ( p < colr->base_glyphs_v1                          ||
+         p >= ( (FT_Byte*)colr->table + colr->table_size ) )
+
     apaint->format = FT_NEXT_BYTE( p );
 
     if ( apaint->format >= FT_COLR_PAINT_FORMAT_MAX )
@@ -678,6 +681,7 @@
   {
     FT_Byte*   p             = NULL;
     FT_Byte*   p_first_layer = NULL;
+    FT_Byte*   p_paint       = NULL;
     FT_UInt32  paint_offset;
 
     Colr*  colr;
@@ -716,8 +720,13 @@
       FT_NEXT_ULONG( p );
     opaque_paint->insert_root_transform =
       0;
-    opaque_paint->p =
-      (FT_Byte*)( colr->layers_v1 + paint_offset );
+
+    p_paint = (FT_Byte*)( colr->layers_v1 + paint_offset );
+
+    if ( p_paint < colr->base_glyphs_v1                          ||
+         p_paint >= ( (FT_Byte*)colr->table + colr->table_size ) )
+
+    opaque_paint->p = p_paint;
 
     iterator->p = p;