From 53894142c1d31c79642b1cd0180130666edf069a Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Thu, 23 Jan 2014 08:14:53 +0100 Subject: [PATCH] Fix Savannah bug #41309. * src/type1/t1load.c (t1_parse_font_matrix): Properly handle result of `T1_ToFixedArray'. * src/cid/cidload.c (cid_parse_font_matrix): Synchronize with `t1_parse_font_matrix'. * src/type42/t42parse.c (t42_parse_font_matrix): Synchronize with `t1_parse_font_matrix'. (t42_parse_encoding): Synchronize with `t1_parse_encoding'. * src/psaux/psobjs.c (ps_parser_load_field) , : Properly handle result of `ps_tofixedarray'. Cherry-pick: 8b281f83e8516535756f92dbf90940ac44bd45e1 --- src/cid/cidload.c | 18 ++++++++++++++---- src/psaux/psobjs.c | 4 +++- src/type1/t1load.c | 2 +- src/type42/t42parse.c | 48 +++++++++++++++++++++++++++++++++++++----------- 4 files changed, 55 insertions(+), 17 deletions(-) diff --git a/src/cid/cidload.c b/src/cid/cidload.c index 5f712bc..70b84fb 100644 --- a/src/cid/cidload.c +++ b/src/cid/cidload.c @@ -160,14 +160,25 @@ if ( parser->num_dict >= 0 && parser->num_dict < face->cid.num_dicts ) { + FT_Int result; + dict = face->cid.font_dicts + parser->num_dict; matrix = &dict->font_matrix; offset = &dict->font_offset; - (void)cid_parser_to_fixed_array( parser, 6, temp, 3 ); + result = cid_parser_to_fixed_array( parser, 6, temp, 3 ); + + if ( result < 6 ) + return CID_Err_Invalid_File_Format; temp_scale = FT_ABS( temp[3] ); + if ( temp_scale == 0 ) + { + FT_ERROR(( "cid_parse_font_matrix: invalid font matrix\n" )); + return CID_Err_Invalid_File_Format; + } + /* Set units per EM based on FontMatrix values. We set the value to */ /* `1000/temp_scale', because temp_scale was already multiplied by */ /* 1000 (in `t1_tofixed', from psobjs.c). */ @@ -182,7 +193,7 @@ temp[2] = FT_DivFix( temp[2], temp_scale ); temp[4] = FT_DivFix( temp[4], temp_scale ); temp[5] = FT_DivFix( temp[5], temp_scale ); - temp[3] = 0x10000L; + temp[3] = temp[3] < 0 ? -0x10000L : 0x10000L; } matrix->xx = temp[0]; @@ -195,8 +206,7 @@ offset->y = temp[5] >> 16; } - return CID_Err_Ok; /* this is a callback function; */ - /* we must return an error code */ + return FT_Err_Ok; } diff --git a/src/psaux/psobjs.c b/src/psaux/psobjs.c index 06df6e6..2089e24 100644 --- a/src/psaux/psobjs.c +++ b/src/psaux/psobjs.c @@ -847,6 +847,8 @@ /* first character must be a delimiter or a part of a number */ /* NB: `values' can be NULL if we just want to skip the */ /* array; in this case we ignore `max_values' */ + /* */ + /* return number of successfully parsed values */ static FT_Int ps_tofixedarray( FT_Byte* *acur, @@ -1193,7 +1195,7 @@ result = ps_tofixedarray( &cur, limit, 4, temp, 0 ); - if ( result < 0 ) + if ( result < 4 ) { FT_ERROR(( "ps_parser_load_field:" " expected four integers in bounding box\n" )); diff --git a/src/type1/t1load.c b/src/type1/t1load.c index 29b0763..bb783cd 100644 --- a/src/type1/t1load.c +++ b/src/type1/t1load.c @@ -1101,7 +1101,7 @@ result = T1_ToFixedArray( parser, 6, temp, 3 ); - if ( result < 0 ) + if ( result < 6 ) { parser->root.error = T1_Err_Invalid_File_Format; return; diff --git a/src/type42/t42parse.c b/src/type42/t42parse.c index 5d5f8f9..6d3a7bb 100644 --- a/src/type42/t42parse.c +++ b/src/type42/t42parse.c @@ -255,12 +255,26 @@ FT_Face root = (FT_Face)&face->root; FT_Fixed temp[6]; FT_Fixed temp_scale; + FT_Int result; - (void)T1_ToFixedArray( parser, 6, temp, 3 ); + result = T1_ToFixedArray( parser, 6, temp, 3 ); + + if ( result < 6 ) + { + parser->root.error = T42_Err_Invalid_File_Format; + return; + } temp_scale = FT_ABS( temp[3] ); + if ( temp_scale == 0 ) + { + FT_ERROR(( "t1_parse_font_matrix: invalid font matrix\n" )); + parser->root.error = T42_Err_Invalid_File_Format; + return; + } + /* Set Units per EM based on FontMatrix values. We set the value to */ /* 1000 / temp_scale, because temp_scale was already multiplied by */ /* 1000 (in t1_tofixed, from psobjs.c). */ @@ -276,7 +290,7 @@ temp[2] = FT_DivFix( temp[2], temp_scale ); temp[4] = FT_DivFix( temp[4], temp_scale ); temp[5] = FT_DivFix( temp[5], temp_scale ); - temp[3] = 0x10000L; + temp[3] = temp[3] < 0 ? -0x10000L : 0x10000L; } matrix->xx = temp[0]; @@ -315,7 +329,7 @@ if ( ft_isdigit( *cur ) || *cur == '[' ) { T1_Encoding encode = &face->type1.encoding; - FT_UInt count, n; + FT_Int count, n; PS_Table char_table = &loader->encoding_table; FT_Memory memory = parser->root.memory; FT_Error error; @@ -330,7 +344,7 @@ parser->root.cursor++; } else - count = (FT_UInt)T1_ToInt( parser ); + count = (FT_Int)T1_ToInt( parser ); T1_Skip_Spaces( parser ); if ( parser->root.cursor >= limit ) @@ -418,7 +432,7 @@ cur = parser->root.cursor; - if ( *cur == '/' && cur + 2 < limit && n < count ) + if ( cur + 2 < limit && *cur == '/' && n < count ) { FT_PtrDist len; @@ -427,6 +441,8 @@ parser->root.cursor = cur; T1_Skip_PS_Token( parser ); + if ( parser->root.cursor >= limit ) + return; if ( parser->root.error ) return; @@ -440,6 +456,19 @@ n++; } + else if ( only_immediates ) + { + /* Since the current position is not updated for */ + /* immediates-only mode we would get an infinite loop if */ + /* we don't do anything here. */ + /* */ + /* This encoding array is not valid according to the type1 */ + /* specification (it might be an encoding for a CID type1 */ + /* font, however), so we conclude that this font is NOT a */ + /* type1 font. */ + parser->root.error = T42_Err_Unknown_File_Format; + return; + } } else { @@ -451,8 +480,8 @@ T1_Skip_Spaces( parser ); } - face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY; - parser->root.cursor = cur; + face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY; + parser->root.cursor = cur; } /* Otherwise, we should have either `StandardEncoding', */ @@ -472,10 +501,7 @@ face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1; else - { - FT_ERROR(( "t42_parse_encoding: invalid token\n" )); - parser->root.error = T42_Err_Invalid_File_Format; - } + parser->root.error = T42_Err_Ignore; } } -- 2.2.0.rc0.207.ga3a616c