[truetype] Tweak `loca` clamping.

Fixes #1095.

* src/truetype/ttpload.c (tt_face_load_loca): Fix up clamping.
* include/freetype/internal/tttypes.h (TT_Face): Correct docs.
This commit is contained in:
Alexei Podtelezhnikov 2021-09-09 22:17:46 -04:00
parent c350aac099
commit e942a31007
2 changed files with 9 additions and 22 deletions

View File

@ -1372,7 +1372,7 @@ FT_BEGIN_HEADER
* *
* num_locations :: * num_locations ::
* The number of glyph locations in this TrueType file. This should be * The number of glyph locations in this TrueType file. This should be
* identical to the number of glyphs. Ignored for Type 2 fonts. * one more than the number of glyphs. Ignored for Type 2 fonts.
* *
* glyph_locations :: * glyph_locations ::
* An array of longs. These are offsets to glyph data within the * An array of longs. These are offsets to glyph data within the
@ -1598,7 +1598,7 @@ FT_BEGIN_HEADER
FT_ULong horz_metrics_size; FT_ULong horz_metrics_size;
FT_ULong vert_metrics_size; FT_ULong vert_metrics_size;
FT_ULong num_locations; /* in broken TTF, gid > 0xFFFF */ FT_ULong num_locations; /* up to 0xFFFF + 1 */
FT_Byte* glyph_locations; FT_Byte* glyph_locations;
FT_Byte* hdmx_table; FT_Byte* hdmx_table;

View File

@ -98,36 +98,23 @@
goto Exit; goto Exit;
} }
if ( face->header.Index_To_Loc_Format != 0 ) shift = face->header.Index_To_Loc_Format != 0 ? 2 : 1;
{
shift = 2;
if ( table_len >= 0x40000L ) if ( table_len > 0x10000UL << shift )
{
FT_TRACE2(( "table too large\n" ));
table_len = 0x3FFFFL;
}
face->num_locations = table_len >> shift;
}
else
{ {
shift = 1; FT_TRACE2(( "table too large\n" ));
table_len = 0x10000UL << shift;
if ( table_len >= 0x20000L )
{
FT_TRACE2(( "table too large\n" ));
table_len = 0x1FFFFL;
}
face->num_locations = table_len >> shift;
} }
face->num_locations = table_len >> shift;
if ( face->num_locations != (FT_ULong)face->root.num_glyphs + 1 ) if ( face->num_locations != (FT_ULong)face->root.num_glyphs + 1 )
{ {
FT_TRACE2(( "glyph count mismatch! loca: %ld, maxp: %ld\n", FT_TRACE2(( "glyph count mismatch! loca: %ld, maxp: %ld\n",
face->num_locations - 1, face->root.num_glyphs )); face->num_locations - 1, face->root.num_glyphs ));
/* we only handle the case where `maxp' gives a larger value */ /* we only handle the case where `maxp' gives a larger value */
if ( face->num_locations <= (FT_ULong)face->root.num_glyphs ) if ( face->num_locations < (FT_ULong)face->root.num_glyphs + 1 )
{ {
FT_ULong new_loca_len = FT_ULong new_loca_len =
( (FT_ULong)face->root.num_glyphs + 1 ) << shift; ( (FT_ULong)face->root.num_glyphs + 1 ) << shift;