summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDominik Röttsches <drott@chromium.org>2022-09-15 09:47:07 -0700
committerWerner Lemberg <wl@gnu.org>2022-09-16 18:55:24 +0200
commit33ceac2afc3608be2d12b3dece071a91e34c3062 (patch)
treeeeb5aac427495722d52357a63c92ec544af23008
parenta0d153645211075fd817d3e497c185827556f8c6 (diff)
downloadfreetype2-33ceac2afc3608be2d12b3dece071a91e34c3062.tar.gz
Reject 'COLR' table if version is 1 but header too small.
* src/sfnt/ttcolr.c (tt_face_load_colr): If the version is determined to be 1, then the table size has to be at least the size of the v1 header. Also, for peeking the number of base glyphs and entries in the layer list, ensure that the table is sufficiently long. Fixes #1179. Original patch by Sergey Temnikov.
-rw-r--r--src/sfnt/ttcolr.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/src/sfnt/ttcolr.c b/src/sfnt/ttcolr.c
index b43216181..5df31b9e0 100644
--- a/src/sfnt/ttcolr.c
+++ b/src/sfnt/ttcolr.c
@@ -57,7 +57,11 @@
#define LAYER_V1_LIST_NUM_LAYERS_SIZE 4U
#define COLOR_STOP_SIZE 6U
#define LAYER_SIZE 4U
-#define COLR_HEADER_SIZE 14U
+/* https://docs.microsoft.com/en-us/typography/opentype/spec/colr#colr-header */
+/* 3 * uint16 + 2 * Offset32 */
+#define COLRV0_HEADER_SIZE 14U
+/* COLRV0_HEADER_SIZE + 5 * Offset32 */
+#define COLRV1_HEADER_SIZE 34U
#define VARIABLE_COLRV1_ENABLED \
@@ -191,7 +195,7 @@
colr_offset_in_stream = FT_STREAM_POS();
#endif
- if ( table_size < COLR_HEADER_SIZE )
+ if ( table_size < COLRV0_HEADER_SIZE )
goto InvalidTable;
if ( FT_FRAME_EXTRACT( table_size, table ) )
@@ -225,9 +229,12 @@
if ( colr->version == 1 )
{
+ if ( table_size < COLRV1_HEADER_SIZE )
+ goto InvalidTable;
+
base_glyphs_offset_v1 = FT_NEXT_ULONG( p );
- if ( base_glyphs_offset_v1 >= table_size )
+ if ( base_glyphs_offset_v1 + 4 >= table_size )
goto InvalidTable;
p1 = (FT_Byte*)( table + base_glyphs_offset_v1 );
@@ -247,6 +254,9 @@
if ( layer_offset_v1 )
{
+ if ( layer_offset_v1 + 4 >= table_size )
+ goto InvalidTable;
+
p1 = (FT_Byte*)( table + layer_offset_v1 );
num_layers_v1 = FT_PEEK_ULONG( p1 );