ref: 913a36509099640dcbf5ace70b220d05eaa7b5c7
parent: 0d0d78dadc9ae38aa0aafbddb5f08d381b7d27cc
author: Werner Lemberg <[email protected]>
date: Sun Nov 19 04:19:17 EST 2006
Because FT_Load_Glyph expects CID values for CID-keyed fonts, the test for a valid glyph index must be deferred to the font drivers. This patch fixes Savannah bug #18301. * src/base/ftobjs.c (FT_Load_Glyph): Don't check `glyph_index'. * src/bdf/bdfdrivr.c (BDF_Glyph_Load), src/cff/cffgload.c (cff_slot_load), src/cid/cidgload.c (cid_slot_load_glyph), src/pcf/pcfdrivr.c (PCF_Glyph_Load), src/pfr/pfrobjs.c (pfr_slot_load), src/truetype/ttdriver.c (Load_Glyph), src/type1/t1gload.c (T1_Load_Glyph), src/winfonts/winfnt.c (FNT_Load_Glyph): Check validity of `glyph_index'.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2006-11-18 Werner Lemberg <[email protected]>
+
+ Because FT_Load_Glyph expects CID values for CID-keyed fonts, the
+ test for a valid glyph index must be deferred to the font drivers.
+ This patch fixes Savannah bug #18301.
+
+ * src/base/ftobjs.c (FT_Load_Glyph): Don't check `glyph_index'.
+ * src/bdf/bdfdrivr.c (BDF_Glyph_Load), src/cff/cffgload.c
+ (cff_slot_load), src/cid/cidgload.c (cid_slot_load_glyph),
+ src/pcf/pcfdrivr.c (PCF_Glyph_Load), src/pfr/pfrobjs.c
+ (pfr_slot_load), src/truetype/ttdriver.c (Load_Glyph),
+ src/type1/t1gload.c (T1_Load_Glyph), src/winfonts/winfnt.c
+ (FNT_Load_Glyph): Check validity of `glyph_index'.
+
2006-11-13 David Turner <[email protected]>
* src/truetype/ttinterp.c (FIX_BYTECODE): Undefine. The interpreter
--- a/src/base/ftcalc.c
+++ b/src/base/ftcalc.c
@@ -315,6 +315,23 @@
/* documentation is in freetype.h */
+ /* The FT_MulDiv function has been optimized thanks to ideas from */
+ /* Graham Asher. The trick is to optimize computation when everything */
+ /* fits within 32-bits (a rather common case). */
+ /* */
+ /* we compute 'a*b+c/2', then divide it by 'c'. (positive values) */
+ /* */
+ /* 46340 is FLOOR(SQRT(2^31-1)). */
+ /* */
+ /* if ( a <= 46340 && b <= 46340 ) then ( a*b <= 0x7FFEA810 ) */
+ /* */
+ /* 0x7FFFFFFF - 0x7FFEA810 = 0x157F0 */
+ /* */
+ /* if ( c < 0x157F0*2 ) then ( a*b+c/2 <= 0x7FFFFFFF ) */
+ /* */
+ /* and 2*0x157F0 = 176096 */
+ /* */
+
FT_EXPORT_DEF( FT_Long )
FT_MulDiv( FT_Long a,
FT_Long b,
@@ -551,7 +568,7 @@
/* apparently, the second version of this code is not compiled correctly */
- /* on Mac machines with the MPW C compiler.. tsk, tsk, tsk... */
+ /* on Mac machines with the MPW C compiler.. tsk, tsk, tsk... */
#if 1
@@ -588,7 +605,7 @@
if ( r >= (FT_UInt32)y ) /* we know y is to be treated as unsigned here */
return ( s < 0 ? 0x80000001UL : 0x7FFFFFFFUL );
/* Return Max/Min Int32 if division overflow. */
- /* This includes division by zero! */
+ /* This includes division by zero! */
q = 0;
for ( i = 0; i < 32; i++ )
{
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -549,8 +549,8 @@
if ( !face || !face->size || !face->glyph )
return FT_Err_Invalid_Face_Handle;
- if ( glyph_index >= (FT_UInt)face->num_glyphs )
- return FT_Err_Invalid_Argument;
+ /* The validity test for `glyph_index' is performed by the */
+ /* font drivers. */
slot = face->glyph;
ft_glyphslot_clear( slot );
--- a/src/bdf/bdfdrivr.c
+++ b/src/bdf/bdfdrivr.c
@@ -648,16 +648,17 @@
FT_UInt glyph_index,
FT_Int32 load_flags )
{
- BDF_Face face = (BDF_Face)FT_SIZE_FACE( size );
+ BDF_Face bdf = (BDF_Face)FT_SIZE_FACE( size );
+ FT_Face face = FT_FACE( bdf );
FT_Error error = BDF_Err_Ok;
FT_Bitmap* bitmap = &slot->bitmap;
bdf_glyph_t glyph;
- int bpp = face->bdffont->bpp;
+ int bpp = bdf->bdffont->bpp;
FT_UNUSED( load_flags );
- if ( !face )
+ if ( !face || glyph_index >= (FT_UInt)face->num_glyphs )
{
error = BDF_Err_Invalid_Argument;
goto Exit;
@@ -665,12 +666,12 @@
/* index 0 is the undefined glyph */
if ( glyph_index == 0 )
- glyph_index = face->default_glyph;
+ glyph_index = bdf->default_glyph;
else
glyph_index--;
/* slot, bitmap => freetype, glyph => bdflib */
- glyph = face->bdffont->glyphs[glyph_index];
+ glyph = bdf->bdffont->glyphs[glyph_index];
bitmap->rows = glyph.bbx.height;
bitmap->width = glyph.bbx.width;
@@ -712,7 +713,7 @@
* used here, provided such fonts do exist.
*/
ft_synthesize_vertical_metrics( &slot->metrics,
- face->bdffont->bbx.height << 6 );
+ bdf->bdffont->bbx.height << 6 );
Exit:
return error;
--- a/src/cff/cffgload.c
+++ b/src/cff/cffgload.c
@@ -2285,6 +2285,20 @@
FT_Vector font_offset;
+ /* in a CID-keyed font, consider `glyph_index' as a CID and map */
+ /* it immediately to the real glyph_index -- if it isn't a */
+ /* subsetted font, glyph_indices and CIDs are identical, though */
+ if ( cff->top_font.font_dict.cid_registry != 0xFFFFU &&
+ cff->charset.cids )
+ {
+ if ( glyph_index < cff->charset.max_cid )
+ glyph_index = cff->charset.cids[glyph_index];
+ else
+ return CFF_Err_Invalid_Argument;
+ }
+ else if ( glyph_index >= cff->num_glyphs )
+ return CFF_Err_Invalid_Argument;
+
if ( load_flags & FT_LOAD_NO_RECURSE )
load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
@@ -2375,18 +2389,6 @@
FT_Byte* charstring;
FT_ULong charstring_len;
-
- /* in a CID-keyed font, consider `glyph_index' as a CID and map */
- /* it immediately to the real glyph_index -- if it isn't a */
- /* subsetted font, glyph_indices and CIDs are identical, though */
- if ( cff->top_font.font_dict.cid_registry != 0xFFFFU &&
- cff->charset.cids )
- {
- if ( glyph_index < cff->charset.max_cid )
- glyph_index = cff->charset.cids[glyph_index];
- else
- glyph_index = 0;
- }
cff_decoder_init( &decoder, face, size, glyph, hinting,
FT_LOAD_TARGET_MODE( load_flags ) );
--- a/src/cff/cffload.c
+++ b/src/cff/cffload.c
@@ -1946,7 +1946,8 @@
encoding->count = 0;
- error = cff_charset_compute_cids( charset, num_glyphs, stream->memory );
+ error = cff_charset_compute_cids( charset, num_glyphs,
+ stream->memory );
if ( error )
goto Exit;
--- a/src/cid/cidgload.c
+++ b/src/cid/cidgload.c
@@ -275,6 +275,12 @@
FT_Vector font_offset;
+ if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
+ {
+ error = CID_Err_Invalid_Argument;
+ goto Exit;
+ }
+
if ( load_flags & FT_LOAD_NO_RECURSE )
load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
--- a/src/pcf/pcfdrivr.c
+++ b/src/pcf/pcfdrivr.c
@@ -442,7 +442,7 @@
FT_TRACE4(( "load_glyph %d ---", glyph_index ));
- if ( !face )
+ if ( !face || glyph_index >= (FT_UInt)face->root.num_glyphs )
{
error = PCF_Err_Invalid_Argument;
goto Exit;
--- a/src/pfr/pfrobjs.c
+++ b/src/pfr/pfrobjs.c
@@ -296,8 +296,11 @@
if ( gindex > 0 )
gindex--;
- /* check that the glyph index is correct */
- FT_ASSERT( gindex < face->phy_font.num_chars );
+ if ( !face || gindex >= face->phy_font.num_chars )
+ {
+ error = PFR_Err_Invalid_Argument;
+ goto Exit;
+ }
/* try to load an embedded bitmap */
if ( ( load_flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP ) ) == 0 )
--- a/src/truetype/ttdriver.c
+++ b/src/truetype/ttdriver.c
@@ -243,6 +243,7 @@
{
TT_GlyphSlot slot = (TT_GlyphSlot)ttslot;
TT_Size size = (TT_Size)ttsize;
+ FT_Face face = ttslot->face;
FT_Error error;
@@ -251,6 +252,9 @@
if ( !size )
return TT_Err_Invalid_Size_Handle;
+
+ if ( !face || glyph_index >= (FT_UInt)face->num_glyphs )
+ return TT_Err_Invalid_Argument;
if ( load_flags & ( FT_LOAD_NO_RECURSE | FT_LOAD_NO_SCALE ) )
{
--- a/src/type1/t1gload.c
+++ b/src/type1/t1gload.c
@@ -225,6 +225,12 @@
#endif
+ if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
+ {
+ error = T1_Err_Invalid_Argument;
+ goto Exit;
+ }
+
FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) );
if ( load_flags & FT_LOAD_NO_RECURSE )
--- a/src/winfonts/winfnt.c
+++ b/src/winfonts/winfnt.c
@@ -649,7 +649,8 @@
FT_UNUSED( load_flags );
- if ( !face || !font )
+ if ( !face || !font ||
+ glyph_index >= (FT_UInt)( FT_FACE( face )->num_glyphs ) )
{
error = FNT_Err_Invalid_Argument;
goto Exit;