| Index: third_party/freetype/src/sfnt/ttcmap.c
|
| diff --git a/core/src/fxge/fx_freetype/fxft2.5.01/src/sfnt/ttcmap.c b/third_party/freetype/src/sfnt/ttcmap.c
|
| similarity index 97%
|
| rename from core/src/fxge/fx_freetype/fxft2.5.01/src/sfnt/ttcmap.c
|
| rename to third_party/freetype/src/sfnt/ttcmap.c
|
| index b79d0ad508854ba717b081b49e9abe2704935f6a..ece9ef11235ff288cddfa6a430e2085666dcf50f 100644
|
| --- a/core/src/fxge/fx_freetype/fxft2.5.01/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, 2013 by */
|
| +/* Copyright 2002-2010, 2012-2014 by */
|
| /* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
| /* */
|
| /* This file is part of the FreeType project, and may only be used, */
|
| @@ -16,13 +16,13 @@
|
| /***************************************************************************/
|
|
|
|
|
| -#include "../../include/ft2build.h"
|
| -#include "../../include/freetype/internal/ftdebug.h"
|
| +#include <ft2build.h>
|
| +#include FT_INTERNAL_DEBUG_H
|
|
|
| #include "sferrors.h" /* must come before FT_INTERNAL_VALIDATE_H */
|
|
|
| -#include "../../include/freetype/internal/ftvalid.h"
|
| -#include "../../include/freetype/internal/ftstream.h"
|
| +#include FT_INTERNAL_VALIDATE_H
|
| +#include FT_INTERNAL_STREAM_H
|
| #include "ttload.h"
|
| #include "ttcmap.h"
|
| #include "sfntpic.h"
|
| @@ -88,9 +88,15 @@
|
| tt_cmap0_validate( FT_Byte* table,
|
| FT_Validator valid )
|
| {
|
| - FT_Byte* p = table + 2;
|
| - FT_UInt length = TT_NEXT_USHORT( p );
|
| + FT_Byte* p;
|
| + FT_UInt length;
|
| +
|
| +
|
| + if ( table + 2 + 2 > valid->limit )
|
| + FT_INVALID_TOO_SHORT;
|
|
|
| + p = table + 2; /* skip format */
|
| + length = TT_NEXT_USHORT( p );
|
|
|
| if ( table + length > valid->limit || length < 262 )
|
| FT_INVALID_TOO_SHORT;
|
| @@ -279,13 +285,20 @@
|
| tt_cmap2_validate( FT_Byte* table,
|
| FT_Validator valid )
|
| {
|
| - FT_Byte* p = table + 2; /* skip format */
|
| - FT_UInt length = TT_PEEK_USHORT( p );
|
| + FT_Byte* p;
|
| + FT_UInt length;
|
| +
|
| FT_UInt n, max_subs;
|
| - FT_Byte* keys; /* keys table */
|
| - FT_Byte* subs; /* sub-headers */
|
| - FT_Byte* glyph_ids; /* glyph ID array */
|
| + FT_Byte* keys; /* keys table */
|
| + FT_Byte* subs; /* sub-headers */
|
| + FT_Byte* glyph_ids; /* glyph ID array */
|
| +
|
|
|
| + if ( table + 2 + 2 > valid->limit )
|
| + FT_INVALID_TOO_SHORT;
|
| +
|
| + p = table + 2; /* skip format */
|
| + length = TT_NEXT_USHORT( p );
|
|
|
| if ( table + length > valid->limit || length < 6 + 512 )
|
| FT_INVALID_TOO_SHORT;
|
| @@ -320,9 +333,8 @@
|
| /* parse sub-headers */
|
| for ( n = 0; n <= max_subs; n++ )
|
| {
|
| - FT_UInt first_code, code_count, offset;
|
| - FT_Int delta;
|
| - FT_Byte* ids;
|
| + FT_UInt first_code, code_count, offset;
|
| + FT_Int delta;
|
|
|
|
|
| first_code = TT_NEXT_USHORT( p );
|
| @@ -344,6 +356,9 @@
|
| /* check offset */
|
| if ( offset != 0 )
|
| {
|
| + FT_Byte* ids;
|
| +
|
| +
|
| ids = p - 2 + offset;
|
| if ( ids < glyph_ids || ids + code_count*2 > table + length )
|
| FT_INVALID_OFFSET;
|
| @@ -816,16 +831,20 @@
|
| tt_cmap4_validate( FT_Byte* table,
|
| FT_Validator valid )
|
| {
|
| - FT_Byte* p = table + 2; /* skip format */
|
| - FT_UInt length = TT_NEXT_USHORT( p );
|
| + FT_Byte* p;
|
| + FT_UInt length;
|
| +
|
| FT_Byte *ends, *starts, *offsets, *deltas, *glyph_ids;
|
| FT_UInt num_segs;
|
| FT_Error error = FT_Err_Ok;
|
|
|
|
|
| - if ( length < 16 )
|
| + if ( table + 2 + 2 > valid->limit )
|
| FT_INVALID_TOO_SHORT;
|
|
|
| + p = table + 2; /* skip format */
|
| + length = TT_NEXT_USHORT( p );
|
| +
|
| /* in certain fonts, the `length' field is invalid and goes */
|
| /* out of bound. We try to correct this here... */
|
| if ( table + length > valid->limit )
|
| @@ -836,6 +855,9 @@
|
| length = (FT_UInt)( valid->limit - table );
|
| }
|
|
|
| + if ( length < 16 )
|
| + FT_INVALID_TOO_SHORT;
|
| +
|
| p = table + 6;
|
| num_segs = TT_NEXT_USHORT( p ); /* read segCountX2 */
|
|
|
| @@ -1647,7 +1669,8 @@
|
| p = is32 + 8192; /* skip `is32' array */
|
| num_groups = TT_NEXT_ULONG( p );
|
|
|
| - if ( p + num_groups * 12 > valid->limit )
|
| + /* p + num_groups * 12 > valid->limit ? */
|
| + if ( num_groups > (FT_UInt32)( valid->limit - p ) / 12 )
|
| FT_INVALID_TOO_SHORT;
|
|
|
| /* check groups, they must be in increasing order */
|
| @@ -1672,7 +1695,12 @@
|
|
|
| if ( valid->level >= FT_VALIDATE_TIGHT )
|
| {
|
| - if ( start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) )
|
| + FT_UInt32 d = end - start;
|
| +
|
| +
|
| + /* start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) ? */
|
| + if ( d > TT_VALID_GLYPH_COUNT( valid ) ||
|
| + start_id >= TT_VALID_GLYPH_COUNT( valid ) - d )
|
| FT_INVALID_GLYPH_ID;
|
|
|
| count = (FT_UInt32)( end - start + 1 );
|
| @@ -1870,7 +1898,9 @@
|
| count = TT_NEXT_ULONG( p );
|
|
|
| if ( length > (FT_ULong)( valid->limit - table ) ||
|
| - length < 20 + count * 2 )
|
| + /* length < 20 + count * 2 ? */
|
| + length < 20 ||
|
| + ( length - 20 ) / 2 < count )
|
| FT_INVALID_TOO_SHORT;
|
|
|
| /* check glyph indices */
|
| @@ -2042,9 +2072,9 @@
|
| tt_cmap12_validate( FT_Byte* table,
|
| FT_Validator valid )
|
| {
|
| - FT_Byte* p;
|
| - FT_ULong length;
|
| - FT_ULong num_groups;
|
| + FT_Byte* p;
|
| + FT_ULong length;
|
| + FT_ULong num_groups;
|
|
|
|
|
| if ( table + 16 > valid->limit )
|
| @@ -2057,7 +2087,9 @@
|
| num_groups = TT_NEXT_ULONG( p );
|
|
|
| if ( length > (FT_ULong)( valid->limit - table ) ||
|
| - length < 16 + 12 * num_groups )
|
| + /* length < 16 + 12 * num_groups ? */
|
| + length < 16 ||
|
| + ( length - 16 ) / 12 < num_groups )
|
| FT_INVALID_TOO_SHORT;
|
|
|
| /* check groups, they must be in increasing order */
|
| @@ -2079,7 +2111,12 @@
|
|
|
| if ( valid->level >= FT_VALIDATE_TIGHT )
|
| {
|
| - if ( start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) )
|
| + FT_UInt32 d = end - start;
|
| +
|
| +
|
| + /* start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) ? */
|
| + if ( d > TT_VALID_GLYPH_COUNT( valid ) ||
|
| + start_id >= TT_VALID_GLYPH_COUNT( valid ) - d )
|
| FT_INVALID_GLYPH_ID;
|
| }
|
|
|
| @@ -2108,8 +2145,6 @@
|
|
|
| char_code = cmap->cur_charcode + 1;
|
|
|
| - n = cmap->cur_group;
|
| -
|
| for ( n = cmap->cur_group; n < cmap->num_groups; n++ )
|
| {
|
| p = cmap->cmap.data + 16 + 12 * n;
|
| @@ -2381,7 +2416,9 @@
|
| num_groups = TT_NEXT_ULONG( p );
|
|
|
| if ( length > (FT_ULong)( valid->limit - table ) ||
|
| - length < 16 + 12 * num_groups )
|
| + /* length < 16 + 12 * num_groups ? */
|
| + length < 16 ||
|
| + ( length - 16 ) / 12 < num_groups )
|
| FT_INVALID_TOO_SHORT;
|
|
|
| /* check groups, they must be in increasing order */
|
| @@ -2432,8 +2469,6 @@
|
|
|
| char_code = cmap->cur_charcode + 1;
|
|
|
| - n = cmap->cur_group;
|
| -
|
| for ( n = cmap->cur_group; n < cmap->num_groups; n++ )
|
| {
|
| p = cmap->cmap.data + 16 + 12 * n;
|
| @@ -2756,13 +2791,22 @@
|
| tt_cmap14_validate( FT_Byte* table,
|
| FT_Validator valid )
|
| {
|
| - FT_Byte* p = table + 2;
|
| - FT_ULong length = TT_NEXT_ULONG( p );
|
| - FT_ULong num_selectors = TT_NEXT_ULONG( p );
|
| + FT_Byte* p;
|
| + FT_ULong length;
|
| + FT_ULong num_selectors;
|
| +
|
| +
|
| + if ( table + 2 + 4 + 4 > valid->limit )
|
| + FT_INVALID_TOO_SHORT;
|
|
|
| + p = table + 2;
|
| + length = TT_NEXT_ULONG( p );
|
| + num_selectors = TT_NEXT_ULONG( p );
|
|
|
| if ( length > (FT_ULong)( valid->limit - table ) ||
|
| - length < 10 + 11 * num_selectors )
|
| + /* length < 10 + 11 * num_selectors ? */
|
| + length < 10 ||
|
| + ( length - 10 ) / 11 < num_selectors )
|
| FT_INVALID_TOO_SHORT;
|
|
|
| /* check selectors, they must be in increasing order */
|
| @@ -2798,7 +2842,8 @@
|
| FT_ULong lastBase = 0;
|
|
|
|
|
| - if ( defp + numRanges * 4 > valid->limit )
|
| + /* defp + numRanges * 4 > valid->limit ? */
|
| + if ( numRanges > (FT_ULong)( valid->limit - defp ) / 4 )
|
| FT_INVALID_TOO_SHORT;
|
|
|
| for ( i = 0; i < numRanges; ++i )
|
| @@ -2825,7 +2870,8 @@
|
| FT_ULong i, lastUni = 0;
|
|
|
|
|
| - if ( numMappings * 4 > (FT_ULong)( valid->limit - ndp ) )
|
| + /* numMappings * 4 > (FT_ULong)( valid->limit - ndp ) ? */
|
| + if ( numMappings > ( (FT_ULong)( valid->limit - ndp ) ) / 4 )
|
| FT_INVALID_TOO_SHORT;
|
|
|
| for ( i = 0; i < numMappings; ++i )
|
| @@ -3208,7 +3254,6 @@
|
| {
|
| FT_Byte *p = tt_cmap14_find_variant( cmap->data + 6,
|
| variantSelector );
|
| - FT_UInt32 *ret;
|
| FT_Int i;
|
| FT_ULong defOff;
|
| FT_ULong nondefOff;
|
| @@ -3242,6 +3287,8 @@
|
| FT_Byte* dp;
|
| FT_UInt di, ni, k;
|
|
|
| + FT_UInt32 *ret;
|
| +
|
|
|
| p = cmap->data + nondefOff;
|
| dp = cmap->data + defOff;
|
| @@ -3447,23 +3494,14 @@
|
| /* only recognize format 0 */
|
| if ( TT_NEXT_USHORT( p ) != 0 )
|
| {
|
| - p -= 2;
|
| FT_ERROR(( "tt_face_build_cmaps:"
|
| " unsupported `cmap' table format = %d\n",
|
| - TT_PEEK_USHORT( p ) ));
|
| + TT_PEEK_USHORT( p - 2) ));
|
| return FT_THROW( Invalid_Table );
|
| }
|
|
|
| num_cmaps = TT_NEXT_USHORT( p );
|
|
|
| -#ifdef FT_MAX_CHARMAP_CACHEABLE
|
| - if ( num_cmaps > FT_MAX_CHARMAP_CACHEABLE )
|
| - FT_ERROR(( "tt_face_build_cmaps: too many cmap subtables (%d)\n"
|
| - " subtable #%d and higher are loaded"
|
| - " but cannot be searched\n",
|
| - num_cmaps, FT_MAX_CHARMAP_CACHEABLE + 1 ));
|
| -#endif
|
| -
|
| for ( ; num_cmaps > 0 && p + 8 <= limit; num_cmaps-- )
|
| {
|
| FT_CharMapRec charmap;
|
| @@ -3497,15 +3535,12 @@
|
| FT_VALIDATE_DEFAULT );
|
|
|
| valid.num_glyphs = (FT_UInt)face->max_profile.numGlyphs;
|
| -#ifndef _FX_MANAGED_CODE_
|
| +
|
| if ( ft_setjmp( FT_VALIDATOR( &valid )->jump_buffer) == 0 )
|
| {
|
| -#endif
|
| /* validate this cmap sub-table */
|
| error = clazz->validate( cmap, FT_VALIDATOR( &valid ) );
|
| -#ifndef _FX_MANAGED_CODE_
|
| - }
|
| -#endif
|
| + }
|
|
|
| if ( valid.validator.error == 0 )
|
| {
|
|
|