Commit 0d226c31c5f3ba8e3eb2cd5a86e5137d25c4cc64

suzuki toshiya 2009-08-01T00:30:24

base: Prevent some overflows on LP64 systems.

diff --git a/ChangeLog b/ChangeLog
index 95f68eb..2069c19 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,33 @@
 2009-07-31  suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
 
+	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 <mpsuzuki@hiroshima-u.ac.jp>
+
 	cff: Cast the long variables to 32-bit for LP64 systems.
 
 	* src/cff/cffdrivr.c (cff_get_advances): Insert
diff --git a/src/base/ftadvanc.c b/src/base/ftadvanc.c
index 504f9d2..8ab7fcb 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 04295a6..82fc4e6 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 6325af3..dead68e 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 9f51394..fdf433a 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;