Commit 94152819b0cdd134f51beb65e4dad21ba7a212ba

Werner Lemberg 2013-05-04T16:40:12

More fixes for clang's `sanitize' feature. * src/base/ftcalc.c (FT_DivFix): Use unsigned values for computations which use the left shift operator and convert to signed as the last step. * src/base/fttrigon.c (ft_trig_prenorm, FT_Vector_Rotate, FT_Vector_Length, FT_Vector_Polarize): Ditto. * src/cff/cffgload.c (cff_decoder_parse_charstrings): Simplify. * src/cff/cffload.c (cff_subfont_load): Fix constant. * src/cff/cffparse.c (cff_parse_integer, cff_parse_real, do_fixed, cff_parse_fixed_dynamic): Use unsigned values for computations which use the left shift operator and convert to signed as the last step. * src/cid/cidload.c (cid_get_offset): Ditto. * src/psaux/psconv.c (PS_Conv_ToFixed): Ditto. * src/psaux/t1decode.c (t1_decoder_parse_charstrings): Ditto. * src/truetype/ttinterp.c (TT_MulFix14, TT_DotFix14): Ditto.

diff --git a/ChangeLog b/ChangeLog
index abd34e3..11ab584 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,28 @@
 2013-05-04  Werner Lemberg  <wl@gnu.org>
 
+	More fixes for clang's `sanitize' feature.
+
+	* src/base/ftcalc.c (FT_DivFix): Use unsigned values for
+	computations which use the left shift operator and convert to signed
+	as the last step.
+	* src/base/fttrigon.c (ft_trig_prenorm, FT_Vector_Rotate,
+	FT_Vector_Length, FT_Vector_Polarize): Ditto.
+
+	* src/cff/cffgload.c (cff_decoder_parse_charstrings): Simplify.
+	* src/cff/cffload.c (cff_subfont_load): Fix constant.
+	* src/cff/cffparse.c (cff_parse_integer, cff_parse_real, do_fixed,
+	cff_parse_fixed_dynamic): Use unsigned values for computations which
+	use the left shift operator and convert to signed as the last step.
+
+	* src/cid/cidload.c (cid_get_offset): Ditto.
+
+	* src/psaux/psconv.c (PS_Conv_ToFixed): Ditto.
+	* src/psaux/t1decode.c (t1_decoder_parse_charstrings): Ditto.
+
+	* src/truetype/ttinterp.c (TT_MulFix14, TT_DotFix14): Ditto.
+
+2013-05-04  Werner Lemberg  <wl@gnu.org>
+
 	Fix errors reported by clang's `sanitize' feature.
 
 	* include/freetype/internal/ftstream.h: Simplify and fix integer
diff --git a/src/base/ftcalc.c b/src/base/ftcalc.c
index da80b5c..cadbeca 100644
--- a/src/base/ftcalc.c
+++ b/src/base/ftcalc.c
@@ -284,16 +284,25 @@
     FT_Int32   s;
     FT_UInt32  q;
 
+
     s = 1;
-    if ( a < 0 ) { a = -a; s = -1; }
-    if ( b < 0 ) { b = -b; s = -s; }
+    if ( a < 0 )
+    {
+      a = -a;
+      s = -1;
+    }
+    if ( b < 0 )
+    {
+      b = -b;
+      s = -s;
+    }
 
     if ( b == 0 )
       /* check for division by 0 */
       q = 0x7FFFFFFFL;
     else
       /* compute result directly */
-      q = (FT_UInt32)( ( ( (FT_Int64)a << 16 ) + ( b >> 1 ) ) / b );
+      q = (FT_UInt32)( ( ( (FT_UInt64)a << 16 ) + ( b >> 1 ) ) / b );
 
     return ( s < 0 ? -(FT_Long)q : (FT_Long)q );
   }
@@ -597,7 +606,7 @@
     else if ( ( a >> 16 ) == 0 )
     {
       /* compute result directly */
-      q = (FT_UInt32)( ( a << 16 ) + ( b >> 1 ) ) / (FT_UInt32)b;
+      q = (FT_UInt32)( ( (FT_ULong)a << 16 ) + ( b >> 1 ) ) / (FT_UInt32)b;
     }
     else
     {
@@ -605,8 +614,8 @@
       FT_Int64  temp, temp2;
 
 
-      temp.hi  = (FT_Int32) ( a >> 16 );
-      temp.lo  = (FT_UInt32)( a << 16 );
+      temp.hi  = (FT_Int32)( a >> 16 );
+      temp.lo  = (FT_UInt32)a << 16;
       temp2.hi = 0;
       temp2.lo = (FT_UInt32)( b >> 1 );
       FT_Add64( &temp, &temp2, &temp );
diff --git a/src/base/fttrigon.c b/src/base/fttrigon.c
index 4df6166..77521fe 100644
--- a/src/base/fttrigon.c
+++ b/src/base/fttrigon.c
@@ -131,8 +131,8 @@
     if ( shift <= FT_TRIG_SAFE_MSB )
     {
       shift  = FT_TRIG_SAFE_MSB - shift;
-      vec->x = x << shift;
-      vec->y = y << shift;
+      vec->x = (FT_Fixed)( (FT_UInt32)x << shift );
+      vec->y = (FT_Fixed)( (FT_UInt32)y << shift );
     }
     else
     {
@@ -392,8 +392,8 @@
       else
       {
         shift  = -shift;
-        vec->x = v.x << shift;
-        vec->y = v.y << shift;
+        vec->x = (FT_Fixed)( (FT_UInt32)v.x << shift );
+        vec->y = (FT_Fixed)( (FT_UInt32)v.y << shift );
       }
     }
   }
