Commit eaf0afb4c75e18d323b7b762ac0c5dd0a8e5202c

Werner Lemberg 2012-10-20T11:27:25

[psaux] Fix some value overflows and improve tracing. * src/psaux/psconv.c: Include FT_INTERNAL_DEBUG_H. (FT_COMPONENT): Define. (PS_Conv_Strtol): Return FT_Long. Handle bad data and overflow. Emit some tracing messages in case of error. (PS_Conv_ToInt): Return FT_Long. (PS_Conv_ToFixed): Updated. * src/psaux/psconv.h: Updated. * include/freetype/internal/fttrace.h: Add `psconv'.

diff --git a/ChangeLog b/ChangeLog
index a6aeca3..d6612c6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,20 @@
 2012-10-20  Werner Lemberg  <wl@gnu.org>
 
+	[psaux] Fix some value overflows and improve tracing.
+
+	* src/psaux/psconv.c: Include FT_INTERNAL_DEBUG_H.
+	(FT_COMPONENT): Define.
+	(PS_Conv_Strtol): Return FT_Long.
+	Handle bad data and overflow.
+	Emit some tracing messages in case of error.
+	(PS_Conv_ToInt): Return FT_Long.
+	(PS_Conv_ToFixed): Updated.
+	* src/psaux/psconv.h: Updated.
+
+	* include/freetype/internal/fttrace.h: Add `psconv'.
+
+2012-10-20  Werner Lemberg  <wl@gnu.org>
+
 	[autofit] Fix `make multi CC=c++'.
 
 	* src/autofit/aflatin.c, src/autofit/aflatin2.c: Include
diff --git a/include/freetype/internal/fttrace.h b/include/freetype/internal/fttrace.h
index e807a61..6e6cb49 100644
--- a/include/freetype/internal/fttrace.h
+++ b/include/freetype/internal/fttrace.h
@@ -73,6 +73,7 @@ FT_TRACE_DEF( t1parse )
   /* PostScript helper module `psaux' */
 FT_TRACE_DEF( t1decode )
 FT_TRACE_DEF( psobjs )
+FT_TRACE_DEF( psconv )
 
   /* PostScript hinting module `pshinter' */
 FT_TRACE_DEF( pshrec )
diff --git a/src/psaux/psconv.c b/src/psaux/psconv.c
index df53083..5747c11 100644
--- a/src/psaux/psconv.c
+++ b/src/psaux/psconv.c
@@ -18,11 +18,22 @@
 
 #include <ft2build.h>
 #include FT_INTERNAL_POSTSCRIPT_AUX_H
+#include FT_INTERNAL_DEBUG_H
 
 #include "psconv.h"
 #include "psauxerr.h"
 
 
+  /*************************************************************************/
+  /*                                                                       */
+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
+  /* messages during execution.                                            */
+  /*                                                                       */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_psconv
+
+
   /* The following array is used by various functions to quickly convert */
   /* digits (both decimal and non-decimal) into numbers.                 */
 
@@ -69,18 +80,27 @@
 #endif /* 'A' == 193 */
 
 
-  FT_LOCAL_DEF( FT_Int )
+  FT_LOCAL_DEF( FT_Long )
   PS_Conv_Strtol( FT_Byte**  cursor,
                   FT_Byte*   limit,
-                  FT_Int     base )
+                  FT_Long    base )
   {
     FT_Byte*  p = *cursor;
-    FT_Int    num = 0;
+    FT_Long   num  = 0;
     FT_Bool   sign = 0;
 
+    FT_Long   num_limit;
+    FT_Char   c_limit;
+
+
+    if ( p >= limit )
+      goto Bad;
 
-    if ( p >= limit || base < 2 || base > 36 )
+    if ( base < 2 || base > 36 )
+    {
+      FT_TRACE4(( "!!!INVALID BASE:!!!" ));
       return 0;
+    }
 
     if ( *p == '-' || *p == '+' )
     {
@@ -88,9 +108,12 @@
 
       p++;
       if ( p == limit )
-        return 0;
+        goto Bad;
     }
 
+    num_limit = 0x7FFFFFFFL / base;
+    c_limit   = (FT_Char)( 0x7FFFFFFFL % base );
+
     for ( ; p < limit; p++ )
     {
       FT_Char  c;
@@ -104,25 +127,38 @@
       if ( c < 0 || c >= base )
         break;
 
+      if ( num > num_limit || ( num == num_limit && c > c_limit ) )
+        goto Overflow;
       num = num * base + c;
     }
 
+    *cursor = p;
+
+  Exit:
     if ( sign )
       num = -num;
 
-    *cursor = p;
-
     return num;
+
+  Overflow:
+    num = 0x7FFFFFFFL;
+    FT_TRACE4(( "!!!OVERFLOW:!!!" ));
+    goto Exit;
+
+  Bad:
+    num = 0;
+    FT_TRACE4(( "!!!END OF DATA:!!!" ));
+    goto Exit;
   }
 
 
-  FT_LOCAL_DEF( FT_Int )
+  FT_LOCAL_DEF( FT_Long )
   PS_Conv_ToInt( FT_Byte**  cursor,
                  FT_Byte*   limit )
 
   {
     FT_Byte*  p;
-    FT_Int    num;
+    FT_Long   num;
 
 
     num = PS_Conv_Strtol( cursor, limit, 10 );
@@ -142,7 +178,7 @@
   FT_LOCAL_DEF( FT_Fixed )
   PS_Conv_ToFixed( FT_Byte**  cursor,
                    FT_Byte*   limit,
-                   FT_Int     power_ten )
+                   FT_Long    power_ten )
   {
     FT_Byte*  p = *cursor;
     FT_Fixed  integral;
diff --git a/src/psaux/psconv.h b/src/psaux/psconv.h
index 84854ba..d91c762 100644
--- a/src/psaux/psconv.h
+++ b/src/psaux/psconv.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Some convenience conversions (specification).                        */
 /*                                                                         */
-/*  Copyright 2006 by                                                      */
+/*  Copyright 2006, 2012 by                                                */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -26,20 +26,20 @@
 FT_BEGIN_HEADER
 
 
-  FT_LOCAL( FT_Int )
+  FT_LOCAL( FT_Long )
   PS_Conv_Strtol( FT_Byte**  cursor,
                   FT_Byte*   limit,
-                  FT_Int     base );
+                  FT_Long    base );
 
 
-  FT_LOCAL( FT_Int )
+  FT_LOCAL( FT_Long )
   PS_Conv_ToInt( FT_Byte**  cursor,
                  FT_Byte*   limit );
 
   FT_LOCAL( FT_Fixed )
   PS_Conv_ToFixed( FT_Byte**  cursor,
                    FT_Byte*   limit,
-                   FT_Int     power_ten );
+                   FT_Long    power_ten );
 
 #if 0
   FT_LOCAL( FT_UInt )