| Index: third_party/freetype/src/truetype/ttpload.c
|
| diff --git a/core/src/fxge/fx_freetype/fxft2.5.01/src/truetype/ttpload.c b/third_party/freetype/src/truetype/ttpload.c
|
| similarity index 87%
|
| rename from core/src/fxge/fx_freetype/fxft2.5.01/src/truetype/ttpload.c
|
| rename to third_party/freetype/src/truetype/ttpload.c
|
| index 13e28b75dee621ac0a5f9afcb8e3a43a493a9882..9991925425280909b91e56e854813f6f42202f3a 100644
|
| --- a/core/src/fxge/fx_freetype/fxft2.5.01/src/truetype/ttpload.c
|
| +++ b/third_party/freetype/src/truetype/ttpload.c
|
| @@ -16,11 +16,11 @@
|
| /***************************************************************************/
|
|
|
|
|
| -#include "../../include/ft2build.h"
|
| -#include "../../include/freetype/internal/ftdebug.h"
|
| -#include "../../include/freetype/internal/ftobjs.h"
|
| -#include "../../include/freetype/internal/ftstream.h"
|
| -#include "../../include/freetype/tttags.h"
|
| +#include <ft2build.h>
|
| +#include FT_INTERNAL_DEBUG_H
|
| +#include FT_INTERNAL_OBJECTS_H
|
| +#include FT_INTERNAL_STREAM_H
|
| +#include FT_TRUETYPE_TAGS_H
|
|
|
| #include "ttpload.h"
|
|
|
| @@ -109,10 +109,56 @@
|
| }
|
| face->num_locations = table_len >> shift;
|
| }
|
| +
|
| + if ( face->num_locations != (FT_ULong)face->root.num_glyphs + 1 )
|
| + {
|
| + FT_TRACE2(( "glyph count mismatch! loca: %d, maxp: %d\n",
|
| + face->num_locations - 1, face->root.num_glyphs ));
|
| +
|
| + /* we only handle the case where `maxp' gives a larger value */
|
| + if ( face->num_locations <= (FT_ULong)face->root.num_glyphs )
|
| + {
|
| + FT_Long new_loca_len =
|
| + ( (FT_Long)( face->root.num_glyphs ) + 1 ) << 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 ( entry == limit )
|
| + {
|
| + /* `loca' is the last table */
|
| + dist = stream->size - pos;
|
| + }
|
| +
|
| + if ( new_loca_len <= dist )
|
| + {
|
| + face->num_locations = face->root.num_glyphs + 1;
|
| + table_len = new_loca_len;
|
| +
|
| + FT_TRACE2(( "adjusting num_locations to %d\n",
|
| + face->num_locations ));
|
| + }
|
| + }
|
| + }
|
| +
|
| /*
|
| * Extract the frame. We don't need to decompress it since
|
| * we are able to parse it directly.
|
| - */
|
| + */
|
| if ( FT_FRAME_EXTRACT( table_len, face->glyph_locations ) )
|
| goto Exit;
|
|
|
| @@ -128,37 +174,40 @@
|
| FT_UInt gindex,
|
| FT_UInt *asize )
|
| {
|
| - FT_ULong pos1 = 0, pos2 = 0;
|
| - FT_Byte* p = NULL;
|
| + FT_ULong pos1, pos2;
|
| + FT_Byte* p;
|
| + FT_Byte* p_limit;
|
|
|
| - if (!face || gindex >= face->num_locations)
|
| - {
|
| - if (asize)
|
| - *asize = 0;
|
|
|
| - return 0;
|
| - }
|
| + pos1 = pos2 = 0;
|
|
|
| - if ( face->header.Index_To_Loc_Format != 0 )
|
| - {
|
| - p = face->glyph_locations + gindex * 4;
|
| - pos1 = FT_NEXT_ULONG(p);
|
| - pos2 = pos1;
|
| - //p has been moved to next location in the previous FT_NEXT_ULONG.
|
| - if ( gindex < face->num_locations - 1 )
|
| - pos2 = FT_NEXT_ULONG(p);
|
| - }
|
| - else
|
| + if ( gindex < face->num_locations )
|
| {
|
| - p = face->glyph_locations + gindex * 2;
|
| - pos1 = FT_NEXT_USHORT(p);
|
| - pos2 = pos1;
|
| - //p has been moved to next location in the previous FT_NEXT_USHORT.
|
| - if ( gindex < face->num_locations - 1 )
|
| - pos2 = FT_NEXT_USHORT( p );
|
| -
|
| - pos1 <<= 1;
|
| - pos2 <<= 1;
|
| + if ( face->header.Index_To_Loc_Format != 0 )
|
| + {
|
| + p = face->glyph_locations + gindex * 4;
|
| + p_limit = face->glyph_locations + face->num_locations * 4;
|
| +
|
| + pos1 = FT_NEXT_ULONG( p );
|
| + pos2 = pos1;
|
| +
|
| + if ( p + 4 <= p_limit )
|
| + pos2 = FT_NEXT_ULONG( p );
|
| + }
|
| + else
|
| + {
|
| + p = face->glyph_locations + gindex * 2;
|
| + p_limit = face->glyph_locations + face->num_locations * 2;
|
| +
|
| + pos1 = FT_NEXT_USHORT( p );
|
| + pos2 = pos1;
|
| +
|
| + if ( p + 2 <= p_limit )
|
| + pos2 = FT_NEXT_USHORT( p );
|
| +
|
| + pos1 <<= 1;
|
| + pos2 <<= 1;
|
| + }
|
| }
|
|
|
| /* Check broken location data */
|
| @@ -459,9 +508,9 @@
|
| record_size = FT_NEXT_ULONG( p );
|
|
|
| /* The maximum number of bytes in an hdmx device record is the */
|
| - /* maximum number of glyphs + 2; this is 0xFFFF + 2; this is */
|
| - /* the reason why `record_size' is a long (which we read as */
|
| - /* unsigned long for convenience). In practice, two bytes */
|
| + /* maximum number of glyphs + 2; this is 0xFFFF + 2, thus */
|
| + /* explaining why `record_size' is a long (which we read as */
|
| + /* unsigned long for convenience). In practice, two bytes are */
|
| /* sufficient to hold the size value. */
|
| /* */
|
| /* There are at least two fonts, HANNOM-A and HANNOM-B version */
|
| @@ -473,8 +522,10 @@
|
| record_size &= 0xFFFFU;
|
|
|
| /* The limit for `num_records' is a heuristic value. */
|
| -
|
| - if ( version != 0 || num_records > 255 || record_size > 0x10001L )
|
| + if ( version != 0 ||
|
| + num_records > 255 ||
|
| + record_size > 0x10001L ||
|
| + record_size < 4 )
|
| {
|
| error = FT_THROW( Invalid_File_Format );
|
| goto Fail;
|
|
|