diff --git a/ChangeLog b/ChangeLog index ab5530f8e..e4ec61658 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2017-09-21 Werner Lemberg + + [truetype] Fix `mmvar' array pointers, part 2. + + The previous commit was incomplete. + + * src/truetype/ttgxvar.c: Properly initialize sub-array offsets for + `master' also. + 2017-09-21 Werner Lemberg [truetype] Fix `mmvar' array pointers. diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c index 8c56c56b6..461b230a0 100644 --- a/src/truetype/ttgxvar.c +++ b/src/truetype/ttgxvar.c @@ -1940,11 +1940,11 @@ TT_Get_MM_Var( TT_Face face, FT_MM_Var* *master ) { - FT_Stream stream = face->root.stream; - FT_Memory memory = face->root.memory; + FT_Stream stream = face->root.stream; + FT_Memory memory = face->root.memory; FT_ULong table_len; - FT_Error error = FT_Err_Ok; - FT_ULong fvar_start; + FT_Error error = FT_Err_Ok; + FT_ULong fvar_start = 0; FT_UInt i, j; FT_MM_Var* mmvar = NULL; FT_Fixed* next_coords; @@ -1954,10 +1954,20 @@ FT_Fixed* c; FT_Var_Named_Style* ns; GX_FVar_Head fvar_head; - FT_Bool usePsName; + FT_Bool usePsName = 0; FT_UInt num_instances; + FT_UInt num_axes; FT_UShort* axis_flags; + FT_Offset mmvar_size; + FT_Offset axis_flags_size; + FT_Offset axis_size; + FT_Offset namedstyle_size; + FT_Offset next_coords_size; + FT_Offset next_name_size; + + FT_Bool need_init; + static const FT_Frame_Field fvar_fields[] = { @@ -1995,16 +2005,10 @@ /* read the font data and set up the internal representation */ /* if not already done */ - if ( !face->blend ) + need_init = !face->blend; + + if ( need_init ) { - FT_Offset mmvar_size; - FT_Offset axis_flags_size; - FT_Offset axis_size; - FT_Offset namedstyle_size; - FT_Offset next_coords_size; - FT_Offset next_name_size; - - FT_TRACE2(( "FVAR " )); /* both `fvar' and `gvar' must be present */ @@ -2045,36 +2049,43 @@ if ( FT_NEW( face->blend ) ) goto Exit; - /* `num_instances' holds the number of all named instances, */ - /* including the default instance which might be missing */ - /* in fvar's table of named instances */ - num_instances = face->root.style_flags >> 16; + num_axes = fvar_head.axisCount; + } + else + num_axes = face->blend->num_axis; - /* prepare storage area for MM data; this cannot overflow */ - /* 32-bit arithmetic because of the size limits used in the */ - /* `fvar' table validity check in `sfnt_init_face' */ + /* `num_instances' holds the number of all named instances, */ + /* including the default instance which might be missing */ + /* in fvar's table of named instances */ + num_instances = face->root.style_flags >> 16; - /* the various `*_size' variables, which we also use as */ - /* offsets into the `mmlen' array, must be multiples of the */ - /* pointer size (except the last one); without such an */ - /* alignment there might be runtime errors due to */ - /* misaligned addresses */ + /* prepare storage area for MM data; this cannot overflow */ + /* 32-bit arithmetic because of the size limits used in the */ + /* `fvar' table validity check in `sfnt_init_face' */ + + /* the various `*_size' variables, which we also use as */ + /* offsets into the `mmlen' array, must be multiples of the */ + /* pointer size (except the last one); without such an */ + /* alignment there might be runtime errors due to */ + /* misaligned addresses */ #undef ALIGN_SIZE #define ALIGN_SIZE( n ) \ ( ( (n) + sizeof (void*) - 1 ) & ~( sizeof (void*) - 1 ) ) - mmvar_size = ALIGN_SIZE( sizeof ( FT_MM_Var ) ); - axis_flags_size = ALIGN_SIZE( fvar_head.axisCount * - sizeof ( FT_UShort ) ); - axis_size = ALIGN_SIZE( fvar_head.axisCount * - sizeof ( FT_Var_Axis ) ); - namedstyle_size = ALIGN_SIZE( num_instances * - sizeof ( FT_Var_Named_Style ) ); - next_coords_size = ALIGN_SIZE( num_instances * - fvar_head.axisCount * - sizeof ( FT_Fixed ) ); - next_name_size = fvar_head.axisCount * 5; + mmvar_size = ALIGN_SIZE( sizeof ( FT_MM_Var ) ); + axis_flags_size = ALIGN_SIZE( num_axes * + sizeof ( FT_UShort ) ); + axis_size = ALIGN_SIZE( num_axes * + sizeof ( FT_Var_Axis ) ); + namedstyle_size = ALIGN_SIZE( num_instances * + sizeof ( FT_Var_Named_Style ) ); + next_coords_size = ALIGN_SIZE( num_instances * + num_axes * + sizeof ( FT_Fixed ) ); + next_name_size = num_axes * 5; + if ( need_init ) + { face->blend->mmvar_len = mmvar_size + axis_flags_size + axis_size + @@ -2090,7 +2101,7 @@ /* the data gets filled in later on */ mmvar->num_axis = - fvar_head.axisCount; + num_axes; mmvar->num_designs = ~0U; /* meaningless in this context; each glyph */ /* may have a different number of designs */ @@ -2111,12 +2122,12 @@ for ( i = 0; i < num_instances; i++ ) { mmvar->namedstyle[i].coords = next_coords; - next_coords += fvar_head.axisCount; + next_coords += num_axes; } next_name = (FT_String*)( (char*)mmvar->namedstyle + namedstyle_size + next_coords_size ); - for ( i = 0; i < fvar_head.axisCount; i++ ) + for ( i = 0; i < num_axes; i++ ) { mmvar->axis[i].name = next_name; next_name += 5; @@ -2128,7 +2139,7 @@ goto Exit; a = mmvar->axis; - for ( i = 0; i < fvar_head.axisCount; i++ ) + for ( i = 0; i < num_axes; i++ ) { GX_FVar_Axis axis_rec; @@ -2178,7 +2189,7 @@ /* named instance coordinates are stored as design coordinates; */ /* we have to convert them to normalized coordinates also */ if ( FT_NEW_ARRAY( face->blend->normalized_stylecoords, - fvar_head.axisCount * num_instances ) ) + num_axes * num_instances ) ) goto Exit; if ( fvar_head.instanceCount && !face->blend->avar_loaded ) @@ -2198,14 +2209,14 @@ { /* PostScript names add 2 bytes to the instance record size */ if ( FT_FRAME_ENTER( ( usePsName ? 6L : 4L ) + - 4L * fvar_head.axisCount ) ) + 4L * num_axes ) ) goto Exit; ns->strid = FT_GET_USHORT(); (void) /* flags = */ FT_GET_USHORT(); c = ns->coords; - for ( j = 0; j < fvar_head.axisCount; j++, c++ ) + for ( j = 0; j < num_axes; j++, c++ ) *c = FT_GET_LONG(); /* valid psid values are 6, [256;32767], and 0xFFFF */ @@ -2214,11 +2225,8 @@ else ns->psid = 0xFFFF; - ft_var_to_normalized( face, - fvar_head.axisCount, - ns->coords, - nsc ); - nsc += fvar_head.axisCount; + ft_var_to_normalized( face, num_axes, ns->coords, nsc ); + nsc += num_axes; FT_FRAME_EXIT(); } @@ -2267,7 +2275,7 @@ a = mmvar->axis; c = ns->coords; - for ( j = 0; j < fvar_head.axisCount; j++, a++, c++ ) + for ( j = 0; j < num_axes; j++, a++, c++ ) *c = a->def; } } @@ -2288,23 +2296,24 @@ FT_MEM_COPY( mmvar, face->blend->mmvar, face->blend->mmvar_len ); axis_flags = - (FT_UShort*)&( mmvar[1] ); + (FT_UShort*)( (char*)mmvar + mmvar_size ); mmvar->axis = - (FT_Var_Axis*)&( axis_flags[mmvar->num_axis] ); + (FT_Var_Axis*)( (char*)axis_flags + axis_flags_size ); mmvar->namedstyle = - (FT_Var_Named_Style*)&( mmvar->axis[mmvar->num_axis] ); + (FT_Var_Named_Style*)( (char*)mmvar->axis+ axis_size ); - next_coords = - (FT_Fixed*)&( mmvar->namedstyle[mmvar->num_namedstyles] ); + next_coords = (FT_Fixed*)( (char*)mmvar->namedstyle + + namedstyle_size ); for ( n = 0; n < mmvar->num_namedstyles; n++ ) { mmvar->namedstyle[n].coords = next_coords; - next_coords += mmvar->num_axis; + next_coords += num_axes; } a = mmvar->axis; - next_name = (FT_String*)next_coords; - for ( n = 0; n < mmvar->num_axis; n++ ) + next_name = (FT_String*)( (char*)mmvar->namedstyle + + namedstyle_size + next_coords_size ); + for ( n = 0; n < num_axes; n++ ) { a->name = next_name;