Commit 248eaa4f601381bdcb584c16a370b5e0ad553613

Werner Lemberg 2017-01-03T00:27:07

Various fixes for clang's undefined behaviour sanitizer. * src/cff/cffload.c (FT_fdot14ToFixed): Fix casting. (cff_blend_doBlend): Don't left-shift negative numbers. Handle 5-byte numbers byte by byte to avoid alignment issues. * src/cff/cffparse.c (cff_parse): Handle 5-byte numbers byte by byte to avoid alignment issues. * src/cid/cidload (cid_read_subrs): Do nothing if we don't have any subrs. * src/psaux/t1decode.c (t1_decode_parse_charstring): Fix tracing. * src/tools/glnames.py (main): Put `DEFINE_PSTABLES' guard around definition of `ft_get_adobe_glyph_index'. * src/psnames/pstables.h: Regenerated. * src/psnames/psmodule.c: Inlude `pstables.h' twice to get both declaration and definition. * src/truetype/ttgxvar.c (FT_fdot14ToFixed, FT_intToFixed): Fix casting.

diff --git a/ChangeLog b/ChangeLog
index e0ac556..c13c48e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,30 @@
+2017-01-03  Werner Lemberg  <wl@gnu.org>
+
+	Various fixes for clang's undefined behaviour sanitizer.
+
+	* src/cff/cffload.c (FT_fdot14ToFixed): Fix casting.
+	(cff_blend_doBlend): Don't left-shift negative numbers.
+	Handle 5-byte numbers byte by byte to avoid alignment issues.
+
+	* src/cff/cffparse.c (cff_parse): Handle 5-byte numbers byte by byte
+	to avoid alignment issues.
+
+	* src/cid/cidload (cid_read_subrs): Do nothing if we don't have any
+	subrs.
+
+	* src/psaux/t1decode.c (t1_decode_parse_charstring): Fix tracing.
+
+	* src/tools/glnames.py (main): Put `DEFINE_PSTABLES' guard around
+	definition of `ft_get_adobe_glyph_index'.
+
+	* src/psnames/pstables.h: Regenerated.
+
+	* src/psnames/psmodule.c: Inlude `pstables.h' twice to get both
+	declaration and definition.
+
+	* src/truetype/ttgxvar.c (FT_fdot14ToFixed, FT_intToFixed): Fix
+	casting.
+
 2017-01-01  Werner Lemberg  <wl@gnu.org>
 
 	[cff] Handle multiple `blend' operators in a row correctly.
diff --git a/src/cff/cffload.c b/src/cff/cffload.c
index c0b88e7..cb1c0b5 100644
--- a/src/cff/cffload.c
+++ b/src/cff/cffload.c
@@ -1113,7 +1113,7 @@
 
 
   /* convert 2.14 to Fixed */
-  #define FT_fdot14ToFixed( x )  ( ( (FT_Fixed)( (FT_Int16)(x) ) ) << 2 )
+  #define FT_fdot14ToFixed( x )  ( (FT_Fixed)( (FT_ULong)(x) << 2 ) )
 
 
   static FT_Error
@@ -1349,24 +1349,25 @@
 
 
       /* convert inputs to 16.16 fixed point */
-      sum = cff_parse_num( parser, &parser->stack[i + base] ) << 16;
+      sum = cff_parse_num( parser, &parser->stack[i + base] ) * 65536;
 
       for ( j = 1; j < blend->lenBV; j++ )
         sum += FT_MulFix( *weight++,
                           cff_parse_num( parser,
-                                         &parser->stack[delta++] ) << 16 );
+                                         &parser->stack[delta++] ) * 65536 );
 
       /* point parser stack to new value on blend_stack */
       parser->stack[i + base] = subFont->blend_top;
 
-      /* Push blended result as Type 2 5-byte fixed point number (except   */
-      /* that host byte order is used).  This will not conflict with       */
-      /* actual DICTs because 255 is a reserved opcode in both CFF and     */
-      /* CFF2 DICTs.  See `cff_parse_num' for decode of this, which rounds */
-      /* to an integer.                                                    */
-      *subFont->blend_top++             = 255;
-      *((FT_UInt32*)subFont->blend_top) = (FT_UInt32)sum; /* write 4 bytes */
-      subFont->blend_top               += 4;
+      /* Push blended result as Type 2 5-byte fixed point number.  This */
+      /* will not conflict with actual DICTs because 255 is a reserved  */
+      /* opcode in both CFF and CFF2 DICTs.  See `cff_parse_num' for    */
+      /* decode of this, which rounds to an integer.                    */
+      *subFont->blend_top++ = 255;
+      *subFont->blend_top++ = ( (FT_UInt32)sum & 0xFF000000U ) >> 24;
+      *subFont->blend_top++ = ( (FT_UInt32)sum & 0x00FF0000U ) >> 16;
+      *subFont->blend_top++ = ( (FT_UInt32)sum & 0x0000FF00U ) >>  8;
+      *subFont->blend_top++ =   (FT_UInt32)sum & 0x000000FFU;
     }
 
     /* leave only numBlends results on parser stack */
