From 2bf03eb7296dc7ebb97b24fe3957a2e33c9672df Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Fri, 20 Feb 2015 20:14:11 +0100 Subject: [PATCH] [cid] Fix signedness issues and emit some better error codes. * src/cid/cidgload.c, src/cid/cidload.h, src/cid/cidobjs.c, src/cid/cidparse.h: Apply. * src/cid/cidload.c: Apply. (parse_fd_array): Reject negative values for number of dictionaries. * src/cid/cidparse.c: Apply. (cid_parser_new): Reject negative values for hex data length. --- ChangeLog | 11 +++++++++++ src/cid/cidgload.c | 20 ++++++++++---------- src/cid/cidload.c | 22 ++++++++++++++-------- src/cid/cidload.h | 2 +- src/cid/cidobjs.c | 2 +- src/cid/cidparse.c | 17 ++++++++++++++--- src/cid/cidparse.h | 4 ++-- 7 files changed, 53 insertions(+), 25 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4cab1b32d..976c1651b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2015-02-20 Werner Lemberg + + [cid] Fix signedness issues and emit some better error codes. + + * src/cid/cidgload.c, src/cid/cidload.h, src/cid/cidobjs.c, + src/cid/cidparse.h: Apply. + * src/cid/cidload.c: Apply. + (parse_fd_array): Reject negative values for number of dictionaries. + * src/cid/cidparse.c: Apply. + (cid_parser_new): Reject negative values for hex data length. + 2015-02-20 Werner Lemberg [cff] Signedness fixes for new engine. diff --git a/src/cid/cidgload.c b/src/cid/cidgload.c index 07e2d6f09..bacf3dabc 100644 --- a/src/cid/cidgload.c +++ b/src/cid/cidgload.c @@ -44,7 +44,7 @@ CID_Face face = (CID_Face)decoder->builder.face; CID_FaceInfo cid = &face->cid; FT_Byte* p; - FT_UInt fd_select; + FT_ULong fd_select; FT_Stream stream = face->cid_stream; FT_Error error = FT_Err_Ok; FT_Byte* charstring = 0; @@ -75,11 +75,11 @@ goto Exit; p = (FT_Byte*)glyph_data.pointer; - fd_select = (FT_UInt)cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); + fd_select = cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); if ( glyph_data.length != 0 ) { - glyph_length = glyph_data.length - cid->fd_bytes; + glyph_length = (FT_ULong)( glyph_data.length - cid->fd_bytes ); (void)FT_ALLOC( charstring, glyph_length ); if ( !error ) ft_memcpy( charstring, glyph_data.pointer + cid->fd_bytes, @@ -99,7 +99,7 @@ /* For ordinary fonts read the CID font dictionary index */ /* and charstring offset from the CIDMap. */ { - FT_UInt entry_len = cid->fd_bytes + cid->gd_bytes; + FT_UInt entry_len = (FT_UInt)( cid->fd_bytes + cid->gd_bytes ); FT_ULong off1; @@ -109,13 +109,13 @@ goto Exit; p = (FT_Byte*)stream->cursor; - fd_select = (FT_UInt) cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); - off1 = (FT_ULong)cid_get_offset( &p, (FT_Byte)cid->gd_bytes ); + fd_select = cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); + off1 = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ); p += cid->fd_bytes; glyph_length = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ) - off1; FT_FRAME_EXIT(); - if ( fd_select >= (FT_UInt)cid->num_dicts ) + if ( fd_select >= (FT_ULong)cid->num_dicts ) { error = FT_THROW( Invalid_Offset ); goto Exit; @@ -133,7 +133,7 @@ { CID_FaceDict dict; CID_Subrs cid_subrs = face->subrs + fd_select; - FT_Int cs_offset; + FT_UInt cs_offset; /* Set up subrs */ @@ -151,7 +151,7 @@ /* Decode the charstring. */ /* Adjustment for seed bytes. */ - cs_offset = ( decoder->lenIV >= 0 ? decoder->lenIV : 0 ); + cs_offset = decoder->lenIV >= 0 ? (FT_UInt)decoder->lenIV : 0; /* Decrypt only if lenIV >= 0. */ if ( decoder->lenIV >= 0 ) @@ -159,7 +159,7 @@ error = decoder->funcs.parse_charstrings( decoder, charstring + cs_offset, - (FT_Int)glyph_length - cs_offset ); + glyph_length - cs_offset ); } FT_FREE( charstring ); diff --git a/src/cid/cidload.c b/src/cid/cidload.c index a82a82f93..460186eb0 100644 --- a/src/cid/cidload.c +++ b/src/cid/cidload.c @@ -38,7 +38,7 @@ /* read a single offset */ - FT_LOCAL_DEF( FT_Long ) + FT_LOCAL_DEF( FT_ULong ) cid_get_offset( FT_Byte* *start, FT_Byte offsize ) { @@ -53,7 +53,7 @@ } *start = p; - return (FT_Long)result; + return result; } @@ -222,6 +222,12 @@ num_dicts = cid_parser_to_int( parser ); + if ( num_dicts < 0 ) + { + FT_ERROR(( "parse_fd_array: invalid number of dictionaries\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } if ( !cid->font_dicts ) { @@ -231,7 +237,7 @@ if ( FT_NEW_ARRAY( cid->font_dicts, num_dicts ) ) goto Exit; - cid->num_dicts = (FT_UInt)num_dicts; + cid->num_dicts = num_dicts; /* don't forget to set a few defaults */ for ( n = 0; n < cid->num_dicts; n++ ) @@ -290,7 +296,7 @@ cid_parse_dict( CID_Face face, CID_Loader* loader, FT_Byte* base, - FT_Long size ) + FT_ULong size ) { CID_Parser* parser = &loader->parser; @@ -450,8 +456,8 @@ } /* read the subrmap's offsets */ - if ( FT_STREAM_SEEK( cid->data_offset + dict->subrmap_offset ) || - FT_FRAME_ENTER( ( num_subrs + 1 ) * dict->sd_bytes ) ) + if ( FT_STREAM_SEEK( cid->data_offset + dict->subrmap_offset ) || + FT_FRAME_ENTER( ( num_subrs + 1 ) * (FT_UInt)dict->sd_bytes ) ) goto Fail; p = (FT_Byte*)stream->cursor; @@ -500,7 +506,7 @@ } } - subr->num_subrs = num_subrs; + subr->num_subrs = (FT_Int)num_subrs; } Exit: @@ -546,7 +552,7 @@ static FT_Error cid_hex_to_binary( FT_Byte* data, - FT_Long data_len, + FT_ULong data_len, FT_ULong offset, CID_Face face ) { diff --git a/src/cid/cidload.h b/src/cid/cidload.h index fab41f9d7..d7776d2f8 100644 --- a/src/cid/cidload.h +++ b/src/cid/cidload.h @@ -36,7 +36,7 @@ FT_BEGIN_HEADER } CID_Loader; - FT_LOCAL( FT_Long ) + FT_LOCAL( FT_ULong ) cid_get_offset( FT_Byte** start, FT_Byte offsize ); diff --git a/src/cid/cidobjs.c b/src/cid/cidobjs.c index a63130da8..dc8667918 100644 --- a/src/cid/cidobjs.c +++ b/src/cid/cidobjs.c @@ -351,7 +351,7 @@ PS_FontInfo info = &cid->font_info; - cidface->num_glyphs = cid->cid_count; + cidface->num_glyphs = (FT_Long)cid->cid_count; cidface->num_charmaps = 0; cidface->face_index = face_index; diff --git a/src/cid/cidparse.c b/src/cid/cidparse.c index 4c8beff20..c27694977 100644 --- a/src/cid/cidparse.c +++ b/src/cid/cidparse.c @@ -86,13 +86,13 @@ /* `StartData' or `/sfnts' */ { FT_Byte buffer[256 + 10]; - FT_Long read_len = 256 + 10; /* same as signed FT_Stream->size */ + FT_ULong read_len = 256 + 10; FT_Byte* p = buffer; for ( offset = FT_STREAM_POS(); ; offset += 256 ) { - FT_Long stream_len; /* same as signed FT_Stream->size */ + FT_ULong stream_len; stream_len = stream->size - FT_STREAM_POS(); @@ -176,7 +176,18 @@ if ( cur[0] == 'S' && ft_strncmp( (char*)cur, "StartData", 9 ) == 0 ) { if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 ) - parser->binary_length = ft_atol( (const char *)arg2 ); + { + FT_Long tmp = ft_atol( (const char *)arg2 ); + + + if ( tmp < 0 ) + { + FT_ERROR(( "cid_parser_new: invalid length of hex data\n" )); + error = FT_THROW( Invalid_File_Format ); + } + else + parser->binary_length = (FT_ULong)tmp; + } goto Exit; } diff --git a/src/cid/cidparse.h b/src/cid/cidparse.h index 93318f2f4..f581bb43f 100644 --- a/src/cid/cidparse.h +++ b/src/cid/cidparse.h @@ -64,11 +64,11 @@ FT_BEGIN_HEADER FT_Stream stream; FT_Byte* postscript; - FT_Long postscript_len; + FT_ULong postscript_len; FT_ULong data_offset; - FT_Long binary_length; + FT_ULong binary_length; CID_FaceInfo cid; FT_Int num_dict;