* src/gzip/ftgzip.c: fixed a bug that caused FreeType to loop endlessly

when trying to read certain compressed gzip files. The following test
    could be used to reveal the bug:

       touch 0123456789 ; gzip 0123456789 ; ftdump 0123456789.gz


    * src/pfr/pfrobjs.c, src/pfr/pfrload.c, src/pfr/pfrtypes.h: several
    fixes to the PFR font driver:

      - the list of available embedded bitmaps was not correctly set
        in the root FT_FaceRec structure describing the face

      - the glyph loader always tried to load the outlines when
        FT_LOAD_SBITS_ONLY was specified

      - the table loaded now scans for *undocumented* elements of a
        physical font's auxiliary data record, this is necessary to
        retrieve the "real" family and style names.

        NOTE THAT THIS CHANGES THE FAMILY NAME OF MANY PFR FONTS !!
This commit is contained in:
David Turner 2003-02-25 19:20:12 +00:00
parent 21493df9bd
commit fd37c4b8ac
5 changed files with 204 additions and 8 deletions

View File

@ -1,3 +1,29 @@
2003-02-25 David Turner <david@freetype.org>
* src/gzip/ftgzip.c: fixed a bug that caused FreeType to loop endlessly
when trying to read certain compressed gzip files. The following test
could be used to reveal the bug:
touch 0123456789 ; gzip 0123456789 ; ftdump 0123456789.gz
* src/pfr/pfrobjs.c, src/pfr/pfrload.c, src/pfr/pfrtypes.h: several
fixes to the PFR font driver:
- the list of available embedded bitmaps was not correctly set
in the root FT_FaceRec structure describing the face
- the glyph loader always tried to load the outlines when
FT_LOAD_SBITS_ONLY was specified
- the table loaded now scans for *undocumented* elements of a
physical font's auxiliary data record, this is necessary to
retrieve the "real" family and style names.
NOTE THAT THIS CHANGES THE FAMILY NAME OF MANY PFR FONTS !!
2003-02-18 David Turner <david@freetype.org>
* src/truetype/ttdriver.c, src/truetype/ttobjs.h, src/truetype/ttobjs.c,

View File

@ -376,6 +376,7 @@
if ( err == Z_STREAM_END )
{
zip->limit = zstream->next_out;
error = FT_Err_Invalid_Stream_Operation;
break;
}
else if ( err != Z_OK )

View File

