Commit 7d3d2cc4fef72c6be9c454b3809c387e12b44cfc

Werner Lemberg 2010-06-09T09:14:09

Fix Savannah bug #30082. * src/cff/cffgload.c (cff_decoder_parse_charstrings) <cff_op_callothersubr>: Protect against stack underflow.

diff --git a/ChangeLog b/ChangeLog
index df72e09..183237f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,8 +1,15 @@
+2010-06-09  Werner Lemberg  <wl@gnu.org>
+
+	Fix Savannah bug #30082.
+
+	* src/cff/cffgload.c (cff_decoder_parse_charstrings)
+	<cff_op_callothersubr>: Protect against stack underflow.
+
 2010-06-08  Werner Lemberg  <wl@gnu.org>
 
 	Fix Savannah bug #30053.
 
-	* src/cff/cffparse (cff_parse_real): Handle border case where
+	* src/cff/cffparse.c (cff_parse_real): Handle border case where
 	`fraction_length' has value 10.
 
 2010-06-07  Werner Lemberg  <wl@gnu.org>
diff --git a/src/cff/cffgload.c b/src/cff/cffgload.c
index 9e4dfc5..58af356 100644
--- a/src/cff/cffgload.c
+++ b/src/cff/cffgload.c
@@ -2275,6 +2275,8 @@
           /* this is the implementation described for `unknown' other  */
           /* subroutines in the Type1 spec.                            */
           args -= 2 + ( args[-2] >> 16 );
+          if ( args < stack )
+            goto Stack_Underflow;
           break;
 
         case cff_op_pop:
diff --git a/src/smooth/ftgrays.c b/src/smooth/ftgrays.c
index 846e454..cef8188 100644
--- a/src/smooth/ftgrays.c
+++ b/src/smooth/ftgrays.c
@@ -1007,45 +1007,40 @@
                               const FT_Vector*  control2,
                               const FT_Vector*  to )
   {
-    TPos        dx, dy, da, db;
+    TPos        dx, dy;
+    TPos        mid_x, mid_y;
     int         top, level;
     int*        levels;
     FT_Vector*  arc;
 
 
-    dx = DOWNSCALE( ras.x ) + to->x - ( control1->x << 1 );
-    if ( dx < 0 )
-      dx = -dx;
-    dy = DOWNSCALE( ras.y ) + to->y - ( control1->y << 1 );
-    if ( dy < 0 )
-      dy = -dy;
-    if ( dx < dy )
-      dx = dy;
-    da = dx;
+    /* Calculate midpoint and compare it with start and end. */
+    mid_x = ( DOWNSCALE( ras.x ) + to->x +
+              3 * ( control1->x + control2->x ) ) / 8;
+    mid_y = ( DOWNSCALE( ras.y ) + to->y +
+              3 * ( control1->y + control2->y ) ) / 8;
 
-    dx = DOWNSCALE( ras.x ) + to->x - 3 * ( control1->x + control2->x );
+    dx = DOWNSCALE( ras.x ) + to->x - ( mid_x << 1 );
     if ( dx < 0 )
       dx = -dx;
-    dy = DOWNSCALE( ras.y ) + to->y - 3 * ( control1->x + control2->y );
+    dy = DOWNSCALE( ras.y ) + to->y - ( mid_y << 1 );
     if ( dy < 0 )
       dy = -dy;
     if ( dx < dy )
       dx = dy;
-    db = dx;
 
+    /* Check whether an approximation with straight lines is sufficient. */
     level = 1;
-    da    = da / ras.cubic_level;
-    db    = db / ras.conic_level;
-    while ( da > 0 || db > 0 )
+    dx    = dx / ras.conic_level;
+    while ( dx > 0 )
     {
-      da >>= 2;
-      db >>= 3;
+      dx >>= 3;
       level++;
     }
 
     if ( level <= 1 )
     {
-      TPos   to_x, to_y, mid_x, mid_y;
+      TPos   to_x, to_y;
 
 
       to_x  = UPSCALE( to->x );
@@ -1104,7 +1099,7 @@
 
     Draw:
       {
-        TPos  to_x, to_y, mid_x, mid_y;
+        TPos  to_x, to_y;
 
 
         to_x  = arc[0].x;