... |
... |
@@ -41,7 +41,7 @@ |
41
|
41
|
|
42
|
42
|
/* NOTE: These are the table sizes calculated through the specs. */
|
43
|
43
|
#define BASE_GLYPH_SIZE 6U
|
44
|
|
-#define BASE_GLYPH_V1_RECORD_SIZE 6U
|
|
44
|
+#define BASE_GLYPH_PAINT_RECORD_SIZE 6U
|
45
|
45
|
#define LAYER_V1_LIST_PAINT_OFFSET_SIZE 4U
|
46
|
46
|
#define LAYER_V1_LIST_NUM_LAYERS_SIZE 4U
|
47
|
47
|
#define COLOR_STOP_SIZE 6U
|
... |
... |
@@ -83,6 +83,13 @@ |
83
|
83
|
FT_ULong num_layers_v1;
|
84
|
84
|
FT_Byte* layers_v1;
|
85
|
85
|
|
|
86
|
+ /*
|
|
87
|
+ * Paint tables start at the minimum of the end of the LayerList and the
|
|
88
|
+ * end of the BaseGlyphList. Record this location in a field here for
|
|
89
|
+ * safety checks when accessing paint tables.
|
|
90
|
+ */
|
|
91
|
+ FT_Byte* paints_start_v1;
|
|
92
|
+
|
86
|
93
|
/* The memory that backs up the `COLR' table. */
|
87
|
94
|
void* table;
|
88
|
95
|
FT_ULong table_size;
|
... |
... |
@@ -170,7 +177,7 @@ |
170
|
177
|
p1 = (FT_Byte*)( table + base_glyphs_offset_v1 );
|
171
|
178
|
num_base_glyphs_v1 = FT_PEEK_ULONG( p1 );
|
172
|
179
|
|
173
|
|
- if ( num_base_glyphs_v1 * BASE_GLYPH_V1_RECORD_SIZE >
|
|
180
|
+ if ( num_base_glyphs_v1 * BASE_GLYPH_PAINT_RECORD_SIZE >
|
174
|
181
|
table_size - base_glyphs_offset_v1 )
|
175
|
182
|
goto InvalidTable;
|
176
|
183
|
|
... |
... |
@@ -185,8 +192,18 @@ |
185
|
192
|
p1 = (FT_Byte*)( table + layer_offset_v1 );
|
186
|
193
|
num_layers_v1 = FT_PEEK_ULONG( p1 );
|
187
|
194
|
|
|
195
|
+ if ( num_layers_v1 * LAYER_V1_LIST_PAINT_OFFSET_SIZE >
|
|
196
|
+ table_size - layer_offset_v1 )
|
|
197
|
+ goto InvalidTable;
|
|
198
|
+
|
188
|
199
|
colr->num_layers_v1 = num_layers_v1;
|
189
|
200
|
colr->layers_v1 = p1;
|
|
201
|
+
|
|
202
|
+ colr->paints_start_v1 =
|
|
203
|
+ FT_MIN( colr->base_glyphs_v1 +
|
|
204
|
+ colr->num_base_glyphs_v1 * BASE_GLYPH_PAINT_RECORD_SIZE,
|
|
205
|
+ colr->layers_v1 +
|
|
206
|
+ colr->num_layers_v1 * LAYER_V1_LIST_PAINT_OFFSET_SIZE );
|
190
|
207
|
}
|
191
|
208
|
|
192
|
209
|
colr->base_glyphs = (FT_Byte*)( table + base_glyph_offset );
|
... |
... |
@@ -367,7 +384,7 @@ |
367
|
384
|
|
368
|
385
|
child_table_p = (FT_Byte*)( paint_base + paint_offset );
|
369
|
386
|
|
370
|
|
- if ( child_table_p < colr->base_glyphs_v1 ||
|
|
387
|
+ if ( child_table_p < colr->paints_start_v1 ||
|
371
|
388
|
child_table_p >= ( (FT_Byte*)colr->table + colr->table_size ) )
|
372
|
389
|
return 0;
|
373
|
390
|
|
... |
... |
@@ -388,7 +405,7 @@ |
388
|
405
|
if ( !p || !colr || !colr->table )
|
389
|
406
|
return 0;
|
390
|
407
|
|
391
|
|
- if ( p < colr->base_glyphs_v1 ||
|
|
408
|
+ if ( p < colr->paints_start_v1 ||
|
392
|
409
|
p >= ( (FT_Byte*)colr->table + colr->table_size ) )
|
393
|
410
|
return 0;
|
394
|
411
|
|
... |
... |
@@ -608,7 +625,7 @@ |
608
|
625
|
* skip `numBaseGlyphV1Records` by adding 4 to start binary search
|
609
|
626
|
* in the array of `BaseGlyphV1Record`.
|
610
|
627
|
*/
|
611
|
|
- FT_Byte *p = base_glyph_begin + 4 + mid * BASE_GLYPH_V1_RECORD_SIZE;
|
|
628
|
+ FT_Byte *p = base_glyph_begin + 4 + mid * BASE_GLYPH_PAINT_RECORD_SIZE;
|
612
|
629
|
|
613
|
630
|
FT_UShort gid = FT_NEXT_USHORT( p );
|
614
|
631
|
|
... |
... |
@@ -704,7 +721,7 @@ |
704
|
721
|
/*
|
705
|
722
|
* First ensure that p is within COLRv1.
|
706
|
723
|
*/
|
707
|
|
- if ( p < colr->base_glyphs_v1 ||
|
|
724
|
+ if ( p < colr->layers_v1 ||
|
708
|
725
|
p >= ( (FT_Byte*)colr->table + colr->table_size ) )
|
709
|
726
|
return 0;
|
710
|
727
|
|
... |
... |
@@ -731,7 +748,7 @@ |
731
|
748
|
|
732
|
749
|
p_paint = (FT_Byte*)( colr->layers_v1 + paint_offset );
|
733
|
750
|
|
734
|
|
- if ( p_paint < colr->base_glyphs_v1 ||
|
|
751
|
+ if ( p_paint < colr->paints_start_v1 ||
|
735
|
752
|
p_paint >= ( (FT_Byte*)colr->table + colr->table_size ) )
|
736
|
753
|
return 0;
|
737
|
754
|
|