* src/truetype/ttpload.c (tt_face_load_loca): Handle buggy fonts
where num_locations < num_glyphs. Problem reported by Ding Li.
This commit is contained in:
parent
ca6fc732b7
commit
6b19e095be
|
@ -1,3 +1,8 @@
|
|||
2008-07-09 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
* src/truetype/ttpload.c (tt_face_load_loca): Handle buggy fonts
|
||||
where num_locations < num_glyphs. Problem reported by Ding Li.
|
||||
|
||||
2008-07-05 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
Since FreeType uses `$(value ...)', we now need GNU make 3.80 or
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
/* */
|
||||
/* TrueType-specific tables loader (body). */
|
||||
/* */
|
||||
/* Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007 by */
|
||||
/* Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007, 2008 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
|
@ -65,6 +65,7 @@
|
|||
{
|
||||
FT_Error error;
|
||||
FT_ULong table_len;
|
||||
FT_Int shift;
|
||||
|
||||
|
||||
/* we need the size of the `glyf' table for malformed `loca' tables */
|
||||
|
@ -82,23 +83,65 @@
|
|||
|
||||
if ( face->header.Index_To_Loc_Format != 0 )
|
||||
{
|
||||
shift = 2;
|
||||
|
||||
if ( table_len >= 0x40000L )
|
||||
{
|
||||
FT_TRACE2(( "table too large!\n" ));
|
||||
error = TT_Err_Invalid_Table;
|
||||
goto Exit;
|
||||
}
|
||||
face->num_locations = (FT_UInt)( table_len >> 2 );
|
||||
face->num_locations = (FT_UInt)( table_len >> shift );
|
||||
}
|
||||
else
|
||||
{
|
||||
shift = 1;
|
||||
|
||||
if ( table_len >= 0x20000L )
|
||||
{
|
||||
FT_TRACE2(( "table too large!\n" ));
|
||||
error = TT_Err_Invalid_Table;
|
||||
goto Exit;
|
||||
}
|
||||
face->num_locations = (FT_UInt)( table_len >> 1 );
|
||||
face->num_locations = (FT_UInt)( table_len >> shift );
|
||||
}
|
||||
|
||||
if ( face->num_locations != (FT_UInt)face->root.num_glyphs )
|
||||
{
|
||||
FT_TRACE2(( "glyph count mismatch! loca: %d, maxp: %d\n",
|
||||
face->num_locations, face->root.num_glyphs ));
|
||||
|
||||
/* we only handle the case where `maxp' gives a larger value */
|
||||
if ( face->num_locations < (FT_UInt)face->root.num_glyphs )
|
||||
{
|
||||
FT_Long new_loca_len = (FT_Long)face->root.num_glyphs << shift;
|
||||
|
||||
TT_Table entry = face->dir_tables;
|
||||
TT_Table limit = entry + face->num_tables;
|
||||
|
||||
FT_Long pos = FT_Stream_Pos( stream );
|
||||
FT_Long dist = 0x7FFFFFFFL;
|
||||
|
||||
|
||||
/* compute the distance to next table in font file */
|
||||
for ( ; entry < limit; entry++ )
|
||||
{
|
||||
FT_Long diff = entry->Offset - pos;
|
||||
|
||||
|
||||
if ( diff > 0 && diff < dist )
|
||||
dist = diff;
|
||||
}
|
||||
|
||||
if ( new_loca_len <= dist )
|
||||
{
|
||||
face->num_locations = (FT_Long)face->root.num_glyphs;
|
||||
table_len = new_loca_len;
|
||||
|
||||
FT_TRACE2(( "adjusting num_locations to %d\n",
|
||||
face->num_locations ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue