diff options
Diffstat (limited to 'third_party/freetype/src/sfnt')
26 files changed, 542 insertions, 295 deletions
diff --git a/third_party/freetype/src/sfnt/Jamfile b/third_party/freetype/src/sfnt/Jamfile index cb20b1b04b..cc98d1011e 100644 --- a/third_party/freetype/src/sfnt/Jamfile +++ b/third_party/freetype/src/sfnt/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/sfnt Jamfile # -# Copyright 2001, 2002, 2004, 2005 by +# Copyright 2001-2015 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -16,7 +16,18 @@ SubDir FT2_TOP $(FT2_SRC_DIR) sfnt ; if $(FT2_MULTI) { - _sources = sfobjs sfdriver ttcmap ttmtx ttpost ttload ttsbit ttkern ttbdf sfntpic ; + _sources = pngshim + sfdriver + sfntpic + sfobjs + ttbdf + ttcmap + ttkern + ttload + ttmtx + ttpost + ttsbit + ; } else { diff --git a/third_party/freetype/src/sfnt/pngshim.c b/third_party/freetype/src/sfnt/pngshim.c index 9bfcc2a779..ea60452635 100644 --- a/third_party/freetype/src/sfnt/pngshim.c +++ b/third_party/freetype/src/sfnt/pngshim.c @@ -4,7 +4,8 @@ /* */ /* PNG Bitmap glyph support. */ /* */ -/* Copyright 2013, 2014 by Google, Inc. */ +/* Copyright 2013-2015 by */ +/* Google, Inc. */ /* Written by Stuart Gill and Behdad Esfahbod. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -36,11 +37,11 @@ /* This code is freely based on cairo-png.c. There's so many ways */ /* to call libpng, and the way cairo does it is defacto standard. */ - static int - multiply_alpha( int alpha, - int color ) + static unsigned int + multiply_alpha( unsigned int alpha, + unsigned int color ) { - int temp = ( alpha * color ) + 0x80; + unsigned int temp = alpha * color + 0x80; return ( temp + ( temp >> 8 ) ) >> 8; @@ -81,10 +82,10 @@ blue = multiply_alpha( alpha, blue ); } - base[0] = blue; - base[1] = green; - base[2] = red; - base[3] = alpha; + base[0] = (unsigned char)blue; + base[1] = (unsigned char)green; + base[2] = (unsigned char)red; + base[3] = (unsigned char)alpha; } } } @@ -109,9 +110,9 @@ unsigned int blue = base[2]; - base[0] = blue; - base[1] = green; - base[2] = red; + base[0] = (unsigned char)blue; + base[1] = (unsigned char)green; + base[2] = (unsigned char)red; base[3] = 0xFF; } } @@ -257,16 +258,16 @@ if ( populate_map_and_metrics ) { - FT_Long size; + FT_ULong size; - metrics->width = (FT_Int)imgWidth; - metrics->height = (FT_Int)imgHeight; + metrics->width = (FT_UShort)imgWidth; + metrics->height = (FT_UShort)imgHeight; map->width = metrics->width; map->rows = metrics->height; map->pixel_mode = FT_PIXEL_MODE_BGRA; - map->pitch = map->width * 4; + map->pitch = (int)( map->width * 4 ); map->num_grays = 256; /* reject too large bitmaps similarly to the rasterizer */ @@ -277,7 +278,7 @@ } /* this doesn't overflow: 0x7FFF * 0x7FFF * 4 < 2^32 */ - size = map->rows * map->pitch; + size = map->rows * (FT_ULong)map->pitch; error = ft_glyphslot_alloc_bitmap( slot, size ); if ( error ) diff --git a/third_party/freetype/src/sfnt/pngshim.h b/third_party/freetype/src/sfnt/pngshim.h index dc9ecaf918..4cc5c2b3a0 100644 --- a/third_party/freetype/src/sfnt/pngshim.h +++ b/third_party/freetype/src/sfnt/pngshim.h @@ -4,7 +4,8 @@ /* */ /* PNG Bitmap glyph support. */ /* */ -/* Copyright 2013 by Google, Inc. */ +/* Copyright 2013-2015 by */ +/* Google, Inc. */ /* Written by Stuart Gill and Behdad Esfahbod. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/sfnt/sfdriver.c b/third_party/freetype/src/sfnt/sfdriver.c index bd8dd2e571..6a3f0d9933 100644 --- a/third_party/freetype/src/sfnt/sfdriver.c +++ b/third_party/freetype/src/sfnt/sfdriver.c @@ -4,7 +4,7 @@ /* */ /* High-level SFNT driver interface (body). */ /* */ -/* Copyright 1996-2007, 2009-2014 by */ +/* Copyright 1996-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -266,7 +266,7 @@ { FT_Stream stream = face->name_table.stream; FT_String* r = (FT_String*)result; - FT_Byte* p; + FT_Char* p; if ( FT_STREAM_SEEK( name->stringOffset ) || @@ -280,11 +280,11 @@ goto Exit; } - p = (FT_Byte*)stream->cursor; + p = (FT_Char*)stream->cursor; for ( ; len > 0; len--, p += 2 ) { - if ( p[0] == 0 && p[1] >= 32 && p[1] < 128 ) + if ( p[0] == 0 && p[1] >= 32 ) *r++ = p[1]; } *r = '\0'; @@ -427,7 +427,7 @@ sfnt_get_interface( FT_Module module, const char* module_interface ) { - /* SFNT_SERVICES_GET derefers `library' in PIC mode */ + /* SFNT_SERVICES_GET dereferences `library' in PIC mode */ #ifdef FT_CONFIG_OPTION_PIC FT_Library library; @@ -505,7 +505,9 @@ PUT_EMBEDDED_BITMAPS( tt_face_set_sbit_strike ), PUT_EMBEDDED_BITMAPS( tt_face_load_strike_metrics ), - tt_face_get_metrics + tt_face_get_metrics, + + tt_face_get_name ) diff --git a/third_party/freetype/src/sfnt/sfdriver.h b/third_party/freetype/src/sfnt/sfdriver.h index 5de25d51ca..944119cc22 100644 --- a/third_party/freetype/src/sfnt/sfdriver.h +++ b/third_party/freetype/src/sfnt/sfdriver.h @@ -4,7 +4,7 @@ /* */ /* High-level SFNT driver interface (specification). */ /* */ -/* Copyright 1996-2001 by */ +/* Copyright 1996-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/sfnt/sferrors.h b/third_party/freetype/src/sfnt/sferrors.h index e981e1d26f..e3bef3f743 100644 --- a/third_party/freetype/src/sfnt/sferrors.h +++ b/third_party/freetype/src/sfnt/sferrors.h @@ -4,7 +4,7 @@ /* */ /* SFNT error codes (specification only). */ /* */ -/* Copyright 2001, 2004, 2012, 2013 by */ +/* Copyright 2001-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/sfnt/sfnt.c b/third_party/freetype/src/sfnt/sfnt.c index d62ed4e0b5..0b8b5f4578 100644 --- a/third_party/freetype/src/sfnt/sfnt.c +++ b/third_party/freetype/src/sfnt/sfnt.c @@ -4,7 +4,7 @@ /* */ /* Single object library component. */ /* */ -/* Copyright 1996-2006, 2013 by */ +/* Copyright 1996-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/sfnt/sfntpic.c b/third_party/freetype/src/sfnt/sfntpic.c index b3fb24b3f0..2aaf4bcc40 100644 --- a/third_party/freetype/src/sfnt/sfntpic.c +++ b/third_party/freetype/src/sfnt/sfntpic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for sfnt module. */ /* */ -/* Copyright 2009, 2010, 2012, 2013 by */ +/* Copyright 2009-2015 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/sfnt/sfntpic.h b/third_party/freetype/src/sfnt/sfntpic.h index b09a9141e0..d99be6a824 100644 --- a/third_party/freetype/src/sfnt/sfntpic.h +++ b/third_party/freetype/src/sfnt/sfntpic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for sfnt module. */ /* */ -/* Copyright 2009, 2012 by */ +/* Copyright 2009-2015 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,8 +20,6 @@ #define __SFNTPIC_H__ -FT_BEGIN_HEADER - #include FT_INTERNAL_PIC_H @@ -31,7 +29,6 @@ FT_BEGIN_HEADER #define SFNT_SERVICE_GLYPH_DICT_GET sfnt_service_glyph_dict #define SFNT_SERVICE_PS_NAME_GET sfnt_service_ps_name #define TT_SERVICE_CMAP_INFO_GET tt_service_get_cmap_info -#define SFNT_SERVICES_GET sfnt_services #define TT_CMAP_CLASSES_GET tt_cmap_classes #define SFNT_SERVICE_SFNT_TABLE_GET sfnt_service_sfnt_table #define SFNT_SERVICE_BDF_GET sfnt_service_bdf @@ -56,6 +53,8 @@ FT_BEGIN_HEADER #include "ttcmap.h" +FT_BEGIN_HEADER + typedef struct sfntModulePIC_ { FT_ServiceDescRec* sfnt_services; @@ -83,8 +82,6 @@ FT_BEGIN_HEADER ( GET_PIC( library )->sfnt_service_ps_name ) #define TT_SERVICE_CMAP_INFO_GET \ ( GET_PIC( library )->tt_service_get_cmap_info ) -#define SFNT_SERVICES_GET \ - ( GET_PIC( library )->sfnt_services ) #define TT_CMAP_CLASSES_GET \ ( GET_PIC( library )->tt_cmap_classes ) #define SFNT_SERVICE_SFNT_TABLE_GET \ @@ -102,12 +99,13 @@ FT_BEGIN_HEADER FT_Error sfnt_module_class_pic_init( FT_Library library ); + +FT_END_HEADER + #endif /* FT_CONFIG_OPTION_PIC */ /* */ -FT_END_HEADER - #endif /* __SFNTPIC_H__ */ diff --git a/third_party/freetype/src/sfnt/sfobjs.c b/third_party/freetype/src/sfnt/sfobjs.c index 70b988d650..14d3adef21 100644 --- a/third_party/freetype/src/sfnt/sfobjs.c +++ b/third_party/freetype/src/sfnt/sfobjs.c @@ -4,7 +4,7 @@ /* */ /* SFNT object management (base). */ /* */ -/* Copyright 1996-2008, 2010-2014 by */ +/* Copyright 1996-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -120,27 +120,9 @@ FT_Memory memory ); - /*************************************************************************/ - /* */ - /* <Function> */ - /* tt_face_get_name */ - /* */ - /* <Description> */ - /* Returns a given ENGLISH name record in ASCII. */ - /* */ - /* <Input> */ - /* face :: A handle to the source face object. */ - /* */ - /* nameid :: The name id of the name record to return. */ - /* */ - /* <InOut> */ - /* name :: The address of a string pointer. NULL if no name is */ - /* present. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - static FT_Error + /* documentation is in sfnt.h */ + + FT_LOCAL_DEF( FT_Error ) tt_face_get_name( TT_Face face, FT_UShort nameid, FT_String** name ) @@ -376,8 +358,8 @@ FT_FREE( stream->base ); stream->size = 0; - stream->base = 0; - stream->close = 0; + stream->base = NULL; + stream->close = NULL; } @@ -580,8 +562,8 @@ table->OrigOffset = sfnt_offset; /* The offsets must be multiples of 4. */ - woff_offset += ( table->CompLength + 3 ) & ~3; - sfnt_offset += ( table->OrigLength + 3 ) & ~3; + woff_offset += ( table->CompLength + 3 ) & ~3U; + sfnt_offset += ( table->OrigLength + 3 ) & ~3U; } /* @@ -609,7 +591,7 @@ if ( woff.privOffset ) { /* ... if it isn't the last block. */ - woff_offset = ( woff_offset + 3 ) & ~3; + woff_offset = ( woff_offset + 3 ) & ~3U; if ( woff.privOffset != woff_offset || woff.privOffset + woff.privLength > woff.length ) @@ -839,13 +821,14 @@ FT_LOCAL_DEF( FT_Error ) sfnt_init_face( FT_Stream stream, TT_Face face, - FT_Int face_index, + FT_Int face_instance_index, FT_Int num_params, FT_Parameter* params ) { - FT_Error error; - FT_Library library = face->root.driver->root.library; - SFNT_Service sfnt; + FT_Error error; + FT_Library library = face->root.driver->root.library; + SFNT_Service sfnt; + FT_Int face_index; /* for now, parameters are unused */ @@ -878,22 +861,65 @@ /* Stream may have changed in sfnt_open_font. */ stream = face->root.stream; - FT_TRACE2(( "sfnt_init_face: %08p, %ld\n", face, face_index )); + FT_TRACE2(( "sfnt_init_face: %08p, %ld\n", face, face_instance_index )); - if ( face_index < 0 ) - face_index = 0; + face_index = FT_ABS( face_instance_index ) & 0xFFFF; if ( face_index >= face->ttc_header.count ) - return FT_THROW( Invalid_Argument ); + { + if ( face_instance_index >= 0 ) + return FT_THROW( Invalid_Argument ); + else + face_index = 0; + } if ( FT_STREAM_SEEK( face->ttc_header.offsets[face_index] ) ) return error; - /* check that we have a valid TrueType file */ + /* check whether we have a valid TrueType file */ error = sfnt->load_font_dir( face, stream ); if ( error ) return error; +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + { + FT_ULong fvar_len; + FT_UShort num_instances; + FT_Int instance_index; + + + instance_index = FT_ABS( face_instance_index ) >> 16; + + /* test whether current face is a GX font with named instances */ + if ( face->goto_table( face, TTAG_fvar, stream, &fvar_len ) || + fvar_len < 20 || + FT_STREAM_SKIP( 12 ) || + FT_READ_USHORT( num_instances ) ) + num_instances = 0; + + /* we support at most 2^15 - 1 instances */ + if ( num_instances >= ( 1U << 15 ) - 1 ) + { + if ( face_instance_index >= 0 ) + return FT_THROW( Invalid_Argument ); + else + num_instances = 0; + } + + /* instance indices in `face_instance_index' start with index 1, */ + /* thus `>' and not `>=' */ + if ( instance_index > num_instances ) + { + if ( face_instance_index >= 0 ) + return FT_THROW( Invalid_Argument ); + else + num_instances = 0; + } + + face->root.style_flags = (FT_Long)num_instances << 16; + } +#endif + face->root.num_faces = face->ttc_header.count; face->root.face_index = face_index; @@ -946,7 +972,7 @@ FT_LOCAL_DEF( FT_Error ) sfnt_load_face( FT_Stream stream, TT_Face face, - FT_Int face_index, + FT_Int face_instance_index, FT_Int num_params, FT_Parameter* params ) { @@ -962,7 +988,7 @@ SFNT_Service sfnt = (SFNT_Service)face->sfnt; - FT_UNUSED( face_index ); + FT_UNUSED( face_instance_index ); /* Check parameters */ @@ -1284,7 +1310,7 @@ flags |= FT_STYLE_FLAG_ITALIC; } - root->style_flags = flags; + root->style_flags |= flags; /*********************************************************************/ /* */ @@ -1431,8 +1457,8 @@ root->ascender = face->horizontal.Ascender; root->descender = face->horizontal.Descender; - root->height = (FT_Short)( root->ascender - root->descender + - face->horizontal.Line_Gap ); + root->height = root->ascender - root->descender + + face->horizontal.Line_Gap; if ( !( root->ascender || root->descender ) ) { @@ -1443,23 +1469,24 @@ root->ascender = face->os2.sTypoAscender; root->descender = face->os2.sTypoDescender; - root->height = (FT_Short)( root->ascender - root->descender + - face->os2.sTypoLineGap ); + root->height = root->ascender - root->descender + + face->os2.sTypoLineGap; } else { root->ascender = (FT_Short)face->os2.usWinAscent; root->descender = -(FT_Short)face->os2.usWinDescent; - root->height = (FT_UShort)( root->ascender - root->descender ); + root->height = root->ascender - root->descender; } } } - root->max_advance_width = face->horizontal.advance_Width_Max; - root->max_advance_height = (FT_Short)( face->vertical_info - ? face->vertical.advance_Height_Max - : root->height ); + root->max_advance_width = + (FT_Short)face->horizontal.advance_Width_Max; + root->max_advance_height = + (FT_Short)( face->vertical_info ? face->vertical.advance_Height_Max + : root->height ); /* See http://www.microsoft.com/OpenType/OTSpec/post.htm -- */ /* Adjust underline position from top edge to centre of */ @@ -1569,7 +1596,7 @@ FT_FREE( face->postscript_name ); - face->sfnt = 0; + face->sfnt = NULL; } diff --git a/third_party/freetype/src/sfnt/sfobjs.h b/third_party/freetype/src/sfnt/sfobjs.h index 6241c93b39..455f86772f 100644 --- a/third_party/freetype/src/sfnt/sfobjs.h +++ b/third_party/freetype/src/sfnt/sfobjs.h @@ -4,7 +4,7 @@ /* */ /* SFNT object management (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -31,20 +31,25 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) sfnt_init_face( FT_Stream stream, TT_Face face, - FT_Int face_index, + FT_Int face_instance_index, FT_Int num_params, FT_Parameter* params ); FT_LOCAL( FT_Error ) sfnt_load_face( FT_Stream stream, TT_Face face, - FT_Int face_index, + FT_Int face_instance_index, FT_Int num_params, FT_Parameter* params ); FT_LOCAL( void ) sfnt_done_face( TT_Face face ); + FT_LOCAL( FT_Error ) + tt_face_get_name( TT_Face face, + FT_UShort nameid, + FT_String** name ); + FT_END_HEADER diff --git a/third_party/freetype/src/sfnt/ttbdf.c b/third_party/freetype/src/sfnt/ttbdf.c index 9401dae5f8..098b781a14 100644 --- a/third_party/freetype/src/sfnt/ttbdf.c +++ b/third_party/freetype/src/sfnt/ttbdf.c @@ -4,7 +4,7 @@ /* */ /* TrueType and OpenType embedded BDF properties (body). */ /* */ -/* Copyright 2005, 2006, 2010, 2013 by */ +/* Copyright 2005-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/sfnt/ttbdf.h b/third_party/freetype/src/sfnt/ttbdf.h index 48a10d6e9b..fe4ba489e8 100644 --- a/third_party/freetype/src/sfnt/ttbdf.h +++ b/third_party/freetype/src/sfnt/ttbdf.h @@ -4,7 +4,7 @@ /* */ /* TrueType and OpenType embedded BDF properties (specification). */ /* */ -/* Copyright 2005 by */ +/* Copyright 2005-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/sfnt/ttcmap.c b/third_party/freetype/src/sfnt/ttcmap.c index ece9ef1123..c4d9abdfe6 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 ); } diff --git a/third_party/freetype/src/sfnt/ttcmap.h b/third_party/freetype/src/sfnt/ttcmap.h index 0fde1676bf..b7ea8ee377 100644 --- a/third_party/freetype/src/sfnt/ttcmap.h +++ b/third_party/freetype/src/sfnt/ttcmap.h @@ -4,7 +4,7 @@ /* */ /* TrueType character mapping table (cmap) support (specification). */ /* */ -/* Copyright 2002-2005, 2009, 2012 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, */ diff --git a/third_party/freetype/src/sfnt/ttcmapc.h b/third_party/freetype/src/sfnt/ttcmapc.h index 2ea204309c..4a489402cf 100644 --- a/third_party/freetype/src/sfnt/ttcmapc.h +++ b/third_party/freetype/src/sfnt/ttcmapc.h @@ -4,7 +4,7 @@ /* */ /* TT CMAP classes definitions (specification only). */ /* */ -/* Copyright 2009 by */ +/* Copyright 2009-2015 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/sfnt/ttkern.c b/third_party/freetype/src/sfnt/ttkern.c index 455e7b5e3d..4fccc535ce 100644 --- a/third_party/freetype/src/sfnt/ttkern.c +++ b/third_party/freetype/src/sfnt/ttkern.c @@ -5,7 +5,7 @@ /* Load the basic TrueType kerning table. This doesn't handle */ /* kerning data within the GPOS table at the moment. */ /* */ -/* Copyright 1996-2007, 2009, 2010, 2013 by */ +/* Copyright 1996-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -108,8 +108,8 @@ p_next = p_limit; /* only use horizontal kerning tables */ - if ( ( coverage & ~8 ) != 0x0001 || - p + 8 > p_limit ) + if ( ( coverage & ~8U ) != 0x0001 || + p + 8 > p_limit ) goto NextTable; num_pairs = FT_NEXT_USHORT( p ); diff --git a/third_party/freetype/src/sfnt/ttkern.h b/third_party/freetype/src/sfnt/ttkern.h index df1da9b273..89cb24f07c 100644 --- a/third_party/freetype/src/sfnt/ttkern.h +++ b/third_party/freetype/src/sfnt/ttkern.h @@ -5,7 +5,7 @@ /* Load the basic TrueType kerning table. This doesn't handle */ /* kerning data within the GPOS table at the moment. */ /* */ -/* Copyright 1996-2001, 2002, 2005, 2007 by */ +/* Copyright 1996-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/sfnt/ttload.c b/third_party/freetype/src/sfnt/ttload.c index 8338150abd..c1bd7f0c82 100644 --- a/third_party/freetype/src/sfnt/ttload.c +++ b/third_party/freetype/src/sfnt/ttload.c @@ -5,7 +5,7 @@ /* Load the basic TrueType tables, i.e., tables that can be either in */ /* TTF or OTF fonts (body). */ /* */ -/* Copyright 1996-2010, 2012-2014 by */ +/* Copyright 1996-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -151,7 +151,8 @@ /* Here, we */ /* */ - /* - check that `num_tables' is valid (and adjust it if necessary) */ + /* - check that `num_tables' is valid (and adjust it if necessary); */ + /* also return the number of valid table entries */ /* */ /* - look for a `head' table, check its size, and parse it to check */ /* whether its `magic' field is correctly set */ @@ -167,7 +168,8 @@ /* */ static FT_Error check_table_dir( SFNT_Header sfnt, - FT_Stream stream ) + FT_Stream stream, + FT_UShort* valid ) { FT_Error error; FT_UShort nn, valid_entries = 0; @@ -208,13 +210,27 @@ /* we ignore invalid tables */ - /* table.Offset + table.Length > stream->size ? */ - if ( table.Length > stream->size || - table.Offset > stream->size - table.Length ) + if ( table.Offset > stream->size ) { FT_TRACE2(( "check_table_dir: table entry %d invalid\n", nn )); continue; } + else if ( table.Length > stream->size - table.Offset ) + { + /* Some tables have such a simple structure that clipping its */ + /* contents is harmless. This also makes FreeType less sensitive */ + /* to invalid table lengths (which programs like Acroread seem to */ + /* ignore in general). */ + + if ( table.Tag == TTAG_hmtx || + table.Tag == TTAG_vmtx ) + valid_entries++; + else + { + FT_TRACE2(( "check_table_dir: table entry %d invalid\n", nn )); + continue; + } + } else valid_entries++; @@ -262,11 +278,11 @@ has_meta = 1; } - sfnt->num_tables = valid_entries; + *valid = valid_entries; - if ( sfnt->num_tables == 0 ) + if ( !valid_entries ) { - FT_TRACE2(( "check_table_dir: no tables found\n" )); + FT_TRACE2(( "check_table_dir: no valid tables found\n" )); error = FT_THROW( Unknown_File_Format ); goto Exit; } @@ -322,8 +338,7 @@ SFNT_HeaderRec sfnt; FT_Error error; FT_Memory memory = stream->memory; - TT_TableRec* entry; - FT_Int nn; + FT_UShort nn, valid_entries; static const FT_Frame_Field offset_table_fields[] = { @@ -364,59 +379,114 @@ if ( sfnt.format_tag != TTAG_OTTO ) { /* check first */ - error = check_table_dir( &sfnt, stream ); + error = check_table_dir( &sfnt, stream, &valid_entries ); if ( error ) { FT_TRACE2(( "tt_face_load_font_dir:" " invalid table directory for TrueType\n" )); - goto Exit; } } + else + valid_entries = sfnt.num_tables; - face->num_tables = sfnt.num_tables; + face->num_tables = valid_entries; face->format_tag = sfnt.format_tag; if ( FT_QNEW_ARRAY( face->dir_tables, face->num_tables ) ) goto Exit; - if ( FT_STREAM_SEEK( sfnt.offset + 12 ) || - FT_FRAME_ENTER( face->num_tables * 16L ) ) + if ( FT_STREAM_SEEK( sfnt.offset + 12 ) || + FT_FRAME_ENTER( sfnt.num_tables * 16L ) ) goto Exit; - entry = face->dir_tables; - FT_TRACE2(( "\n" " tag offset length checksum\n" " ----------------------------------\n" )); + valid_entries = 0; for ( nn = 0; nn < sfnt.num_tables; nn++ ) { - entry->Tag = FT_GET_TAG4(); - entry->CheckSum = FT_GET_ULONG(); - entry->Offset = FT_GET_ULONG(); - entry->Length = FT_GET_ULONG(); + TT_TableRec entry; + FT_UShort i; + FT_Bool duplicate; - /* ignore invalid tables */ - /* entry->Offset + entry->Length > stream->size ? */ - if ( entry->Length > stream->size || - entry->Offset > stream->size - entry->Length ) + entry.Tag = FT_GET_TAG4(); + entry.CheckSum = FT_GET_ULONG(); + entry.Offset = FT_GET_ULONG(); + entry.Length = FT_GET_ULONG(); + + /* ignore invalid tables that can't be sanitized */ + + if ( entry.Offset > stream->size ) continue; + else if ( entry.Length > stream->size - entry.Offset ) + { + if ( entry.Tag == TTAG_hmtx || + entry.Tag == TTAG_vmtx ) + { +#ifdef FT_DEBUG_LEVEL_TRACE + FT_ULong old_length = entry.Length; +#endif + + + /* make metrics table length a multiple of 4 */ + entry.Length = ( stream->size - entry.Offset ) & ~3U; + + FT_TRACE2(( " %c%c%c%c %08lx %08lx %08lx" + " (sanitized; original length %08lx)", + (FT_Char)( entry.Tag >> 24 ), + (FT_Char)( entry.Tag >> 16 ), + (FT_Char)( entry.Tag >> 8 ), + (FT_Char)( entry.Tag ), + entry.Offset, + entry.Length, + entry.CheckSum, + old_length )); + } + else + continue; + } +#ifdef FT_DEBUG_LEVEL_TRACE else + FT_TRACE2(( " %c%c%c%c %08lx %08lx %08lx", + (FT_Char)( entry.Tag >> 24 ), + (FT_Char)( entry.Tag >> 16 ), + (FT_Char)( entry.Tag >> 8 ), + (FT_Char)( entry.Tag ), + entry.Offset, + entry.Length, + entry.CheckSum )); +#endif + + /* ignore duplicate tables – the first one wins */ + duplicate = 0; + for ( i = 0; i < valid_entries; i++ ) { - FT_TRACE2(( " %c%c%c%c %08lx %08lx %08lx\n", - (FT_Char)( entry->Tag >> 24 ), - (FT_Char)( entry->Tag >> 16 ), - (FT_Char)( entry->Tag >> 8 ), - (FT_Char)( entry->Tag ), - entry->Offset, - entry->Length, - entry->CheckSum )); - entry++; + if ( face->dir_tables[i].Tag == entry.Tag ) + { + duplicate = 1; + break; + } + } + if ( duplicate ) + { + FT_TRACE2(( " (duplicate, ignored)\n" )); + continue; + } + else + { + FT_TRACE2(( "\n" )); + + /* we finally have a valid entry */ + face->dir_tables[valid_entries++] = entry; } } + /* final adjustment to number of tables */ + face->num_tables = valid_entries; + FT_FRAME_EXIT(); FT_TRACE2(( "table directory loaded\n\n" )); diff --git a/third_party/freetype/src/sfnt/ttload.h b/third_party/freetype/src/sfnt/ttload.h index 49a1aee163..a6d91c5b70 100644 --- a/third_party/freetype/src/sfnt/ttload.h +++ b/third_party/freetype/src/sfnt/ttload.h @@ -5,7 +5,7 @@ /* Load the basic TrueType tables, i.e., tables that can be either in */ /* TTF or OTF fonts (specification). */ /* */ -/* Copyright 1996-2001, 2002, 2005, 2006 by */ +/* Copyright 1996-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/sfnt/ttmtx.c b/third_party/freetype/src/sfnt/ttmtx.c index bb319577e2..58309aa496 100644 --- a/third_party/freetype/src/sfnt/ttmtx.c +++ b/third_party/freetype/src/sfnt/ttmtx.c @@ -4,7 +4,7 @@ /* */ /* Load the metrics tables common to TTF and OTF fonts (body). */ /* */ -/* Copyright 2006-2009, 2011-2014 by */ +/* Copyright 2006-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/sfnt/ttmtx.h b/third_party/freetype/src/sfnt/ttmtx.h index fb040394c0..096ee062cf 100644 --- a/third_party/freetype/src/sfnt/ttmtx.h +++ b/third_party/freetype/src/sfnt/ttmtx.h @@ -4,7 +4,7 @@ /* */ /* Load the metrics tables common to TTF and OTF fonts (specification). */ /* */ -/* Copyright 2006, 2014 by */ +/* Copyright 2006-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/sfnt/ttpost.c b/third_party/freetype/src/sfnt/ttpost.c index 99d800549f..8d29d1e9f6 100644 --- a/third_party/freetype/src/sfnt/ttpost.c +++ b/third_party/freetype/src/sfnt/ttpost.c @@ -5,7 +5,7 @@ /* Postcript name table processing for TrueType and OpenType fonts */ /* (body). */ /* */ -/* Copyright 1996-2003, 2006-2010, 2013, 2014 by */ +/* Copyright 1996-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -52,7 +52,7 @@ #include FT_SERVICE_POSTSCRIPT_CMAPS_H -#define MAC_NAME( x ) ( (FT_String*)psnames->macintosh_name( x ) ) +#define MAC_NAME( x ) (FT_String*)psnames->macintosh_name( (FT_UInt)(x) ) #else /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */ @@ -62,7 +62,7 @@ /* table of Mac names. Thus, it is possible to build a version of */ /* FreeType without the Type 1 driver & PSNames module. */ -#define MAC_NAME( x ) ( (FT_String*)tt_post_default_names[x] ) +#define MAC_NAME( x ) (FT_String*)tt_post_default_names[x] /* the 258 default Mac PS glyph names; see file `tools/glnames.py' */ @@ -155,7 +155,7 @@ static FT_Error load_format_20( TT_Face face, FT_Stream stream, - FT_Long post_limit ) + FT_ULong post_limit ) { FT_Memory memory = stream->memory; FT_Error error; @@ -163,8 +163,8 @@ FT_Int num_glyphs; FT_UShort num_names; - FT_UShort* glyph_indices = 0; - FT_Char** name_strings = 0; + FT_UShort* glyph_indices = NULL; + FT_Char** name_strings = NULL; if ( FT_READ_USHORT( num_glyphs ) ) @@ -243,14 +243,17 @@ goto Fail1; } - if ( (FT_Int)len > post_limit || - FT_STREAM_POS() > post_limit - (FT_Int)len ) + if ( len > post_limit || + FT_STREAM_POS() > post_limit - len ) { + FT_Int d = (FT_Int)post_limit - (FT_Int)FT_STREAM_POS(); + + FT_ERROR(( "load_format_20:" " exceeding string length (%d)," " truncating at end of post table (%d byte left)\n", - len, post_limit - FT_STREAM_POS() )); - len = FT_MAX( 0, post_limit - FT_STREAM_POS() ); + len, d )); + len = (FT_UInt)FT_MAX( 0, d ); } if ( FT_NEW_ARRAY( name_strings[n], len + 1 ) || @@ -307,13 +310,13 @@ static FT_Error load_format_25( TT_Face face, FT_Stream stream, - FT_Long post_limit ) + FT_ULong post_limit ) { FT_Memory memory = stream->memory; FT_Error error; FT_Int num_glyphs; - FT_Char* offset_table = 0; + FT_Char* offset_table = NULL; FT_UNUSED( post_limit ); @@ -377,7 +380,7 @@ FT_Error error; FT_Fixed format; FT_ULong post_len; - FT_Long post_limit; + FT_ULong post_limit; /* get a stream for the face's resource */ @@ -547,10 +550,7 @@ } if ( idx < (FT_UInt)table->num_glyphs ) /* paranoid checking */ - { - idx += table->offsets[idx]; - *PSname = MAC_NAME( idx ); - } + *PSname = MAC_NAME( (FT_Int)idx + table->offsets[idx] ); } /* nothing to do for format == 0x00030000L */ diff --git a/third_party/freetype/src/sfnt/ttpost.h b/third_party/freetype/src/sfnt/ttpost.h index 6f06d75a71..e3eca02c62 100644 --- a/third_party/freetype/src/sfnt/ttpost.h +++ b/third_party/freetype/src/sfnt/ttpost.h @@ -5,7 +5,7 @@ /* Postcript name table processing for TrueType and OpenType fonts */ /* (specification). */ /* */ -/* Copyright 1996-2001, 2002 by */ +/* Copyright 1996-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/third_party/freetype/src/sfnt/ttsbit.c b/third_party/freetype/src/sfnt/ttsbit.c index c2db96c6d8..3b351ecfce 100644 --- a/third_party/freetype/src/sfnt/ttsbit.c +++ b/third_party/freetype/src/sfnt/ttsbit.c @@ -4,7 +4,7 @@ /* */ /* TrueType and OpenType embedded bitmap support (body). */ /* */ -/* Copyright 2005-2009, 2013, 2014 by */ +/* Copyright 2005-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* Copyright 2013 by Google, Inc. */ @@ -101,10 +101,10 @@ p = face->sbit_table; - version = FT_NEXT_ULONG( p ); + version = FT_NEXT_LONG( p ); num_strikes = FT_NEXT_ULONG( p ); - if ( ( version & 0xFFFF0000UL ) != 0x00020000UL ) + if ( ( (FT_ULong)version & 0xFFFF0000UL ) != 0x00020000UL ) { error = FT_THROW( Unknown_File_Format ); goto Exit; @@ -254,15 +254,15 @@ metrics->x_ppem = (FT_UShort)strike[44]; metrics->y_ppem = (FT_UShort)strike[45]; - metrics->ascender = (FT_Char)strike[16] << 6; /* hori.ascender */ - metrics->descender = (FT_Char)strike[17] << 6; /* hori.descender */ + metrics->ascender = (FT_Char)strike[16] * 64; /* hori.ascender */ + metrics->descender = (FT_Char)strike[17] * 64; /* hori.descender */ metrics->height = metrics->ascender - metrics->descender; /* Is this correct? */ metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB */ strike[18] + /* max_width */ (FT_Char)strike[23] /* min_advance_SB */ - ) << 6; + ) * 64; return FT_Err_Ok; } @@ -273,6 +273,7 @@ FT_UShort ppem, resolution; TT_HoriHeader *hori; FT_ULong table_size; + FT_Pos ppem_, upem_; /* to reduce casts */ FT_Error error; FT_Byte* p; @@ -305,12 +306,15 @@ metrics->x_ppem = ppem; metrics->y_ppem = ppem; - metrics->ascender = ppem * hori->Ascender * 64 / upem; - metrics->descender = ppem * hori->Descender * 64 / upem; - metrics->height = ppem * ( hori->Ascender - - hori->Descender + - hori->Line_Gap ) * 64 / upem; - metrics->max_advance = ppem * hori->advance_Width_Max * 64 / upem; + ppem_ = (FT_Pos)ppem; + upem_ = (FT_Pos)upem; + + metrics->ascender = ppem_ * hori->Ascender * 64 / upem_; + metrics->descender = ppem_ * hori->Descender * 64 / upem_; + metrics->height = ppem_ * ( hori->Ascender - + hori->Descender + + hori->Line_Gap ) * 64 / upem_; + metrics->max_advance = ppem_ * hori->advance_Width_Max * 64 / upem_; return error; } @@ -420,7 +424,7 @@ FT_Error error = FT_Err_Ok; FT_UInt width, height; FT_Bitmap* map = decoder->bitmap; - FT_Long size; + FT_ULong size; if ( !decoder->metrics_loaded ) @@ -432,38 +436,38 @@ width = decoder->metrics->width; height = decoder->metrics->height; - map->width = (int)width; - map->rows = (int)height; + map->width = width; + map->rows = height; switch ( decoder->bit_depth ) { case 1: map->pixel_mode = FT_PIXEL_MODE_MONO; - map->pitch = ( map->width + 7 ) >> 3; + map->pitch = (int)( ( map->width + 7 ) >> 3 ); map->num_grays = 2; break; case 2: map->pixel_mode = FT_PIXEL_MODE_GRAY2; - map->pitch = ( map->width + 3 ) >> 2; + map->pitch = (int)( ( map->width + 3 ) >> 2 ); map->num_grays = 4; break; case 4: map->pixel_mode = FT_PIXEL_MODE_GRAY4; - map->pitch = ( map->width + 1 ) >> 1; + map->pitch = (int)( ( map->width + 1 ) >> 1 ); map->num_grays = 16; break; case 8: map->pixel_mode = FT_PIXEL_MODE_GRAY; - map->pitch = map->width; + map->pitch = (int)( map->width ); map->num_grays = 256; break; case 32: map->pixel_mode = FT_PIXEL_MODE_BGRA; - map->pitch = map->width * 4; + map->pitch = (int)( map->width * 4 ); map->num_grays = 256; break; @@ -472,7 +476,7 @@ goto Exit; } - size = map->rows * map->pitch; + size = map->rows * (FT_ULong)map->pitch; /* check that there is no empty image */ if ( size == 0 ) @@ -561,7 +565,8 @@ { FT_Error error = FT_Err_Ok; FT_Byte* line; - FT_Int bit_height, bit_width, pitch, width, height, line_bits, h; + FT_Int pitch, width, height, line_bits, h; + FT_UInt bit_height, bit_width; FT_Bitmap* bitmap; @@ -577,8 +582,8 @@ line_bits = width * decoder->bit_depth; - if ( x_pos < 0 || x_pos + width > bit_width || - y_pos < 0 || y_pos + height > bit_height ) + if ( x_pos < 0 || (FT_UInt)( x_pos + width ) > bit_width || + y_pos < 0 || (FT_UInt)( y_pos + height ) > bit_height ) { FT_TRACE1(( "tt_sbit_decoder_load_byte_aligned:" " invalid bitmap dimensions\n" )); @@ -699,7 +704,8 @@ { FT_Error error = FT_Err_Ok; FT_Byte* line; - FT_Int bit_height, bit_width, pitch, width, height, line_bits, h, nbits; + FT_Int pitch, width, height, line_bits, h, nbits; + FT_UInt bit_height, bit_width; FT_Bitmap* bitmap; FT_UShort rval; @@ -716,8 +722,8 @@ line_bits = width * decoder->bit_depth; - if ( x_pos < 0 || x_pos + width > bit_width || - y_pos < 0 || y_pos + height > bit_height ) + if ( x_pos < 0 || (FT_UInt)( x_pos + width ) > bit_width || + y_pos < 0 || (FT_UInt)( y_pos + height ) > bit_height ) { FT_TRACE1(( "tt_sbit_decoder_load_bit_aligned:" " invalid bitmap dimensions\n" )); @@ -1379,9 +1385,9 @@ metrics->horiBearingX = (FT_Short)originOffsetX; metrics->horiBearingY = (FT_Short)( -originOffsetY + metrics->height ); - metrics->horiAdvance = (FT_Short)( aadvance * - face->root.size->metrics.x_ppem / - face->header.Units_Per_EM ); + metrics->horiAdvance = (FT_UShort)( aadvance * + face->root.size->metrics.x_ppem / + face->header.Units_Per_EM ); } return error; @@ -1442,7 +1448,7 @@ FT_Library library = face->root.glyph->library; - FT_Bitmap_New( &new_map ); + FT_Bitmap_Init( &new_map ); /* Convert to 8bit grayscale. */ error = FT_Bitmap_Convert( library, map, &new_map, 1 ); diff --git a/third_party/freetype/src/sfnt/ttsbit.h b/third_party/freetype/src/sfnt/ttsbit.h index 695d0d8d02..d4e13aefb8 100644 --- a/third_party/freetype/src/sfnt/ttsbit.h +++ b/third_party/freetype/src/sfnt/ttsbit.h @@ -4,7 +4,7 @@ /* */ /* TrueType and OpenType embedded bitmap support (specification). */ /* */ -/* Copyright 1996-2008, 2013 by */ +/* Copyright 1996-2015 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ |