diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-02-22 18:22:08 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-02-22 18:22:08 +0000 |
commit | 6711d4064b217e4d28a0c69c00ef77116b20ce58 (patch) | |
tree | 590cb03cda519182d3a4460c62edd32e98438916 | |
parent | a4359e53674321de54a44ea785133cc7b23e203a (diff) | |
parent | d8fac342f6834f7f9704971aba626b092a7e7d59 (diff) | |
download | freetype-android-platform-13.0.0_r6.tar.gz |
Snap for 9635940 from d8fac342f6834f7f9704971aba626b092a7e7d59 to tm-platform-releaseandroid-platform-13.0.0_r7android-platform-13.0.0_r6
Change-Id: I26988f19e4eaa2e250f83c0945ee4a071a690de7
-rw-r--r-- | src/sfnt/ttcolr.c | 70 |
1 files changed, 55 insertions, 15 deletions
diff --git a/src/sfnt/ttcolr.c b/src/sfnt/ttcolr.c index 8f5cc8bcd..ec972a8f4 100644 --- a/src/sfnt/ttcolr.c +++ b/src/sfnt/ttcolr.c @@ -49,6 +49,11 @@ #define LAYER_SIZE 4U #define COLR_HEADER_SIZE 14U +#define ENSURE_READ_BYTES( byte_size ) \ + if ( p < colr->paints_start_v1 || \ + p > (FT_Byte*)colr->table + colr->table_size - byte_size ) \ + return 0; + typedef enum FT_PaintFormat_Internal_ { @@ -372,13 +377,16 @@ static FT_Bool - read_color_line( FT_Byte* color_line_p, - FT_ColorLine *colorline ) + read_color_line( Colr* colr, + FT_Byte* color_line_p, + FT_ColorLine* colorline) { FT_Byte* p = color_line_p; FT_PaintExtend paint_extend; + ENSURE_READ_BYTES( 3 ); + paint_extend = (FT_PaintExtend)FT_NEXT_BYTE( p ); if ( paint_extend > FT_COLR_PAINT_EXTEND_REFLECT ) return 0; @@ -477,6 +485,7 @@ else if ( apaint->format == FT_COLR_PAINTFORMAT_SOLID ) { + ENSURE_READ_BYTES( 4 ); apaint->u.solid.color.palette_index = FT_NEXT_USHORT( p ); apaint->u.solid.color.alpha = FT_NEXT_SHORT( p ); @@ -485,6 +494,7 @@ else if ( apaint->format == FT_COLR_PAINTFORMAT_COLR_GLYPH ) { + ENSURE_READ_BYTES(2); apaint->u.colr_glyph.glyphID = FT_NEXT_USHORT( p ); return 1; @@ -502,14 +512,16 @@ if ( apaint->format == FT_COLR_PAINTFORMAT_LINEAR_GRADIENT ) { - if ( !read_color_line( child_table_p, - &apaint->u.linear_gradient.colorline ) ) + if ( !read_color_line( colr, + child_table_p, + &apaint->u.linear_gradient.colorline) ) return 0; /* * In order to support variations expose these as FT_Fixed 16.16 values so * that we can support fractional values after interpolation. */ + ENSURE_READ_BYTES( 12 ); apaint->u.linear_gradient.p0.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); apaint->u.linear_gradient.p0.y = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); apaint->u.linear_gradient.p1.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); @@ -522,10 +534,21 @@ else if ( apaint->format == FT_COLR_PAINTFORMAT_RADIAL_GRADIENT ) { - if ( !read_color_line( child_table_p, - &apaint->u.radial_gradient.colorline ) ) + FT_Pos tmp; + + + if ( !read_color_line( colr, + child_table_p, + &apaint->u.radial_gradient.colorline) ) return 0; + /* In the OpenType specification, `r0` and `r1` are defined as */ + /* `UFWORD`. Since FreeType doesn't have a corresponding 16.16 */ + /* format we convert to `FWORD` and replace negative values with */ + /* (32bit) `FT_INT_MAX`. */ + + ENSURE_READ_BYTES( 12 ); + apaint->u.radial_gradient.c0.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); apaint->u.radial_gradient.c0.y = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); @@ -541,10 +564,13 @@ else if ( apaint->format == FT_COLR_PAINTFORMAT_SWEEP_GRADIENT ) { - if ( !read_color_line( child_table_p, - &apaint->u.sweep_gradient.colorline ) ) + if ( !read_color_line( colr, + child_table_p, + &apaint->u.sweep_gradient.colorline) ) return 0; + ENSURE_READ_BYTES( 8 ); + apaint->u.sweep_gradient.center.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); apaint->u.sweep_gradient.center.y = @@ -560,6 +586,7 @@ if ( apaint->format == FT_COLR_PAINTFORMAT_GLYPH ) { + ENSURE_READ_BYTES( 2 ); apaint->u.glyph.paint.p = child_table_p; apaint->u.glyph.paint.insert_root_transform = 0; apaint->u.glyph.glyphID = FT_NEXT_USHORT( p ); @@ -581,6 +608,7 @@ * The following matrix coefficients are encoded as * OpenType 16.16 fixed-point values. */ + ENSURE_READ_BYTES( 24 ); apaint->u.transform.affine.xx = FT_NEXT_LONG( p ); apaint->u.transform.affine.yx = FT_NEXT_LONG( p ); apaint->u.transform.affine.xy = FT_NEXT_LONG( p ); @@ -596,6 +624,7 @@ apaint->u.translate.paint.p = child_table_p; apaint->u.translate.paint.insert_root_transform = 0; + ENSURE_READ_BYTES( 4 ); apaint->u.translate.dx = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); apaint->u.translate.dy = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); @@ -615,6 +644,7 @@ apaint->u.scale.paint.insert_root_transform = 0; /* All scale paints get at least one scale value. */ + ENSURE_READ_BYTES( 2 ); apaint->u.scale.scale_x = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) ); /* Non-uniform ones read an extra y value. */ @@ -622,7 +652,10 @@ FT_COLR_PAINTFORMAT_SCALE || (FT_PaintFormat_Internal)apaint->format == FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER ) + { + ENSURE_READ_BYTES( 2 ); apaint->u.scale.scale_y = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) ); + } else apaint->u.scale.scale_y = apaint->u.scale.scale_x; @@ -633,6 +666,7 @@ (FT_PaintFormat_Internal)apaint->format == FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM_CENTER ) { + ENSURE_READ_BYTES( 4 ); apaint->u.scale.center_x = INT_TO_FIXED( FT_NEXT_SHORT ( p ) ); apaint->u.scale.center_y = INT_TO_FIXED( FT_NEXT_SHORT ( p ) ); } @@ -656,11 +690,13 @@ apaint->u.rotate.paint.p = child_table_p; apaint->u.rotate.paint.insert_root_transform = 0; + ENSURE_READ_BYTES( 2 ); apaint->u.rotate.angle = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) ); if ( (FT_PaintFormat_Internal)apaint->format == FT_COLR_PAINTFORMAT_INTERNAL_ROTATE_CENTER ) { + ENSURE_READ_BYTES( 4 ); apaint->u.rotate.center_x = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); apaint->u.rotate.center_y = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); } @@ -682,12 +718,14 @@ apaint->u.skew.paint.p = child_table_p; apaint->u.skew.paint.insert_root_transform = 0; + ENSURE_READ_BYTES( 4 ); apaint->u.skew.x_skew_angle = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) ); apaint->u.skew.y_skew_angle = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) ); if ( (FT_PaintFormat_Internal)apaint->format == FT_COLR_PAINTFORMAT_INTERNAL_SKEW_CENTER ) { + ENSURE_READ_BYTES( 4 ); apaint->u.skew.center_x = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); apaint->u.skew.center_y = INT_TO_FIXED( FT_NEXT_SHORT( p ) ); } @@ -710,6 +748,7 @@ apaint->u.composite.source_paint.p = child_table_p; apaint->u.composite.source_paint.insert_root_transform = 0; + ENSURE_READ_BYTES( 1 ); composite_mode = FT_NEXT_BYTE( p ); if ( composite_mode >= FT_COLR_COMPOSITE_MAX ) return 0; @@ -955,13 +994,6 @@ p = iterator->p; /* - * First ensure that p is within COLRv1. - */ - if ( p < colr->layers_v1 || - p >= ( (FT_Byte*)colr->table + colr->table_size ) ) - return 0; - - /* * Do a cursor sanity check of the iterator. Counting backwards from * where it stands, we need to end up at a position after the beginning * of the `LayerV1List` table and not after the end of the @@ -977,6 +1009,14 @@ colr->num_layers_v1 * LAYER_V1_LIST_PAINT_OFFSET_SIZE ) ) return 0; + /* + * Before reading, ensure that `p` is within 'COLR' v1 and we can read a + * 4-byte ULONG. + */ + if ( p < colr->layers_v1 || + p > ( (FT_Byte*)colr->table + colr->table_size - 4 ) ) + return 0; + paint_offset = FT_NEXT_ULONG( p ); opaque_paint->insert_root_transform = |