ref: 65be4b21127e99ad652d4f8a1154679c4bea6677
parent: b5e003f1f2866940a9c5bb1632f79ed76161f839
author: Ben Wagner <bungeman@chromium.org>
date: Thu Oct 21 05:55:28 EDT 2021
[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.
--- a/src/type1/t1load.c
+++ b/src/type1/t1load.c
@@ -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;