Commit ad4eecca7732a0b7c1ec000d178864df2bbe7629

Werner Lemberg 2012-10-20T21:27:17

[cff] Improve parsing of invalid real numbers. * src/cff/cffparse.c (cff_parse_real): Always parse complete number, even in case of overflow or underflow. Also trace one more underflow.

diff --git a/ChangeLog b/ChangeLog
index 2be2972..c7d401e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2012-10-20  Werner Lemberg  <wl@gnu.org>
+
+	[cff] Improve parsing of invalid real numbers.
+
+	* src/cff/cffparse.c (cff_parse_real): Always parse complete number,
+	even in case of overflow or underflow.
+	Also trace one more underflow.
+
 2012-10-20  Andreas Pehnack  <andreas.pehnack@me.com>
 
 	[sfnt] Load pure CFF fonts wrapped in SFNT container.
diff --git a/src/cff/cffparse.c b/src/cff/cffparse.c
index 015a1d1..5e58c8b 100644
--- a/src/cff/cffparse.c
+++ b/src/cff/cffparse.c
@@ -137,7 +137,7 @@
     FT_UInt   phase;
 
     FT_Long   result, number, exponent;
-    FT_Int    sign = 0, exponent_sign = 0;
+    FT_Int    sign = 0, exponent_sign = 0, have_overflow = 0;
     FT_Long   exponent_add, integer_length, fraction_length;
 
 
@@ -251,16 +251,11 @@
         if ( nib >= 10 )
           break;
 
-        exponent = exponent * 10 + nib;
-
         /* Arbitrarily limit exponent. */
         if ( exponent > 1000 )
-        {
-          if ( exponent_sign )
-            goto Underflow;
-          else
-            goto Overflow;
-        }
+          have_overflow = 1;
+        else
+          exponent = exponent * 10 + nib;
       }
 
       if ( exponent_sign )
@@ -270,6 +265,14 @@
     if ( !number )
       goto Exit;
 
+    if ( have_overflow )
+    {
+      if ( exponent_sign )
+        goto Underflow;
+      else
+        goto Overflow;
+    }
+
     /* We don't check `power_ten' and `exponent_add'. */
     exponent += power_ten + exponent_add;
 
@@ -336,9 +339,10 @@
       integer_length  += exponent;
       fraction_length -= exponent;
 
-      /* Check for overflow and underflow. */
-      if ( FT_ABS( integer_length ) > 5 )
+      if ( integer_length > 5 )
         goto Overflow;
+      if ( integer_length < -5 )
+        goto Underflow;
 
       /* Remove non-significant digits. */
       if ( integer_length < 0 )