@ -432,7 +432,16 @@
}
/* load font ID, i.e. name */
/* load font ID, this is a so-called "unique" name that is rather
* long and descriptive (like "Tiresias ScreenFont v7.51").
*
* note that a PFR font's family name is contained in an *undocumented*
* string of the "auxiliary data" portion of a physical font record. this
* may also contain the "real" style name !
*
* if no family name is present, the font id is used instead for the
* family
*/
FT_CALLBACK_DEF( FT_Error )
pfr_extra_item_load_font_id( FT_Byte* p,
FT_Byte* limit,
@ -693,12 +702,54 @@
};
/* loads a name from the auxiliary data. Since this extracts undocumented
* strings from the font file, we need to be careful here
*/
static FT_Error
pfr_aux_name_load( FT_Byte* p,
FT_UInt len,
FT_Memory memory,
FT_String* *astring )
{
FT_Error error = 0;
FT_String* result = NULL;
FT_UInt n, ok;
if ( len > 0 && p[len-1] == 0 )
len--;
/* check that each character is ASCII, that's to be sure
* to not load garbage..
*/
ok = (len > 0);
for ( n = 0; n < len; n++ )
if ( p[n] < 32 || p[n] > 127 )
{
ok = 0;
break;
}
if ( ok )
{
if ( FT_ALLOC( result, len+1 ) )
goto Exit;
FT_MEM_COPY( result, p, len );
result[len] = 0;
}
Exit:
*astring = result;
return error;
}
FT_LOCAL_DEF( void )
pfr_phy_font_done( PFR_PhyFont phy_font,
FT_Memory memory )
{
if ( phy_font->font_id )
FT_FREE( phy_font->font_id );
FT_FREE( phy_font->font_id );
FT_FREE( phy_font->family_name );
FT_FREE( phy_font->style_name );
FT_FREE( phy_font->vertical.stem_snaps );
phy_font->vertical.num_stem_snaps = 0;
@ -736,6 +787,7 @@
}
FT_LOCAL_DEF( FT_Error )
pfr_phy_font_load( PFR_PhyFont phy_font,
FT_Stream stream,
@ -790,12 +842,82 @@
goto Fail;
}
/* skip the aux bytes */
/* in certain fonts, the auxiliary bytes contain interesting */
/* information. These are not in the specification but can be */
/* guessed by looking at the content of a few PFR0 fonts */
PFR_CHECK( 3 );
num_aux = PFR_NEXT_ULONG( p );
PFR_CHECK( num_aux );
p += num_aux;
if ( num_aux > 0 )
{
FT_Byte* q = p;
FT_Byte* q2;
PFR_CHECK( num_aux );
p += num_aux;
while ( num_aux >= 0 )
{
FT_UInt length, type;
if ( q + 4 > p )
break;
length = PFR_NEXT_USHORT(q);
if ( length < 4 || length > num_aux )
break;
q2 = q + length - 2;
type = PFR_NEXT_USHORT(q);
switch ( type )
{
case 1:
{
/* this seems to correspond to the font's family name,
* padded to 16-bits with one zero when necessary
*/
error = pfr_aux_name_load( q, length-4U, memory,
&phy_font->family_name );
if ( error )
goto Exit;
}
break;
case 2:
{
if ( q + 32 > q2 )
break;
q += 10;
phy_font->ascent = PFR_NEXT_SHORT(q);
phy_font->descent = PFR_NEXT_SHORT(q);
phy_font->leading = PFR_NEXT_SHORT(q);
q += 16;
}
break;
case 3:
{
FT_UInt n, len, ok;
/* this seems to correspond to the font's style name,
* padded to 16-bits with one zero when necessary
*/
error = pfr_aux_name_load( q, length-4U, memory,
&phy_font->style_name );
if ( error )
goto Exit;
}
break;
default:
;
}
q = q2;
num_aux -= length;
}
}
/* read the blue values */
{

View File

@ -41,6 +41,10 @@
FT_LOCAL_DEF( void )
pfr_face_done( PFR_Face face )
{
/* we don't want dangling pointers */
face->root.family_name = NULL;
face->root.style_name = NULL;
/* finalize the physical font record */
pfr_phy_font_done( &face->phy_font, FT_FACE_MEMORY( face ) );
@ -136,8 +140,18 @@
if ( phy_font->num_kern_pairs > 0 )
root->face_flags |= FT_FACE_FLAG_KERNING;
root->family_name = phy_font->font_id;
root->style_name = NULL; /* no style name in font file */
/* if no family name was found in the "undocumented" auxiliary
* data, use the font ID instead. This sucks but is better than
* nothing
*/
root->family_name = phy_font->family_name;
if ( root->family_name == NULL )
root->family_name = phy_font->font_id;
/* note that the style name can be NULL in certain PFR fonts,
* probably meaning "Regular"
*/
root->style_name = phy_font->style_name;
root->num_fixed_sizes = 0;
root->available_sizes = 0;
@ -150,6 +164,27 @@
( ( ( root->ascender - root->descender ) * 12 )
/ 10 );
if ( phy_font->num_strikes > 0 )
{
FT_UInt n, count = phy_font->num_strikes;
FT_Bitmap_Size* size;
PFR_Strike strike;
FT_Memory memory = root->stream->memory;
if ( FT_NEW_ARRAY( root->available_sizes, count ) )
goto Exit;
size = root->available_sizes;
strike = phy_font->strikes;
for ( n = 0; n < count; n++, size++, strike++ )
{
size->height = strike->y_ppm;
size->width = strike->x_ppm;
}
root->num_fixed_sizes = count;
}
/* now compute maximum advance width */
if ( ( phy_font->flags & PFR_PHY_PROPORTIONAL ) == 0 )
root->max_advance_width = (FT_Short)phy_font->standard_advance;
@ -255,6 +290,12 @@
goto Exit;
}
if ( load_flags & FT_LOAD_SBITS_ONLY )
{
error = FT_Err_Invalid_Argument;
goto Exit;
}
gchar = face->phy_font.chars + gindex;
slot->root.format = FT_GLYPH_FORMAT_OUTLINE;
outline->n_points = 0;

View File

@ -230,11 +230,17 @@ FT_BEGIN_HEADER
FT_BBox bbox;
FT_UInt flags;
FT_UInt standard_advance;
FT_Int ascent; /* optional, bbox.yMax if not present */
FT_Int descent; /* optional, bbox.yMin if not present */
FT_Int leading; /* optional, 0 if not present */
PFR_DimensionRec horizontal;
PFR_DimensionRec vertical;
FT_String* font_id;
FT_String* family_name;
FT_String* style_name;
FT_UInt num_strikes;
FT_UInt max_strikes;