From 658f530ef54d973b0741df73b0939d906f0f68a1 Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Mon, 15 Feb 2016 14:28:28 +0100 Subject: [PATCH] [cff] Correctly trace SIDs that contain NULL bytes. We need this to properly trace Multiple Master CFFs, which contain two SIDs that are charstrings. This commit makes FreeType also show the last SID, omitted previously due to a bug. * src/cff/cfftypes.h (CFF_FontRec): Add `string_pool_size' field. * src/cff/cffload.c (cff_index_get_pointers): Add argument to return the pool size. Update all callers. * src/cff/cffobjs.c (cff_face_init) [FT_DEBUG_LEVEL_TRACE]: Directly access `cff->strings' to display the non-default strings. --- ChangeLog | 19 +++++++++++++++++++ src/cff/cffload.c | 30 ++++++++++++++++++------------ src/cff/cffobjs.c | 37 +++++++++++++++++++++++++++++++++++-- src/cff/cfftypes.h | 1 + 4 files changed, 73 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 648cb3d89..b8847559a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2016-02-15 Werner Lemberg + + [cff] Correctly trace SIDs that contain NULL bytes. + + We need this to properly trace Multiple Master CFFs, which contain + two SIDs that are charstrings. + + This commit makes FreeType also show the last SID, omitted + previously due to a bug. + + * src/cff/cfftypes.h (CFF_FontRec): Add `string_pool_size' field. + + * src/cff/cffload.c (cff_index_get_pointers): Add argument to return + the pool size. + Update all callers. + + * src/cff/cffobjs.c (cff_face_init) [FT_DEBUG_LEVEL_TRACE]: Directly + access `cff->strings' to display the non-default strings. + 2016-02-14 Werner Lemberg * src/base/fthash.c: Include FT_INTERNAL_MEMORY_H. diff --git a/src/cff/cffload.c b/src/cff/cffload.c index 2ea4e3700..920f10b68 100644 --- a/src/cff/cffload.c +++ b/src/cff/cffload.c @@ -382,13 +382,15 @@ static FT_Error cff_index_get_pointers( CFF_Index idx, FT_Byte*** table, - FT_Byte** pool ) + FT_Byte** pool, + FT_ULong* pool_size ) { FT_Error error = FT_Err_Ok; FT_Memory memory = idx->stream->memory; FT_Byte** t = NULL; FT_Byte* new_bytes = NULL; + FT_ULong new_size; *table = NULL; @@ -400,10 +402,11 @@ goto Exit; } - if ( idx->count > 0 && - !FT_NEW_ARRAY( t, idx->count + 1 ) && - ( !pool || !FT_ALLOC( new_bytes, - idx->data_size + idx->count ) ) ) + new_size = idx->data_size + idx->count; + + if ( idx->count > 0 && + !FT_NEW_ARRAY( t, idx->count + 1 ) && + ( !pool || !FT_ALLOC( new_bytes, new_size ) ) ) { FT_ULong n, cur_offset; FT_ULong extra = 0; @@ -459,6 +462,8 @@ if ( pool ) *pool = new_bytes; + if ( pool_size ) + *pool_size = new_size; } Exit: @@ -1408,7 +1413,7 @@ goto Exit; error = cff_index_get_pointers( &font->local_subrs_index, - &font->local_subrs, NULL ); + &font->local_subrs, NULL, NULL ); if ( error ) goto Exit; } @@ -1486,16 +1491,17 @@ /* read the name, top dict, string and global subrs index */ if ( FT_SET_ERROR( cff_index_init( &font->name_index, - stream, 0 ) ) || + stream, 0 ) ) || FT_SET_ERROR( cff_index_init( &font->font_dict_index, - stream, 0 ) ) || + stream, 0 ) ) || FT_SET_ERROR( cff_index_init( &string_index, - stream, 1 ) ) || + stream, 1 ) ) || FT_SET_ERROR( cff_index_init( &font->global_subrs_index, - stream, 1 ) ) || + stream, 1 ) ) || FT_SET_ERROR( cff_index_get_pointers( &string_index, &font->strings, - &font->string_pool ) ) ) + &font->string_pool, + &font->string_pool_size ) ) ) goto Exit; font->num_strings = string_index.count; @@ -1622,7 +1628,7 @@ font->num_glyphs = font->charstrings_index.count; error = cff_index_get_pointers( &font->global_subrs_index, - &font->global_subrs, NULL ); + &font->global_subrs, NULL, NULL ); if ( error ) goto Exit; diff --git a/src/cff/cffobjs.c b/src/cff/cffobjs.c index e22ae82bc..52fd0ec59 100644 --- a/src/cff/cffobjs.c +++ b/src/cff/cffobjs.c @@ -625,11 +625,44 @@ FT_TRACE4(( "SIDs\n" )); /* dump string index, including default strings for convenience */ - for ( idx = 0; idx < cff->num_strings + 390; idx++ ) + for ( idx = 0; idx <= 390; idx++ ) { s = cff_index_get_sid_string( cff, idx ); if ( s ) - FT_TRACE4((" %5d %s\n", idx, s )); + FT_TRACE4(( " %5d %s\n", idx, s )); + } + + /* In Multiple Master CFFs, two SIDs hold the Normalize Design */ + /* Vector (NDV) and Convert Design Vector (CDV) charstrings, */ + /* which may contain NULL bytes in the middle of the data, too. */ + /* We thus access `cff->strings' directly. */ + for ( idx = 1; idx < cff->num_strings; idx++ ) + { + FT_Byte* s1 = cff->strings[idx - 1]; + FT_Byte* s2 = cff->strings[idx]; + size_t s1len = s2 - s1 - 1; /* without the final NULL byte */ + size_t l; + + + FT_TRACE4(( " %5d ", idx + 390, s )); + for ( l = 0; l < s1len; l++ ) + FT_TRACE4(( "%c", s1[l] )); + FT_TRACE4(( "\n" )); + } + + /* print last element */ + if ( cff->num_strings ) + { + FT_Byte* s1 = cff->strings[cff->num_strings - 1]; + FT_Byte* s2 = cff->string_pool + cff->string_pool_size; + size_t s1len = s2 - s1 - 1; + size_t l; + + + FT_TRACE4(( " %5d ", cff->num_strings + 390, s )); + for ( l = 0; l < s1len; l++ ) + FT_TRACE4(( "%c", s1[l] )); + FT_TRACE4(( "\n" )); } } #endif /* FT_DEBUG_LEVEL_TRACE */ diff --git a/src/cff/cfftypes.h b/src/cff/cfftypes.h index 10fe9372f..b2320fd93 100644 --- a/src/cff/cfftypes.h +++ b/src/cff/cfftypes.h @@ -255,6 +255,7 @@ FT_BEGIN_HEADER FT_UInt num_strings; FT_Byte** strings; FT_Byte* string_pool; + FT_ULong string_pool_size; CFF_SubFontRec top_font; FT_UInt num_subfonts;