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; |