@@ -429,7 +429,7 @@
     if ( shift > 0 )
       return ( v.x + ( 1 << ( shift - 1 ) ) ) >> shift;
 
-    return v.x << -shift;
+    return (FT_Fixed)( (FT_UInt32)v.x << -shift );
   }
 
 
@@ -454,7 +454,8 @@
 
     v.x = ft_trig_downscale( v.x );
 
-    *length = ( shift >= 0 ) ? ( v.x >> shift ) : ( v.x << -shift );
+    *length = ( shift >= 0 ) ?                      ( v.x >>  shift )
+                             : (FT_Fixed)( (FT_UInt32)v.x << -shift );
     *angle  = v.y;
   }
 
diff --git a/src/cff/cffgload.c b/src/cff/cffgload.c
index 9a15107..0ca29d4 100644
--- a/src/cff/cffgload.c
+++ b/src/cff/cffgload.c
@@ -975,7 +975,7 @@
         {
           if ( ip + 1 >= limit )
             goto Syntax_Error;
-          val = (FT_Short)( ( (FT_UShort)ip[0] << 8 ) | ip[1] );
+          val = (FT_Short)( ( ip[0] << 8 ) | ip[1] );
           ip += 2;
         }
         else if ( v < 247 )
@@ -996,10 +996,10 @@
         {
           if ( ip + 3 >= limit )
             goto Syntax_Error;
-          val = (FT_Int32)( ( (FT_UInt32)ip[0] << 24 ) |
-                            ( (FT_UInt32)ip[1] << 16 ) |
-                            ( (FT_UInt32)ip[2] <<  8 ) |
-                              (FT_UInt32)ip[3] );
+          val = (FT_Int32)( ( ip[0] << 24 ) |
+                            ( ip[1] << 16 ) |
+                            ( ip[2] <<  8 ) |
+                              ip[3]         );
           ip    += 4;
           if ( charstring_type == 2 )
             shift = 0;
diff --git a/src/cff/cffload.c b/src/cff/cffload.c
index 6a303ff..64b4971 100644
--- a/src/cff/cffload.c
+++ b/src/cff/cffload.c
@@ -1314,7 +1314,7 @@
     /* set defaults */
     FT_MEM_ZERO( top, sizeof ( *top ) );
 
-    top->underline_position  = -100L << 16;
+    top->underline_position  = -( 100L << 16 );
     top->underline_thickness = 50L << 16;
     top->charstring_type     = 2;
     top->font_matrix.xx      = 0x10000L;
diff --git a/src/cff/cffparse.c b/src/cff/cffparse.c
index 319e61b..1c55cff 100644
--- a/src/cff/cffparse.c
+++ b/src/cff/cffparse.c
@@ -65,7 +65,7 @@
       if ( p + 2 > limit )
         goto Bad;
 
-      val = (FT_Short)( ( (FT_Int)p[0] << 8 ) | p[1] );
+      val = (FT_Short)( ( p[0] << 8 ) | p[1] );
       p  += 2;
     }
     else if ( v == 29 )
@@ -73,10 +73,10 @@
       if ( p + 4 > limit )
         goto Bad;
 
-      val = ( (FT_Long)p[0] << 24 ) |
-            ( (FT_Long)p[1] << 16 ) |
-            ( (FT_Long)p[2] <<  8 ) |
-                       p[3];
+      val = (FT_Long)( ( p[0] << 24 ) |
+                       ( p[1] << 16 ) |
+                       ( p[2] <<  8 ) |
+                         p[3]         );
       p += 4;
     }
     else if ( v < 247 )
@@ -316,7 +316,7 @@
           else
             exponent -= fraction_length;
 
-          result   = number << 16;
+          result   = (FT_Long)( (FT_ULong)number << 16 );
           *scaling = exponent;
         }
       }
@@ -373,7 +373,7 @@
         if ( number > 0x7FFFL )
           goto Overflow;
 
-        result = number << 16;
+        result = (FT_Long)( (FT_ULong)number << 16 );
       }
     }
 
@@ -435,7 +435,7 @@
         goto Overflow;
       }
 
-      return val << 16;
+      return (FT_Long)( (FT_ULong)val << 16 );
 
     Overflow:
       FT_TRACE4(( "!!!OVERFLOW:!!!" ));
