diff --git a/ChangeLog b/ChangeLog index 95f68ebc..2069c190 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,31 @@ +2009-07-31 suzuki toshiya + + base: Prevent some overflows on LP64 systems. + + * src/base/ftadvance.c (FT_Get_Advances): Cast the + unsigned long constant FT_LOAD_ADVANCE_ONLY to FT_UInt32 + for LP64 platforms. + + * src/base/ftcalc.c (FT_Sqrt32): All internal variables + are changed to FT_UInt32 from FT_ULong. + (FT_MulDiv): Insert casts to FT_Int32 for LP64 platforms. + This function is designed for 32-bit integer, although + their arguments and return value are FT_Long. + + * src/base/ftobjs.c (FT_Get_Char_Index): Check `charcode' + is within unsigned 32-bit integer for LP64 platforms. + (FT_Face_GetCharVariantIndex): Check `charcode' and + `variantSelector' are within 32-bit integer for LP64 + platforms. + (FT_Face_GetCharsOfVariant): Check `variantSelector' is + within unsigned 32-bit integer for LP64 platforms. + + * src/base/fttrigon.c (ft_trig_downscale): The FT_Fixed + variable `val' and unsigned long constant FT_TRIG_SCALE + are casted to FT_UInt32, when calculates FT_UInt32. + (FT_Vector_Rotate): The long constant 1L is casted to + FT_Int32 to calculate FT_Int32 `half'. + 2009-07-31 suzuki toshiya cff: Cast the long variables to 32-bit for LP64 systems. diff --git a/src/base/ftadvanc.c b/src/base/ftadvanc.c index 504f9d23..8ab7fcb9 100644 --- a/src/base/ftadvanc.c +++ b/src/base/ftadvanc.c @@ -140,7 +140,7 @@ if ( flags & FT_ADVANCE_FLAG_FAST_ONLY ) return FT_Err_Unimplemented_Feature; - flags |= FT_LOAD_ADVANCE_ONLY; + flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY; for ( nn = 0; nn < count; nn++ ) { error = FT_Load_Glyph( face, start + nn, flags ); diff --git a/src/base/ftcalc.c b/src/base/ftcalc.c index 04295a69..82fc4e6b 100644 --- a/src/base/ftcalc.c +++ b/src/base/ftcalc.c @@ -110,12 +110,12 @@ FT_EXPORT_DEF( FT_Int32 ) FT_Sqrt32( FT_Int32 x ) { - FT_ULong val, root, newroot, mask; + FT_UInt32 val, root, newroot, mask; root = 0; - mask = 0x40000000L; - val = (FT_ULong)x; + mask = (FT_UInt32)0x40000000UL; + val = (FT_UInt32)x; do { @@ -362,6 +362,7 @@ long s; + /* XXX: this function does not allow 64-bit arguments */ if ( a == 0 || b == c ) return a; @@ -377,12 +378,12 @@ FT_Int64 temp, temp2; - ft_multo64( a, b, &temp ); + ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp ); temp2.hi = 0; temp2.lo = (FT_UInt32)(c >> 1); FT_Add64( &temp, &temp2, &temp ); - a = ft_div64by32( temp.hi, temp.lo, c ); + a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c ); } else a = 0x7FFFFFFFL; @@ -416,8 +417,8 @@ FT_Int64 temp; - ft_multo64( a, b, &temp ); - a = ft_div64by32( temp.hi, temp.lo, c ); + ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp ); + a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c ); } else a = 0x7FFFFFFFL; @@ -539,13 +540,14 @@ FT_UInt32 q; - s = a; a = FT_ABS( a ); - s ^= b; b = FT_ABS( b ); + /* XXX: this function does not allow 64-bit arguments */ + s = (FT_Int32)a; a = FT_ABS( a ); + s ^= (FT_Int32)b; b = FT_ABS( b ); if ( b == 0 ) { /* check for division by 0 */ - q = 0x7FFFFFFFL; + q = (FT_UInt32)0x7FFFFFFFL; } else if ( ( a >> 16 ) == 0 ) { @@ -562,7 +564,7 @@ temp2.hi = 0; temp2.lo = (FT_UInt32)( b >> 1 ); FT_Add64( &temp, &temp2, &temp ); - q = ft_div64by32( temp.hi, temp.lo, b ); + q = ft_div64by32( temp.hi, temp.lo, (FT_Int32)b ); } return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); @@ -889,8 +891,9 @@ FT_Int64 z1, z2; - ft_multo64( in_x, out_y, &z1 ); - ft_multo64( in_y, out_x, &z2 ); + /* XXX: this function does not allow 64-bit arguments */ + ft_multo64( (FT_Int32)in_x, (FT_Int32)out_y, &z1 ); + ft_multo64( (FT_Int32)in_y, (FT_Int32)out_x, &z2 ); if ( z1.hi > z2.hi ) result = +1; diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index 6325af36..dead68e3 100644 --- a/src/base/ftobjs.c +++ b/src/base/ftobjs.c @@ -3054,7 +3054,12 @@ FT_CMap cmap = FT_CMAP( face->charmap ); - result = cmap->clazz->char_index( cmap, charcode ); + if ( charcode > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); + FT_TRACE1(( " 0x%x is truncated\n", charcode )); + } + result = cmap->clazz->char_index( cmap, (FT_UInt32)charcode ); } return result; } @@ -3134,8 +3139,20 @@ FT_CMap vcmap = FT_CMAP( charmap ); - result = vcmap->clazz->char_var_index( vcmap, ucmap, charcode, - variantSelector ); + if ( charcode > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); + FT_TRACE1(( " 0x%x is truncated\n", charcode )); + } + if ( variantSelector > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" )); + FT_TRACE1(( " 0x%x is truncated\n", variantSelector )); + } + + result = vcmap->clazz->char_var_index( vcmap, ucmap, + (FT_UInt32)charcode, + (FT_UInt32)variantSelector ); } } @@ -3163,8 +3180,20 @@ FT_CMap vcmap = FT_CMAP( charmap ); - result = vcmap->clazz->char_var_default( vcmap, charcode, - variantSelector ); + if ( charcode > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); + FT_TRACE1(( " 0x%x is truncated\n", charcode )); + } + if ( variantSelector > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" )); + FT_TRACE1(( " 0x%x is truncated\n", variantSelector )); + } + + result = vcmap->clazz->char_var_default( vcmap, + (FT_UInt32)charcode, + (FT_UInt32)variantSelector ); } } @@ -3219,7 +3248,14 @@ FT_Memory memory = FT_FACE_MEMORY( face ); - result = vcmap->clazz->charvariant_list( vcmap, memory, charcode ); + if ( charcode > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); + FT_TRACE1(( " 0x%x is truncated\n", charcode )); + } + + result = vcmap->clazz->charvariant_list( vcmap, memory, + (FT_UInt32)charcode ); } } return result; @@ -3246,8 +3282,14 @@ FT_Memory memory = FT_FACE_MEMORY( face ); + if ( variantSelector > 0xFFFFFFFFUL ) + { + FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" )); + FT_TRACE1(( " 0x%x is truncated\n", variantSelector )); + } + result = vcmap->clazz->variantchar_list( vcmap, memory, - variantSelector ); + (FT_UInt32)variantSelector ); } } diff --git a/src/base/fttrigon.c b/src/base/fttrigon.c index 9f513946..fdf433ab 100644 --- a/src/base/fttrigon.c +++ b/src/base/fttrigon.c @@ -72,10 +72,10 @@ val = ( val >= 0 ) ? val : -val; v1 = (FT_UInt32)val >> 16; - v2 = (FT_UInt32)val & 0xFFFFL; + v2 = (FT_UInt32)(val & 0xFFFFL); - k1 = FT_TRIG_SCALE >> 16; /* constant */ - k2 = FT_TRIG_SCALE & 0xFFFFL; /* constant */ + k1 = (FT_UInt32)FT_TRIG_SCALE >> 16; /* constant */ + k2 = (FT_UInt32)(FT_TRIG_SCALE & 0xFFFFL); /* constant */ hi = k1 * v1; lo1 = k1 * v2 + k2 * v1; /* can't overflow */ @@ -86,7 +86,7 @@ hi += lo1 >> 16; if ( lo1 < lo3 ) - hi += 0x10000UL; + hi += (FT_UInt32)0x10000UL; val = (FT_Fixed)hi; @@ -433,7 +433,7 @@ if ( shift > 0 ) { - FT_Int32 half = 1L << ( shift - 1 ); + FT_Int32 half = (FT_Int32)1L << ( shift - 1 ); vec->x = ( v.x + half + FT_SIGN_LONG( v.x ) ) >> shift;