Index: third_party/freetype/src/sfnt/ttcmap.c |
diff --git a/third_party/freetype/src/sfnt/ttcmap.c b/third_party/freetype/src/sfnt/ttcmap.c |
index ece9ef11235ff288cddfa6a430e2085666dcf50f..c4d9abdfe6800edc47cbef350419f5f7c3d6ab8e 100644 |
--- a/third_party/freetype/src/sfnt/ttcmap.c |
+++ b/third_party/freetype/src/sfnt/ttcmap.c |
@@ -4,7 +4,7 @@ |
/* */ |
/* TrueType character mapping table (cmap) support (body). */ |
/* */ |
-/* Copyright 2002-2010, 2012-2014 by */ |
+/* Copyright 2002-2015 by */ |
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
/* */ |
/* This file is part of the FreeType project, and may only be used, */ |
@@ -51,6 +51,13 @@ |
#define TT_NEXT_ULONG FT_NEXT_ULONG |
+ /* Too large glyph index return values are caught in `FT_Get_Char_Index' */ |
+ /* and `FT_Get_Next_Char' (the latter calls the internal `next' function */ |
+ /* again in this case). To mark character code return values as invalid */ |
+ /* it is sufficient to set the corresponding glyph index return value to */ |
+ /* zero. */ |
+ |
+ |
FT_CALLBACK_DEF( FT_Error ) |
tt_cmap_init( TT_CMap cmap, |
FT_Byte* table ) |
@@ -199,7 +206,7 @@ |
/***** FORMAT 2 *****/ |
/***** *****/ |
/***** This is used for certain CJK encodings that encode text in a *****/ |
- /***** mixed 8/16 bits encoding along the following lines: *****/ |
+ /***** mixed 8/16 bits encoding along the following lines. *****/ |
/***** *****/ |
/***** * Certain byte values correspond to an 8-bit character code *****/ |
/***** (typically in the range 0..127 for ASCII compatibility). *****/ |
@@ -209,19 +216,19 @@ |
/***** second byte of a 2-byte character). *****/ |
/***** *****/ |
/***** The following charmap lookup and iteration functions all *****/ |
- /***** assume that the value "charcode" correspond to following: *****/ |
+ /***** assume that the value `charcode' fulfills the following. *****/ |
/***** *****/ |
- /***** - For one byte characters, "charcode" is simply the *****/ |
+ /***** - For one byte characters, `charcode' is simply the *****/ |
/***** character code. *****/ |
/***** *****/ |
- /***** - For two byte characters, "charcode" is the 2-byte *****/ |
- /***** character code in big endian format. More exactly: *****/ |
+ /***** - For two byte characters, `charcode' is the 2-byte *****/ |
+ /***** character code in big endian format. More precisely: *****/ |
/***** *****/ |
/***** (charcode >> 8) is the first byte value *****/ |
/***** (charcode & 0xFF) is the second byte value *****/ |
/***** *****/ |
- /***** Note that not all values of "charcode" are valid according *****/ |
- /***** to these rules, and the function moderately check the *****/ |
+ /***** Note that not all values of `charcode' are valid according *****/ |
+ /***** to these rules, and the function moderately checks the *****/ |
/***** arguments. *****/ |
/***** *****/ |
/*************************************************************************/ |
@@ -249,7 +256,7 @@ |
/* table, i.e., it is the corresponding sub-header index multiplied */ |
/* by 8. */ |
/* */ |
- /* Each sub-header has the following format: */ |
+ /* Each sub-header has the following format. */ |
/* */ |
/* NAME OFFSET TYPE DESCRIPTION */ |
/* */ |
@@ -264,11 +271,11 @@ |
/* according to the specification. */ |
/* */ |
/* If a character code is contained within a given sub-header, then */ |
- /* mapping it to a glyph index is done as follows: */ |
+ /* mapping it to a glyph index is done as follows. */ |
/* */ |
/* * The value of `offset' is read. This is a _byte_ distance from the */ |
/* location of the `offset' field itself into a slice of the */ |
- /* `glyph_ids' table. Let's call it `slice' (it is a USHORT[] too). */ |
+ /* `glyph_ids' table. Let's call it `slice' (it is a USHORT[], too). */ |
/* */ |
/* * The value `slice[char.lo - first]' is read. If it is 0, there is */ |
/* no glyph for the charcode. Otherwise, the value of `delta' is */ |
@@ -326,7 +333,7 @@ |
FT_ASSERT( p == table + 518 ); |
subs = p; |
- glyph_ids = subs + (max_subs + 1) * 8; |
+ glyph_ids = subs + ( max_subs + 1 ) * 8; |
if ( glyph_ids > valid->limit ) |
FT_INVALID_TOO_SHORT; |
@@ -360,7 +367,7 @@ |
ids = p - 2 + offset; |
- if ( ids < glyph_ids || ids + code_count*2 > table + length ) |
+ if ( ids < glyph_ids || ids + code_count * 2 > table + length ) |
FT_INVALID_OFFSET; |
/* check glyph IDs */ |
@@ -375,7 +382,7 @@ |
idx = TT_NEXT_USHORT( p ); |
if ( idx != 0 ) |
{ |
- idx = ( idx + delta ) & 0xFFFFU; |
+ idx = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU; |
if ( idx >= TT_VALID_GLYPH_COUNT( valid ) ) |
FT_INVALID_GLYPH_ID; |
} |
@@ -436,6 +443,7 @@ |
} |
result = sub; |
} |
+ |
Exit: |
return result; |
} |
@@ -472,9 +480,10 @@ |
idx = TT_PEEK_USHORT( p ); |
if ( idx != 0 ) |
- result = (FT_UInt)( idx + delta ) & 0xFFFFU; |
+ result = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU; |
} |
} |
+ |
return result; |
} |
@@ -524,7 +533,7 @@ |
if ( idx != 0 ) |
{ |
- gindex = ( idx + delta ) & 0xFFFFU; |
+ gindex = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU; |
if ( gindex != 0 ) |
{ |
result = charcode; |
@@ -786,7 +795,7 @@ |
if ( gindex != 0 ) |
{ |
- gindex = (FT_UInt)( ( gindex + delta ) & 0xFFFFU ); |
+ gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU; |
if ( gindex != 0 ) |
{ |
cmap->cur_charcode = charcode; |
@@ -800,7 +809,7 @@ |
{ |
do |
{ |
- FT_UInt gindex = (FT_UInt)( ( charcode + delta ) & 0xFFFFU ); |
+ FT_UInt gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU; |
if ( gindex != 0 ) |
@@ -973,7 +982,7 @@ |
/* segment if it contains only a single character. */ |
/* */ |
/* We thus omit the test here, delaying it to the */ |
- /* routines which actually access the cmap. */ |
+ /* routines that actually access the cmap. */ |
else if ( n != num_segs - 1 || |
!( start == 0xFFFFU && end == 0xFFFFU ) ) |
{ |
@@ -993,7 +1002,7 @@ |
idx = FT_NEXT_USHORT( p ); |
if ( idx != 0 ) |
{ |
- idx = (FT_UInt)( idx + delta ) & 0xFFFFU; |
+ idx = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU; |
if ( idx >= TT_VALID_GLYPH_COUNT( valid ) ) |
FT_INVALID_GLYPH_ID; |
@@ -1026,12 +1035,17 @@ |
FT_UInt32* pcharcode, |
FT_Bool next ) |
{ |
+ TT_Face face = (TT_Face)cmap->cmap.charmap.face; |
+ FT_Byte* limit = face->cmap_table + face->cmap_size; |
+ |
+ |
FT_UInt num_segs2, start, end, offset; |
FT_Int delta; |
FT_UInt i, num_segs; |
FT_UInt32 charcode = *pcharcode; |
FT_UInt gindex = 0; |
FT_Byte* p; |
+ FT_Byte* q; |
p = cmap->data + 6; |
@@ -1045,65 +1059,106 @@ |
if ( next ) |
charcode++; |
+ if ( charcode > 0xFFFFU ) |
+ return 0; |
+ |
/* linear search */ |
- for ( ; charcode <= 0xFFFFU; charcode++ ) |
- { |
- FT_Byte* q; |
+ p = cmap->data + 14; /* ends table */ |
+ q = cmap->data + 16 + num_segs2; /* starts table */ |
+ for ( i = 0; i < num_segs; i++ ) |
+ { |
+ end = TT_NEXT_USHORT( p ); |
+ start = TT_NEXT_USHORT( q ); |
- p = cmap->data + 14; /* ends table */ |
- q = cmap->data + 16 + num_segs2; /* starts table */ |
+ if ( charcode < start ) |
+ { |
+ if ( next ) |
+ charcode = start; |
+ else |
+ break; |
+ } |
- for ( i = 0; i < num_segs; i++ ) |
+ Again: |
+ if ( charcode <= end ) |
{ |
- end = TT_NEXT_USHORT( p ); |
- start = TT_NEXT_USHORT( q ); |
+ FT_Byte* r; |
+ |
- if ( charcode >= start && charcode <= end ) |
+ r = q - 2 + num_segs2; |
+ delta = TT_PEEK_SHORT( r ); |
+ r += num_segs2; |
+ offset = TT_PEEK_USHORT( r ); |
+ |
+ /* some fonts have an incorrect last segment; */ |
+ /* we have to catch it */ |
+ if ( i >= num_segs - 1 && |
+ start == 0xFFFFU && end == 0xFFFFU ) |
{ |
- p = q - 2 + num_segs2; |
- delta = TT_PEEK_SHORT( p ); |
- p += num_segs2; |
- offset = TT_PEEK_USHORT( p ); |
- |
- /* some fonts have an incorrect last segment; */ |
- /* we have to catch it */ |
- if ( i >= num_segs - 1 && |
- start == 0xFFFFU && end == 0xFFFFU ) |
+ if ( offset && r + offset + 2 > limit ) |
{ |
- TT_Face face = (TT_Face)cmap->cmap.charmap.face; |
- FT_Byte* limit = face->cmap_table + face->cmap_size; |
+ delta = 1; |
+ offset = 0; |
+ } |
+ } |
+ if ( offset == 0xFFFFU ) |
+ continue; |
- if ( offset && p + offset + 2 > limit ) |
- { |
- delta = 1; |
- offset = 0; |
- } |
- } |
+ if ( offset ) |
+ { |
+ r += offset + ( charcode - start ) * 2; |
- if ( offset == 0xFFFFU ) |
+ /* if r > limit, the whole segment is invalid */ |
+ if ( next && r > limit ) |
continue; |
- if ( offset ) |
+ gindex = TT_PEEK_USHORT( r ); |
+ if ( gindex ) |
{ |
- p += offset + ( charcode - start ) * 2; |
- gindex = TT_PEEK_USHORT( p ); |
- if ( gindex != 0 ) |
- gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU; |
+ gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU; |
+ if ( gindex >= (FT_UInt)face->root.num_glyphs ) |
+ gindex = 0; |
} |
- else |
- gindex = (FT_UInt)( charcode + delta ) & 0xFFFFU; |
+ } |
+ else |
+ { |
+ gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU; |
- break; |
+ if ( next && gindex >= (FT_UInt)face->root.num_glyphs ) |
+ { |
+ /* we have an invalid glyph index; if there is an overflow, */ |
+ /* we can adjust `charcode', otherwise the whole segment is */ |
+ /* invalid */ |
+ gindex = 0; |
+ |
+ if ( (FT_Int)charcode + delta < 0 && |
+ (FT_Int)end + delta >= 0 ) |
+ charcode = (FT_UInt)( -delta ); |
+ |
+ else if ( (FT_Int)charcode + delta < 0x10000L && |
+ (FT_Int)end + delta >= 0x10000L ) |
+ charcode = (FT_UInt)( 0x10000L - delta ); |
+ |
+ else |
+ continue; |
+ } |
+ } |
+ |
+ if ( next && !gindex ) |
+ { |
+ if ( charcode >= 0xFFFFU ) |
+ break; |
+ |
+ charcode++; |
+ goto Again; |
} |
- } |
- if ( !next || gindex ) |
break; |
+ } |
} |
- if ( next && gindex ) |
+ if ( next ) |
*pcharcode = charcode; |
return gindex; |
@@ -1294,10 +1349,10 @@ |
p += offset + ( charcode - start ) * 2; |
gindex = TT_PEEK_USHORT( p ); |
if ( gindex != 0 ) |
- gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU; |
+ gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU; |
} |
else |
- gindex = (FT_UInt)( charcode + delta ) & 0xFFFFU; |
+ gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU; |
break; |
} |
@@ -1310,7 +1365,6 @@ |
/* if `charcode' is not in any segment, then `mid' is */ |
/* the segment nearest to `charcode' */ |
- /* */ |
if ( charcode > end ) |
{ |
@@ -1443,7 +1497,7 @@ |
/* */ |
/* NAME OFFSET TYPE DESCRIPTION */ |
/* */ |
- /* format 0 USHORT must be 4 */ |
+ /* format 0 USHORT must be 6 */ |
/* length 2 USHORT table length in bytes */ |
/* language 4 USHORT Mac language code */ |
/* */ |
@@ -1511,6 +1565,7 @@ |
p += 2 * idx; |
result = TT_PEEK_USHORT( p ); |
} |
+ |
return result; |
} |
@@ -1531,7 +1586,7 @@ |
if ( char_code >= 0x10000UL ) |
- goto Exit; |
+ return 0; |
if ( char_code < start ) |
char_code = start; |
@@ -1547,10 +1602,13 @@ |
result = char_code; |
break; |
} |
+ |
+ if ( char_code >= 0xFFFFU ) |
+ return 0; |
+ |
char_code++; |
} |
- Exit: |
*pchar_code = result; |
return gindex; |
} |
@@ -1602,7 +1660,7 @@ |
/***** *****/ |
/***** The purpose of this format is to easily map UTF-16 text to *****/ |
/***** glyph indices. Basically, the `char_code' must be in one of *****/ |
- /***** the following formats: *****/ |
+ /***** the following formats. *****/ |
/***** *****/ |
/***** - A 16-bit value that isn't part of the Unicode Surrogates *****/ |
/***** Area (i.e. U+D800-U+DFFF). *****/ |
@@ -1615,7 +1673,7 @@ |
/***** The `is32' table embedded in the charmap indicates whether a *****/ |
/***** given 16-bit value is in the surrogates area or not. *****/ |
/***** *****/ |
- /***** So, for any given `char_code', we can assert the following: *****/ |
+ /***** So, for any given `char_code', we can assert the following. *****/ |
/***** *****/ |
/***** If `char_hi == 0' then we must have `is32[char_lo] == 0'. *****/ |
/***** *****/ |
@@ -1770,7 +1828,10 @@ |
if ( char_code <= end ) |
{ |
- result = (FT_UInt)( start_id + char_code - start ); |
+ if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) ) |
+ return 0; |
+ |
+ result = (FT_UInt)( start_id + ( char_code - start ) ); |
break; |
} |
} |
@@ -1782,8 +1843,9 @@ |
tt_cmap8_char_next( TT_CMap cmap, |
FT_UInt32 *pchar_code ) |
{ |
+ FT_Face face = cmap->cmap.charmap.face; |
FT_UInt32 result = 0; |
- FT_UInt32 char_code = *pchar_code + 1; |
+ FT_UInt32 char_code; |
FT_UInt gindex = 0; |
FT_Byte* table = cmap->data; |
FT_Byte* p = table + 8204; |
@@ -1791,6 +1853,11 @@ |
FT_UInt32 start, end, start_id; |
+ if ( *pchar_code >= 0xFFFFFFFFUL ) |
+ return 0; |
+ |
+ char_code = *pchar_code + 1; |
+ |
p = table + 8208; |
for ( ; num_groups > 0; num_groups-- ) |
@@ -1802,18 +1869,35 @@ |
if ( char_code < start ) |
char_code = start; |
+ Again: |
if ( char_code <= end ) |
{ |
- gindex = (FT_UInt)( char_code - start + start_id ); |
- if ( gindex != 0 ) |
+ /* ignore invalid group */ |
+ if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) ) |
+ continue; |
+ |
+ gindex = (FT_UInt)( start_id + ( char_code - start ) ); |
+ |
+ /* does first element of group point to `.notdef' glyph? */ |
+ if ( gindex == 0 ) |
{ |
- result = char_code; |
- goto Exit; |
+ if ( char_code >= 0xFFFFFFFFUL ) |
+ break; |
+ |
+ char_code++; |
+ goto Again; |
} |
+ |
+ /* if `gindex' is invalid, the remaining values */ |
+ /* in this group are invalid, too */ |
+ if ( gindex >= (FT_UInt)face->num_glyphs ) |
+ continue; |
+ |
+ result = char_code; |
+ break; |
} |
} |
- Exit: |
*pchar_code = result; |
return gindex; |
} |
@@ -1930,14 +2014,20 @@ |
FT_Byte* p = table + 12; |
FT_UInt32 start = TT_NEXT_ULONG( p ); |
FT_UInt32 count = TT_NEXT_ULONG( p ); |
- FT_UInt32 idx = (FT_ULong)( char_code - start ); |
+ FT_UInt32 idx; |
+ |
+ |
+ if ( char_code < start ) |
+ return 0; |
+ idx = char_code - start; |
if ( idx < count ) |
{ |
p += 2 * idx; |
result = TT_PEEK_USHORT( p ); |
} |
+ |
return result; |
} |
@@ -1947,7 +2037,7 @@ |
FT_UInt32 *pchar_code ) |
{ |
FT_Byte* table = cmap->data; |
- FT_UInt32 char_code = *pchar_code + 1; |
+ FT_UInt32 char_code; |
FT_UInt gindex = 0; |
FT_Byte* p = table + 12; |
FT_UInt32 start = TT_NEXT_ULONG( p ); |
@@ -1955,10 +2045,15 @@ |
FT_UInt32 idx; |
+ if ( *pchar_code >= 0xFFFFFFFFUL ) |
+ return 0; |
+ |
+ char_code = *pchar_code + 1; |
+ |
if ( char_code < start ) |
char_code = start; |
- idx = (FT_UInt32)( char_code - start ); |
+ idx = char_code - start; |
p += 2 * idx; |
for ( ; idx < count; idx++ ) |
@@ -1966,6 +2061,10 @@ |
gindex = TT_NEXT_USHORT( p ); |
if ( gindex != 0 ) |
break; |
+ |
+ if ( char_code >= 0xFFFFFFFFUL ) |
+ return 0; |
+ |
char_code++; |
} |
@@ -2134,6 +2233,7 @@ |
static void |
tt_cmap12_next( TT_CMap12 cmap ) |
{ |
+ FT_Face face = cmap->cmap.cmap.charmap.face; |
FT_Byte* p; |
FT_ULong start, end, start_id, char_code; |
FT_ULong n; |
@@ -2155,18 +2255,35 @@ |
if ( char_code < start ) |
char_code = start; |
- for ( ; char_code <= end; char_code++ ) |
+ Again: |
+ if ( char_code <= end ) |
{ |
- gindex = (FT_UInt)( start_id + char_code - start ); |
+ /* ignore invalid group */ |
+ if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) ) |
+ continue; |
- if ( gindex ) |
+ gindex = (FT_UInt)( start_id + ( char_code - start ) ); |
+ |
+ /* does first element of group point to `.notdef' glyph? */ |
+ if ( gindex == 0 ) |
{ |
- cmap->cur_charcode = char_code;; |
- cmap->cur_gindex = gindex; |
- cmap->cur_group = n; |
+ if ( char_code >= 0xFFFFFFFFUL ) |
+ goto Fail; |
- return; |
+ char_code++; |
+ goto Again; |
} |
+ |
+ /* if `gindex' is invalid, the remaining values */ |
+ /* in this group are invalid, too */ |
+ if ( gindex >= (FT_UInt)face->num_glyphs ) |
+ continue; |
+ |
+ cmap->cur_charcode = char_code; |
+ cmap->cur_gindex = gindex; |
+ cmap->cur_group = n; |
+ |
+ return; |
} |
} |
@@ -2196,7 +2313,12 @@ |
end = 0xFFFFFFFFUL; |
if ( next ) |
+ { |
+ if ( char_code >= 0xFFFFFFFFUL ) |
+ return 0; |
+ |
char_code++; |
+ } |
min = 0; |
max = num_groups; |
@@ -2217,20 +2339,24 @@ |
else |
{ |
start_id = TT_PEEK_ULONG( p ); |
- gindex = (FT_UInt)( start_id + char_code - start ); |
+ /* reject invalid glyph index */ |
+ if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) ) |
+ gindex = 0; |
+ else |
+ gindex = (FT_UInt)( start_id + ( char_code - start ) ); |
break; |
} |
} |
if ( next ) |
{ |
+ FT_Face face = cmap->cmap.charmap.face; |
TT_CMap12 cmap12 = (TT_CMap12)cmap; |
/* if `char_code' is not in any group, then `mid' is */ |
/* the group nearest to `char_code' */ |
- /* */ |
if ( char_code > end ) |
{ |
@@ -2243,6 +2369,9 @@ |
cmap12->cur_charcode = char_code; |
cmap12->cur_group = mid; |
+ if ( gindex >= (FT_UInt)face->num_glyphs ) |
+ gindex = 0; |
+ |
if ( !gindex ) |
{ |
tt_cmap12_next( cmap12 ); |
@@ -2253,8 +2382,7 @@ |
else |
cmap12->cur_gindex = gindex; |
- if ( gindex ) |
- *pchar_code = cmap12->cur_charcode; |
+ *pchar_code = cmap12->cur_charcode; |
} |
return gindex; |
@@ -2274,11 +2402,8 @@ |
FT_UInt32 *pchar_code ) |
{ |
TT_CMap12 cmap12 = (TT_CMap12)cmap; |
- FT_ULong gindex; |
- |
+ FT_UInt gindex; |
- if ( cmap12->cur_charcode >= 0xFFFFFFFFUL ) |
- return 0; |
/* no need to search */ |
if ( cmap12->valid && cmap12->cur_charcode == *pchar_code ) |
@@ -2286,11 +2411,8 @@ |
tt_cmap12_next( cmap12 ); |
if ( cmap12->valid ) |
{ |
- gindex = cmap12->cur_gindex; |
- |
- /* XXX: check cur_charcode overflow is expected */ |
- if ( gindex ) |
- *pchar_code = (FT_UInt32)cmap12->cur_charcode; |
+ gindex = cmap12->cur_gindex; |
+ *pchar_code = (FT_UInt32)cmap12->cur_charcode; |
} |
else |
gindex = 0; |
@@ -2298,8 +2420,7 @@ |
else |
gindex = tt_cmap12_char_map_binary( cmap, pchar_code, 1 ); |
- /* XXX: check gindex overflow is expected */ |
- return (FT_UInt32)gindex; |
+ return gindex; |
} |
@@ -2458,6 +2579,7 @@ |
static void |
tt_cmap13_next( TT_CMap13 cmap ) |
{ |
+ FT_Face face = cmap->cmap.cmap.charmap.face; |
FT_Byte* p; |
FT_ULong start, end, glyph_id, char_code; |
FT_ULong n; |
@@ -2483,9 +2605,9 @@ |
{ |
gindex = (FT_UInt)glyph_id; |
- if ( gindex ) |
+ if ( gindex && gindex < (FT_UInt)face->num_glyphs ) |
{ |
- cmap->cur_charcode = char_code;; |
+ cmap->cur_charcode = char_code; |
cmap->cur_gindex = gindex; |
cmap->cur_group = n; |
@@ -2520,7 +2642,12 @@ |
end = 0xFFFFFFFFUL; |
if ( next ) |
+ { |
+ if ( char_code >= 0xFFFFFFFFUL ) |
+ return 0; |
+ |
char_code++; |
+ } |
min = 0; |
max = num_groups; |
@@ -2548,6 +2675,7 @@ |
if ( next ) |
{ |
+ FT_Face face = cmap->cmap.charmap.face; |
TT_CMap13 cmap13 = (TT_CMap13)cmap; |
@@ -2565,6 +2693,9 @@ |
cmap13->cur_charcode = char_code; |
cmap13->cur_group = mid; |
+ if ( gindex >= (FT_UInt)face->num_glyphs ) |
+ gindex = 0; |
+ |
if ( !gindex ) |
{ |
tt_cmap13_next( cmap13 ); |
@@ -2575,8 +2706,7 @@ |
else |
cmap13->cur_gindex = gindex; |
- if ( gindex ) |
- *pchar_code = cmap13->cur_charcode; |
+ *pchar_code = cmap13->cur_charcode; |
} |
return gindex; |
@@ -2599,18 +2729,14 @@ |
FT_UInt gindex; |
- if ( cmap13->cur_charcode >= 0xFFFFFFFFUL ) |
- return 0; |
- |
/* no need to search */ |
if ( cmap13->valid && cmap13->cur_charcode == *pchar_code ) |
{ |
tt_cmap13_next( cmap13 ); |
if ( cmap13->valid ) |
{ |
- gindex = cmap13->cur_gindex; |
- if ( gindex ) |
- *pchar_code = cmap13->cur_charcode; |
+ gindex = cmap13->cur_gindex; |
+ *pchar_code = cmap13->cur_charcode; |
} |
else |
gindex = 0; |
@@ -3496,7 +3622,7 @@ |
{ |
FT_ERROR(( "tt_face_build_cmaps:" |
" unsupported `cmap' table format = %d\n", |
- TT_PEEK_USHORT( p - 2) )); |
+ TT_PEEK_USHORT( p - 2 ) )); |
return FT_THROW( Invalid_Table ); |
} |