@@ -501,7 +501,7 @@
       else
       {
         *scaling = 0;
-        return number << 16;
+        return (FT_Long)( (FT_ULong)number << 16 );
       }
     }
   }
diff --git a/src/cid/cidload.c b/src/cid/cidload.c
index 8ced316..f2a18ea 100644
--- a/src/cid/cidload.c
+++ b/src/cid/cidload.c
@@ -42,7 +42,7 @@
   cid_get_offset( FT_Byte*  *start,
                   FT_Byte    offsize )
   {
-    FT_Long   result;
+    FT_ULong  result;
     FT_Byte*  p = *start;
 
 
@@ -53,7 +53,7 @@
     }
 
     *start = p;
-    return result;
+    return (FT_Long)result;
   }
 
 
diff --git a/src/psaux/psconv.c b/src/psaux/psconv.c
index b7870c5..d0d8861 100644
--- a/src/psaux/psconv.c
+++ b/src/psaux/psconv.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Some convenience conversions (body).                                 */
 /*                                                                         */
-/*  Copyright 2006, 2008, 2009, 2012 by                                    */
+/*  Copyright 2006, 2008, 2009, 2012-2013 by                               */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -229,7 +229,7 @@
       if ( integral > 0x7FFF )
         have_overflow = 1;
       else
-        integral <<= 16;
+        integral = (FT_Fixed)( (FT_UInt32)integral << 16 );
     }
 
     /* read the decimal part */
diff --git a/src/psaux/t1decode.c b/src/psaux/t1decode.c
index a69af43..60d4d4b 100644
--- a/src/psaux/t1decode.c
+++ b/src/psaux/t1decode.c
@@ -565,10 +565,10 @@
           goto Syntax_Error;
         }
 
-        value = (FT_Int32)( ( (FT_Long)ip[0] << 24 ) |
-                            ( (FT_Long)ip[1] << 16 ) |
-                            ( (FT_Long)ip[2] << 8  ) |
-                                       ip[3]         );
+        value = (FT_Int32)( ( ip[0] << 24 ) |
+                            ( ip[1] << 16 ) |
+                            ( ip[2] << 8  ) |
+                              ip[3]         );
         ip += 4;
 
         /* According to the specification, values > 32000 or < -32000 must */
@@ -591,7 +591,7 @@
         else
         {
           if ( !large_int )
-            value <<= 16;
+            value = (FT_Int32)( (FT_UInt32)value << 16 );
         }
 
         break;
@@ -611,13 +611,13 @@
             }
 
             if ( ip[-2] < 251 )
-              value =  ( ( (FT_Int32)ip[-2] - 247 ) << 8 ) + ip[-1] + 108;
+              value =    ( ( ip[-2] - 247 ) * 256 ) + ip[-1] + 108;
             else
-              value = -( ( ( (FT_Int32)ip[-2] - 251 ) << 8 ) + ip[-1] + 108 );
+              value = -( ( ( ip[-2] - 251 ) * 256 ) + ip[-1] + 108 );
           }
 
           if ( !large_int )
-            value <<= 16;
+            value = (FT_Int32)( (FT_UInt32)value << 16 );
         }
         else
         {
diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c
index dd90cc8..872894d 100644
--- a/src/truetype/ttinterp.c
+++ b/src/truetype/ttinterp.c
@@ -1479,7 +1479,7 @@
     l  = (FT_UInt32)( ( a & 0xFFFFU ) * b );
     m  = ( a >> 16 ) * b;
 
-    lo = l + (FT_UInt32)( m << 16 );
+    lo = l + ( (FT_UInt32)m << 16 );
     hi = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo < l );
 
     /* divide the result by 2^14 with rounding */
@@ -1491,7 +1491,7 @@
     l   = lo + 0x2000U;
     hi += l < lo;
 
-    return ( hi << 18 ) | ( l >> 14 );
+    return (FT_Int32)( ( (FT_UInt32)hi << 18 ) | ( l >> 14 ) );
   }
 #endif
 
@@ -1511,14 +1511,14 @@
     l = (FT_UInt32)( ( ax & 0xFFFFU ) * bx );
     m = ( ax >> 16 ) * bx;
 
-    lo1 = l + (FT_UInt32)( m << 16 );
+    lo1 = l + ( (FT_UInt32)m << 16 );
     hi1 = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo1 < l );
 
     /* compute ay*by as 64-bit value */
     l = (FT_UInt32)( ( ay & 0xFFFFU ) * by );
     m = ( ay >> 16 ) * by;
 
-    lo2 = l + (FT_UInt32)( m << 16 );
+    lo2 = l + ( (FT_UInt32)m << 16 );
     hi2 = ( m >> 16 ) + ( (FT_Int32)l >> 31 ) + ( lo2 < l );
 
     /* add them */
@@ -1534,7 +1534,7 @@
     l   = lo + 0x2000U;
     hi += ( l < lo );
 
-    return ( hi << 18 ) | ( l >> 14 );
+    return (FT_Int32)( ( (FT_UInt32)hi << 18 ) | ( l >> 14 ) );
   }