[sfnt] Guard individual `COLR` v1 paint field reads.
* src/sfnt/ttcolr.c (ENSURE_READ_BYTES): New macro. (read_paint): Use it – after the start pointer `p` has been checked for whether it allows reading the format byte, each successive paint table field read need to be bounds-checked before reading further values. Reported as https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52404
This commit is contained in:
parent
8493877e78
commit
04272824e0
|
@ -69,6 +69,11 @@
|
|||
&tt_driver_class && \
|
||||
((TT_Driver)FT_FACE_DRIVER( face ))->enable_variable_colrv1 )
|
||||
|
||||
#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_
|
||||
{
|
||||
|
@ -695,6 +700,7 @@
|
|||
(FT_PaintFormat_Internal)apaint->format ==
|
||||
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SOLID )
|
||||
{
|
||||
ENSURE_READ_BYTES( 4 );
|
||||
apaint->u.solid.color.palette_index = FT_NEXT_USHORT( p );
|
||||
apaint->u.solid.color.alpha = FT_NEXT_SHORT( p );
|
||||
|
||||
|
@ -703,6 +709,7 @@
|
|||
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SOLID &&
|
||||
VARIABLE_COLRV1_ENABLED )
|
||||
{
|
||||
ENSURE_READ_BYTES( 4 );
|
||||
var_index_base = FT_NEXT_ULONG( p );
|
||||
|
||||
if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 1,
|
||||
|
@ -720,6 +727,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;
|
||||
|
@ -746,9 +754,11 @@
|
|||
return 0;
|
||||
|
||||
/*
|
||||
* In order to support variations expose these as FT_Fixed 16.16 values so
|
||||
* that we can support fractional values after interpolation.
|
||||
* 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 ) );
|
||||
|
@ -759,6 +769,7 @@
|
|||
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
|
||||
if ( do_read_var && VARIABLE_COLRV1_ENABLED )
|
||||
{
|
||||
ENSURE_READ_BYTES( 4 );
|
||||
var_index_base = FT_NEXT_ULONG ( p );
|
||||
|
||||
if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 6,
|
||||
|
@ -792,11 +803,14 @@
|
|||
do_read_var ) )
|
||||
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 ) );
|
||||
|
||||
|
@ -812,6 +826,7 @@
|
|||
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
|
||||
if ( do_read_var && VARIABLE_COLRV1_ENABLED )
|
||||
{
|
||||
ENSURE_READ_BYTES( 4 );
|
||||
var_index_base = FT_NEXT_ULONG ( p );
|
||||
|
||||
if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 6,
|
||||
|
@ -846,6 +861,8 @@
|
|||
do_read_var) )
|
||||
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 =
|
||||
|
@ -859,6 +876,7 @@
|
|||
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
|
||||
if ( do_read_var && VARIABLE_COLRV1_ENABLED )
|
||||
{
|
||||
ENSURE_READ_BYTES( 4 );
|
||||
var_index_base = FT_NEXT_ULONG ( p );
|
||||
|
||||
if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 4,
|
||||
|
@ -882,6 +900,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 );
|
||||
|
@ -905,6 +924,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 );
|
||||
|
@ -917,6 +937,7 @@
|
|||
FT_COLR_PAINTFORMAT_INTERNAL_VAR_TRANSFORM &&
|
||||
VARIABLE_COLRV1_ENABLED )
|
||||
{
|
||||
ENSURE_READ_BYTES( 4 );
|
||||
var_index_base = FT_NEXT_ULONG( p );
|
||||
|
||||
if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 6,
|
||||
|
@ -944,6 +965,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 ) );
|
||||
|
||||
|
@ -952,6 +974,7 @@
|
|||
FT_COLR_PAINTFORMAT_INTERNAL_VAR_TRANSLATE &&
|
||||
VARIABLE_COLRV1_ENABLED )
|
||||
{
|
||||
ENSURE_READ_BYTES( 4 );
|
||||
var_index_base = FT_NEXT_ULONG( p );
|
||||
|
||||
if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 2,
|
||||
|
@ -976,6 +999,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. */
|
||||
|
@ -986,7 +1010,10 @@
|
|||
FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER ||
|
||||
(FT_PaintFormat_Internal)apaint->format ==
|
||||
FT_COLR_PAINTFORMAT_INTERNAL_VAR_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;
|
||||
|
||||
|
@ -1001,6 +1028,7 @@
|
|||
(FT_PaintFormat_Internal)apaint->format ==
|
||||
FT_COLR_PAINTFORMAT_INTERNAL_VAR_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 ) );
|
||||
}
|
||||
|
@ -1023,6 +1051,7 @@
|
|||
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM_CENTER ) &&
|
||||
VARIABLE_COLRV1_ENABLED )
|
||||
{
|
||||
ENSURE_READ_BYTES( 4 );
|
||||
var_index_base = FT_NEXT_ULONG( p );
|
||||
|
||||
if ( (FT_PaintFormat_Internal)apaint->format ==
|
||||
|
@ -1093,6 +1122,7 @@
|
|||
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 ==
|
||||
|
@ -1100,6 +1130,7 @@
|
|||
(FT_PaintFormat_Internal)apaint->format ==
|
||||
FT_COLR_PAINTFORMAT_INTERNAL_VAR_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 ) );
|
||||
}
|
||||
|
@ -1119,6 +1150,7 @@
|
|||
FT_UInt num_deltas = 0;
|
||||
|
||||
|
||||
ENSURE_READ_BYTES( 4 );
|
||||
var_index_base = FT_NEXT_ULONG( p );
|
||||
|
||||
if ( (FT_PaintFormat_Internal)apaint->format ==
|
||||
|
@ -1162,6 +1194,7 @@
|
|||
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 ) );
|
||||
|
||||
|
@ -1170,6 +1203,7 @@
|
|||
(FT_PaintFormat_Internal)apaint->format ==
|
||||
FT_COLR_PAINTFORMAT_INTERNAL_VAR_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 ) );
|
||||
}
|
||||
|
@ -1187,6 +1221,7 @@
|
|||
FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW_CENTER ) &&
|
||||
VARIABLE_COLRV1_ENABLED )
|
||||
{
|
||||
ENSURE_READ_BYTES( 4 );
|
||||
var_index_base = FT_NEXT_ULONG( p );
|
||||
|
||||
if ( (FT_PaintFormat_Internal)apaint->format ==
|
||||
|
@ -1228,6 +1263,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;
|
||||
|
|
Loading…
Reference in New Issue