[mm] Delay setting blend weight and design position.

Previously the `blend->weight_vector`, `blend->default_weight_vector`,
and `blend->design_pos` were set early to allocated but uninitialized
memory under the assumption that the memory would eventually be
initialized. However, it is possible that some of the required
keywords may not actually be present, leaving the memory uninitialized.
This is different from a present but invalid table, which would produce
an error.

Reported as
  https://bugs.chromium.org/p/chromium/issues/detail?id=1261762

* src/type1/t1load.c (t1_allocate_blend): Remove early allocation and
initialization.
(parse_blend_design_positions, parse_weight_vector): Parse into local
and assign to blend if valid.
(T1_Open_Face): Check that if a blend exists that it has the weight
vector and design positions.
This commit is contained in:
Ben Wagner 2021-10-21 09:55:28 -04:00 committed by Alexei Podtelezhnikov
parent b5e003f1f2
commit 65be4b2112
1 changed files with 50 additions and 32 deletions

View File

@ -117,6 +117,9 @@
goto Exit;
blend->num_default_design_vector = 0;
blend->weight_vector = NULL;
blend->default_weight_vector = NULL;
blend->design_pos[0] = NULL;
face->blend = blend;
}
@ -130,14 +133,11 @@
/* allocate the blend `private' and `font_info' dictionaries */
if ( FT_QNEW_ARRAY( blend->font_infos[1], num_designs ) ||
FT_QNEW_ARRAY( blend->privates [1], num_designs ) ||
FT_QNEW_ARRAY( blend->bboxes [1], num_designs ) ||
FT_QNEW_ARRAY( blend->weight_vector, num_designs * 2 ) )
if ( FT_QNEW_ARRAY( blend->font_infos[1], num_designs ) ||
FT_QNEW_ARRAY( blend->privates [1], num_designs ) ||
FT_QNEW_ARRAY( blend->bboxes [1], num_designs ) )
goto Exit;
blend->default_weight_vector = blend->weight_vector + num_designs;
blend->font_infos[0] = &face->type1.font_info;
blend->privates [0] = &face->type1.private_dict;
blend->bboxes [0] = &face->type1.font_bbox;
@ -164,21 +164,6 @@
blend->num_axis = num_axis;
}
/* allocate the blend design pos table if needed */
num_designs = blend->num_designs;
num_axis = blend->num_axis;
if ( num_designs && num_axis && blend->design_pos[0] == NULL )
{
FT_UInt n;
if ( FT_QNEW_ARRAY( blend->design_pos[0], num_designs * num_axis ) )
goto Exit;
for ( n = 1; n < num_designs; n++ )
blend->design_pos[n] = blend->design_pos[0] + num_axis * n;
}
Exit:
return error;
@ -872,13 +857,15 @@
{
T1_TokenRec design_tokens[T1_MAX_MM_DESIGNS];
FT_Int num_designs;
FT_Int num_axis;
FT_Int num_axis = 0; /* make compiler happy */
T1_Parser parser = &loader->parser;
FT_Memory memory = face->root.memory;
FT_Error error = FT_Err_Ok;
PS_Blend blend;
FT_Fixed* design_pos[T1_MAX_MM_DESIGNS];
design_pos[0] = NULL;
/* get the array of design tokens -- compute number of designs */
T1_ToTokenArray( parser, design_tokens,
T1_MAX_MM_DESIGNS, &num_designs );
@ -899,12 +886,10 @@
{
FT_Byte* old_cursor = parser->root.cursor;
FT_Byte* old_limit = parser->root.limit;
FT_Int n;
FT_Int n,nn;
PS_Blend blend;
blend = face->blend;
num_axis = 0; /* make compiler happy */
FT_TRACE4(( " [" ));
for ( n = 0; n < num_designs; n++ )
@ -937,7 +922,13 @@
(FT_UInt)num_axis );
if ( error )
goto Exit;
blend = face->blend;
/* allocate a blend design pos table */
if ( FT_QNEW_ARRAY( design_pos[0], num_designs * num_axis ) )
goto Exit;
for ( nn = 1; nn < num_designs; nn++ )
design_pos[nn] = design_pos[0] + num_axis * nn;
}
else if ( n_axis != num_axis )
{
@ -955,8 +946,8 @@
parser->root.cursor = token2->start;
parser->root.limit = token2->limit;
blend->design_pos[n][axis] = T1_ToFixed( parser, 0 );
FT_TRACE4(( " %f", (double)blend->design_pos[n][axis] / 65536 ));
design_pos[n][axis] = T1_ToFixed( parser, 0 );
FT_TRACE4(( " %f", (double)design_pos[n][axis] / 65536 ));
}
FT_TRACE4(( "]" )) ;
}
@ -965,9 +956,21 @@
loader->parser.root.cursor = old_cursor;
loader->parser.root.limit = old_limit;
/* a valid BlendDesignPosition has been parsed */
blend = face->blend;
if ( blend->design_pos[0] )
FT_FREE( blend->design_pos[0] );
for ( n = 0; n < num_designs; n++ )
{
blend->design_pos[n] = design_pos[n];
design_pos[n] = NULL;
}
}
Exit:
FT_FREE( design_pos[0] );
loader->parser.root.error = error;
}
@ -1088,6 +1091,7 @@
T1_TokenRec design_tokens[T1_MAX_MM_DESIGNS];
FT_Int num_designs;
FT_Error error = FT_Err_Ok;
FT_Memory memory = face->root.memory;
T1_Parser parser = &loader->parser;
PS_Blend blend = face->blend;
T1_Token token;
@ -1129,6 +1133,12 @@
goto Exit;
}
if ( !blend->weight_vector )
if ( FT_QNEW_ARRAY( blend->weight_vector, num_designs * 2 ) )
goto Exit;
blend->default_weight_vector = blend->weight_vector + num_designs;
old_cursor = parser->root.cursor;
old_limit = parser->root.limit;
@ -2578,7 +2588,15 @@
( !face->blend->num_designs || !face->blend->num_axis ) )
T1_Done_Blend( face );
/* another safety check */
/* the font may have no valid WeightVector */
if ( face->blend && !face->blend->weight_vector )
T1_Done_Blend( face );
/* the font may have no valid BlendDesignPositions */
if ( face->blend && !face->blend->design_pos[0] )
T1_Done_Blend( face );
/* the font may have no valid BlendDesignMap */
if ( face->blend )
{
FT_UInt i;