From 2eaf0cf8fd6e7c290497fedb08134a89e7b49b1d Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Thu, 19 Mar 2015 17:34:42 +0400 Subject: Update bundled FreeType to 2.5.5 Removed everything, imported with help of import_from_tarball.sh script, and then added a pre-generated builds/unix/ftconfig.h Task-number: QTBUG-44648 Change-Id: Iea948e41f7761f1580382b3763d04c7a61383382 Reviewed-by: Lars Knoll --- src/3rdparty/freetype/src/type1/t1parse.c | 76 ++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 27 deletions(-) (limited to 'src/3rdparty/freetype/src/type1/t1parse.c') diff --git a/src/3rdparty/freetype/src/type1/t1parse.c b/src/3rdparty/freetype/src/type1/t1parse.c index 2a762279fd..ccf9f4cc56 100644 --- a/src/3rdparty/freetype/src/type1/t1parse.c +++ b/src/3rdparty/freetype/src/type1/t1parse.c @@ -4,7 +4,7 @@ /* */ /* Type 1 parser (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2008, 2009 by */ +/* Copyright 1996-2005, 2008, 2009, 2012-2014 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -119,10 +119,10 @@ if ( !FT_FRAME_ENTER( header_length ) ) { - error = T1_Err_Ok; + error = FT_Err_Ok; if ( ft_memcmp( stream->cursor, header_string, header_length ) != 0 ) - error = T1_Err_Unknown_File_Format; + error = FT_THROW( Unknown_File_Format ); FT_FRAME_EXIT(); } @@ -158,13 +158,13 @@ error = check_type1_format( stream, "%!PS-AdobeFont", 14 ); if ( error ) { - if ( error != T1_Err_Unknown_File_Format ) + if ( FT_ERR_NEQ( error, Unknown_File_Format ) ) goto Exit; error = check_type1_format( stream, "%!FontType", 10 ); if ( error ) { - FT_TRACE2(( "[not a Type1 font]\n" )); + FT_TRACE2(( " not a Type 1 font\n" )); goto Exit; } } @@ -263,7 +263,7 @@ { FT_Stream stream = parser->stream; FT_Memory memory = parser->root.memory; - FT_Error error = T1_Err_Ok; + FT_Error error = FT_Err_Ok; FT_ULong size; @@ -299,7 +299,7 @@ { FT_ERROR(( "T1_Get_Private_Dict:" " invalid private dictionary section\n" )); - error = T1_Err_Invalid_File_Format; + error = FT_THROW( Invalid_File_Format ); goto Fail; } @@ -313,7 +313,7 @@ error = read_pfb_tag( stream, &tag, &size ); if ( error || tag != 0x8002U ) { - error = T1_Err_Ok; + error = FT_Err_Ok; break; } @@ -332,9 +332,11 @@ /* dictionary block in the heap. */ /* first of all, look at the `eexec' keyword */ - FT_Byte* cur = parser->base_dict; - FT_Byte* limit = cur + parser->base_len; - FT_Byte c; + FT_Byte* cur = parser->base_dict; + FT_Byte* limit = cur + parser->base_len; + FT_Byte c; + FT_Pointer pos_lf; + FT_Bool test_cr; Again: @@ -342,7 +344,7 @@ { c = cur[0]; if ( c == 'e' && cur + 9 < limit ) /* 9 = 5 letters for `eexec' + */ - /* newline + 4 chars */ + /* whitespace + 4 chars */ { if ( cur[1] == 'e' && cur[2] == 'x' && @@ -355,7 +357,7 @@ { FT_ERROR(( "T1_Get_Private_Dict:" " could not find `eexec' keyword\n" )); - error = T1_Err_Invalid_File_Format; + error = FT_THROW( Invalid_File_Format ); goto Exit; } } @@ -364,7 +366,8 @@ /* or string (as e.g. in u003043t.gsf from ghostscript) */ parser->root.cursor = parser->base_dict; - parser->root.limit = cur + 9; + /* set limit to `eexec' + whitespace + 4 characters */ + parser->root.limit = cur + 10; cur = parser->root.cursor; limit = parser->root.limit; @@ -396,27 +399,37 @@ parser->root.limit = parser->base_dict + parser->base_len; T1_Skip_PS_Token( parser ); - cur = parser->root.cursor; + cur = parser->root.cursor; + limit = parser->root.limit; - /* according to the Type1 spec, the first cipher byte must not be */ + /* According to the Type 1 spec, the first cipher byte must not be */ /* an ASCII whitespace character code (blank, tab, carriage return */ /* or line feed). We have seen Type 1 fonts with two line feed */ /* characters... So skip now all whitespace character codes. */ - while ( cur < limit && - ( *cur == ' ' || - *cur == '\t' || - *cur == '\r' || - *cur == '\n' ) ) + /* */ + /* On the other hand, Adobe's Type 1 parser handles fonts just */ + /* fine that are violating this limitation, so we add a heuristic */ + /* test to stop at \r only if it is not used for EOL. */ + + pos_lf = ft_memchr( cur, '\n', limit - cur ); + test_cr = FT_BOOL( !pos_lf || + pos_lf > ft_memchr( cur, '\r', limit - cur ) ); + + while ( cur < limit && + ( *cur == ' ' || + *cur == '\t' || + (test_cr && *cur == '\r' ) || + *cur == '\n' ) ) ++cur; if ( cur >= limit ) { FT_ERROR(( "T1_Get_Private_Dict:" " `eexec' not properly terminated\n" )); - error = T1_Err_Invalid_File_Format; + error = FT_THROW( Invalid_File_Format ); goto Exit; } - size = parser->base_len - ( cur - parser->base_dict ); + size = (FT_ULong)( parser->base_len - ( cur - parser->base_dict ) ); if ( parser->in_memory ) { @@ -437,11 +450,12 @@ /* now determine whether the private dictionary is encoded in binary */ /* or hexadecimal ASCII format -- decode it accordingly */ - /* we need to access the next 4 bytes (after the final \r following */ - /* the `eexec' keyword); if they all are hexadecimal digits, then */ - /* we have a case of ASCII storage */ + /* we need to access the next 4 bytes (after the final whitespace */ + /* following the `eexec' keyword); if they all are hexadecimal */ + /* digits, then we have a case of ASCII storage */ - if ( ft_isxdigit( cur[0] ) && ft_isxdigit( cur[1] ) && + if ( cur + 3 < limit && + ft_isxdigit( cur[0] ) && ft_isxdigit( cur[1] ) && ft_isxdigit( cur[2] ) && ft_isxdigit( cur[3] ) ) { /* ASCII hexadecimal encoding */ @@ -467,6 +481,14 @@ /* we now decrypt the encoded binary private dictionary */ psaux->t1_decrypt( parser->private_dict, parser->private_len, 55665U ); + if ( parser->private_len < 4 ) + { + FT_ERROR(( "T1_Get_Private_Dict:" + " invalid private dictionary section\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + /* replace the four random bytes at the beginning with whitespace */ parser->private_dict[0] = ' '; parser->private_dict[1] = ' '; -- cgit v1.2.3