Upstream fixes for pcf fonts. http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=74af85c4b62b35e55b0ce9dec55ee10cbc4962a2 http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=06842c7b49c21f13c0ab61201daab6ff5a358fcc diff --git a/src/pcf/pcfread.c b/src/pcf/pcfread.c index 998cbed..e3caf82 100644 --- a/src/pcf/pcfread.c +++ b/src/pcf/pcfread.c @@ -2,7 +2,7 @@ FreeType font driver for pcf fonts - Copyright 2000-2010, 2012, 2013 by + Copyright 2000-2010, 2012-2014 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy @@ -78,7 +78,7 @@ THE SOFTWARE. FT_FRAME_START( 16 ), FT_FRAME_ULONG_LE( type ), FT_FRAME_ULONG_LE( format ), - FT_FRAME_ULONG_LE( size ), + FT_FRAME_ULONG_LE( size ), /* rounded up to a multiple of 4 */ FT_FRAME_ULONG_LE( offset ), FT_FRAME_END }; @@ -95,9 +95,11 @@ THE SOFTWARE. FT_Memory memory = FT_FACE( face )->memory; FT_UInt n; + FT_ULong size; - if ( FT_STREAM_SEEK ( 0 ) || - FT_STREAM_READ_FIELDS ( pcf_toc_header, toc ) ) + + if ( FT_STREAM_SEEK( 0 ) || + FT_STREAM_READ_FIELDS( pcf_toc_header, toc ) ) return FT_THROW( Cannot_Open_Resource ); if ( toc->version != PCF_FILE_VERSION || @@ -154,14 +156,35 @@ THE SOFTWARE. break; } - /* we now check whether the `size' and `offset' values are reasonable: */ - /* `offset' + `size' must not exceed the stream size */ + /* + * We now check whether the `size' and `offset' values are reasonable: + * `offset' + `size' must not exceed the stream size. + * + * Note, however, that X11's `pcfWriteFont' routine (used by the + * `bdftopcf' program to create PDF font files) has two special + * features. + * + * - It always assigns the accelerator table a size of 100 bytes in the + * TOC, regardless of its real size, which can vary between 34 and 72 + * bytes. + * + * - Due to the way the routine is designed, it ships out the last font + * table with its real size, ignoring the TOC's size value. Since + * the TOC size values are always rounded up to a multiple of 4, the + * difference can be up to three bytes for all tables except the + * accelerator table, for which the difference can be as large as 66 + * bytes. + * + */ + tables = face->toc.tables; - for ( n = 0; n < toc->count; n++ ) + size = stream->size; + + for ( n = 0; n < toc->count - 1; n++ ) { /* we need two checks to avoid overflow */ - if ( ( tables->size > stream->size ) || - ( tables->offset > stream->size - tables->size ) ) + if ( ( tables->size > size ) || + ( tables->offset > size - tables->size ) ) { error = FT_THROW( Invalid_Table ); goto Exit; @@ -169,6 +192,15 @@ THE SOFTWARE. tables++; } + /* no check of `tables->size' for last table element ... */ + if ( ( tables->offset > size ) ) + { + error = FT_THROW( Invalid_Table ); + goto Exit; + } + /* ... instead, we adjust `tables->size' to the real value */ + tables->size = size - tables->offset; + #ifdef FT_DEBUG_LEVEL_TRACE { @@ -733,8 +765,8 @@ THE SOFTWARE. FT_TRACE4(( " number of bitmaps: %d\n", nbitmaps )); - /* XXX: PCF_Face->nmetrics is singed FT_Long, see pcf.h */ - if ( face->nmetrics < 0 || nbitmaps != ( FT_ULong )face->nmetrics ) + /* XXX: PCF_Face->nmetrics is signed FT_Long, see pcf.h */ + if ( face->nmetrics < 0 || nbitmaps != (FT_ULong)face->nmetrics ) return FT_THROW( Invalid_File_Format ); if ( FT_NEW_ARRAY( offsets, nbitmaps ) ) diff --git a/src/pcf/pcfread.c b/src/pcf/pcfread.c index e3caf82..a29a9e3 100644 --- a/src/pcf/pcfread.c +++ b/src/pcf/pcfread.c @@ -192,14 +192,15 @@ THE SOFTWARE. tables++; } - /* no check of `tables->size' for last table element ... */ + /* only check `tables->offset' for last table element ... */ if ( ( tables->offset > size ) ) { error = FT_THROW( Invalid_Table ); goto Exit; } - /* ... instead, we adjust `tables->size' to the real value */ - tables->size = size - tables->offset; + /* ... and adjust `tables->size' to the real value if necessary */ + if ( tables->size > size - tables->offset ) + tables->size = size - tables->offset; #ifdef FT_DEBUG_LEVEL_TRACE