diff --git a/src/cff/cffparse.c b/src/cff/cffparse.c
index ee538c3..3c701e0 100644
--- a/src/cff/cffparse.c
+++ b/src/cff/cffparse.c
@@ -448,9 +448,13 @@
       /* 16.16 fixed point is used internally for CFF2 blend results. */
       /* Since these are trusted values, a limit check is not needed. */
 
-      /* After the 255, 4 bytes are in host order. */
-      /* Blend result is rounded to integer.       */
-      return (FT_Long)( *( (FT_UInt32 *) ( d[0] + 1 ) ) + 0x8000U ) >> 16;
+      /* After the 255, 4 bytes give the number. */
+      /* Blend result is rounded to integer.     */
+      return (FT_Short)(
+               ( ( ( (FT_ULong)*( d[0] + 1 ) << 24 ) |
+                   ( (FT_ULong)*( d[0] + 2 ) << 16 ) |
+                   ( (FT_ULong)*( d[0] + 3 ) <<  8 ) |
+                     (FT_ULong)*( d[0] + 4 )         ) + 0x8000U ) >> 16 );
     }
 
     else
diff --git a/src/cid/cidload.c b/src/cid/cidload.c
index fc2a3cf..cbc1089 100644
--- a/src/cid/cidload.c
+++ b/src/cid/cidload.c
@@ -461,6 +461,9 @@
       FT_Byte*      p;
 
 
+      if ( !num_subrs )
+        continue;
+
       /* reallocate offsets array if needed */
       if ( num_subrs + 1 > max_offsets )
       {
diff --git a/src/psaux/t1decode.c b/src/psaux/t1decode.c
index 1cd9d73..7b7035d 100644
--- a/src/psaux/t1decode.c
+++ b/src/psaux/t1decode.c
@@ -666,9 +666,9 @@
 
 #ifdef FT_DEBUG_LEVEL_TRACE
         if ( large_int )
-          FT_TRACE4(( " %ld", value ));
+          FT_TRACE4(( " %d", value ));
         else
-          FT_TRACE4(( " %ld", value / 65536 ));
+          FT_TRACE4(( " %d", value / 65536 ));
 #endif
 
         *top++       = value;
diff --git a/src/psnames/psmodule.c b/src/psnames/psmodule.c
index 01b85c3..af7067e 100644
--- a/src/psnames/psmodule.c
+++ b/src/psnames/psmodule.c
@@ -23,6 +23,7 @@
 
 #include "psmodule.h"
 
+#include "pstables.h"
 #define  DEFINE_PS_TABLES
 #include "pstables.h"
 
diff --git a/src/psnames/pstables.h b/src/psnames/pstables.h
index 309f16b..cae2f1f 100644
--- a/src/psnames/pstables.h
+++ b/src/psnames/pstables.h
@@ -4135,6 +4135,7 @@
   ;
 
 
+#ifdef  DEFINE_PS_TABLES
   /*
    *  This function searches the compressed table efficiently.
    */
@@ -4229,6 +4230,7 @@
   NotFound:
     return 0;
   }
+#endif /* DEFINE_PS_TABLES */
 
 #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
 
diff --git a/src/tools/glnames.py b/src/tools/glnames.py
index 3569f06..2e48236 100644
--- a/src/tools/glnames.py
+++ b/src/tools/glnames.py
@@ -5378,6 +5378,7 @@ def main():
   # write the lookup routine now
   #
   write( """\
+#ifdef  DEFINE_PS_TABLES
   /*
    *  This function searches the compressed table efficiently.
    */
@@ -5472,6 +5473,7 @@ def main():
   NotFound:
     return 0;
   }
+#endif /* DEFINE_PS_TABLES */
 
 #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
 
diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c
index 7689870..135bb68 100644
--- a/src/truetype/ttgxvar.c
+++ b/src/truetype/ttgxvar.c
@@ -396,10 +396,10 @@
   /* some macros we need */
   #define FT_FIXED_ONE  ( (FT_Fixed)0x10000 )
 
-  #define FT_fdot14ToFixed( x )                    \
-          ( ( (FT_Fixed)( (FT_Int16)(x) ) ) << 2 )
-  #define FT_intToFixed( i )                     \
-          ( (FT_Fixed)( (FT_UInt32)(i) << 16 ) )
+  #define FT_fdot14ToFixed( x )                \
+          ( (FT_Fixed)( (FT_ULong)(x) << 2 ) )
+  #define FT_intToFixed( i )                    \
+          ( (FT_Fixed)( (FT_ULong)(i) << 16 ) )
   #define FT_fixedToInt( x )                                   \
           ( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) )