Commit 4a1f1a6d2a5118ae45f0f950a824ad7a1363a044

Werner Lemberg 2017-06-01T13:15:54

[psaux] 32bit integer overflow tun-time errors (#46149). * src/psaux/t1decode.c (t1_decoder_parse_charstrings): Use OVERFLOW_ADD_LONG and OVERFLOW_SUB_LONG where appropriate.

diff --git a/ChangeLog b/ChangeLog
index a044712..57753f2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2017-06-01  Werner Lemberg  <wl@gnu.org>
 
+	[psaux] 32bit integer overflow tun-time errors (#46149).
+
+	* src/psaux/t1decode.c (t1_decoder_parse_charstrings): Use
+	OVERFLOW_ADD_LONG and OVERFLOW_SUB_LONG where appropriate.
+
+2017-06-01  Werner Lemberg  <wl@gnu.org>
+
 	* src/truetype/ttinterp.c (TT_RunIns): Adjust loop counter again.
 
 	Problem reported by Marek Kašík <mkasik@redhat.com>.
diff --git a/src/psaux/t1decode.c b/src/psaux/t1decode.c
index 7dd4513..04de122 100644
--- a/src/psaux/t1decode.c
+++ b/src/psaux/t1decode.c
@@ -864,7 +864,9 @@
 
 
               for ( mm = 1; mm < blend->num_designs; mm++ )
-                tmp += FT_MulFix( *delta++, blend->weight_vector[mm] );
+                tmp = OVERFLOW_ADD_LONG(
+                        tmp,
+                        FT_MulFix( *delta++, blend->weight_vector[mm] ) );
 
               *values++ = tmp;
             }
@@ -904,7 +906,7 @@
           if ( arg_cnt != 2 )
             goto Unexpected_OtherSubr;
 
-          top[0] += top[1]; /* XXX (over|under)flow */
+          top[0] = OVERFLOW_ADD_LONG( top[0], top[1] );
 
           known_othersubr_result_cnt = 1;
           break;
@@ -915,7 +917,7 @@
           if ( arg_cnt != 2 )
             goto Unexpected_OtherSubr;
 
-          top[0] -= top[1]; /* XXX (over|under)flow */
+          top[0] = OVERFLOW_SUB_LONG( top[0], top[1] );
 
           known_othersubr_result_cnt = 1;
           break;
@@ -1147,11 +1149,13 @@
 
           builder->parse_state = T1_Parse_Have_Width;
 
-          builder->left_bearing.x += top[0];
-          builder->advance.x       = top[1];
-          builder->advance.y       = 0;
+          builder->left_bearing.x = OVERFLOW_ADD_LONG(
+                                      builder->left_bearing.x, top[0] );
 
-          orig_x = x = builder->pos_x + top[0];
+          builder->advance.x = top[1];
+          builder->advance.y = 0;
+
+          orig_x = x = OVERFLOW_ADD_LONG( builder->pos_x, top[0] );
           orig_y = y = builder->pos_y;
 
           FT_UNUSED( orig_y );
@@ -1177,13 +1181,16 @@
 
           builder->parse_state = T1_Parse_Have_Width;
 
-          builder->left_bearing.x += top[0];
-          builder->left_bearing.y += top[1];
-          builder->advance.x       = top[2];
-          builder->advance.y       = top[3];
+          builder->left_bearing.x = OVERFLOW_ADD_LONG(
+                                      builder->left_bearing.x, top[0] );
+          builder->left_bearing.y = OVERFLOW_ADD_LONG(
+                                      builder->left_bearing.y, top[1] );
+
+          builder->advance.x = top[2];
+          builder->advance.y = top[3];
 
-          x = builder->pos_x + top[0];
-          y = builder->pos_y + top[1];
+          x = OVERFLOW_ADD_LONG( builder->pos_x, top[0] );
+          y = OVERFLOW_ADD_LONG( builder->pos_y, top[1] );
 
           /* the `metrics_only' indicates that we only want to compute */
           /* the glyph's metrics (lsb + advance width), not load the   */
@@ -1210,13 +1217,14 @@
           if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) )
             goto Fail;
 
-          x += top[0];
+          x = OVERFLOW_ADD_LONG( x, top[0] );
           goto Add_Line;
 
         case op_hmoveto:
           FT_TRACE4(( " hmoveto" ));
 
-          x += top[0];
+          x = OVERFLOW_ADD_LONG( x, top[0] );
+
           if ( !decoder->flex_state )
           {
             if ( builder->parse_state == T1_Parse_Start )
@@ -1232,12 +1240,14 @@
                FT_SET_ERROR( t1_builder_check_points( builder, 3 ) )   )
             goto Fail;
 
-          x += top[0];
+          x = OVERFLOW_ADD_LONG( x, top[0] );
           t1_builder_add_point( builder, x, y, 0 );
-          x += top[1];
-          y += top[2];
+
+          x = OVERFLOW_ADD_LONG( x, top[1] );
+          y = OVERFLOW_ADD_LONG( y, top[2] );
           t1_builder_add_point( builder, x, y, 0 );
-          y += top[3];
+
+          y = OVERFLOW_ADD_LONG( y, top[3] );
           t1_builder_add_point( builder, x, y, 1 );
           break;
 
@@ -1247,8 +1257,8 @@
           if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) )
             goto Fail;
 
-          x += top[0];
-          y += top[1];
+          x = OVERFLOW_ADD_LONG( x, top[0] );
+          y = OVERFLOW_ADD_LONG( y, top[1] );
 
         Add_Line:
           if ( FT_SET_ERROR( t1_builder_add_point1( builder, x, y ) ) )
@@ -1258,8 +1268,9 @@
         case op_rmoveto:
           FT_TRACE4(( " rmoveto" ));
 
-          x += top[0];
-          y += top[1];
+          x = OVERFLOW_ADD_LONG( x, top[0] );
+          y = OVERFLOW_ADD_LONG( y, top[1] );
+
           if ( !decoder->flex_state )
           {
             if ( builder->parse_state == T1_Parse_Start )
@@ -1275,16 +1286,16 @@
                FT_SET_ERROR( t1_builder_check_points( builder, 3 ) )   )
             goto Fail;
 
-          x += top[0];
-          y += top[1];
+          x = OVERFLOW_ADD_LONG( x, top[0] );
+          y = OVERFLOW_ADD_LONG( y, top[1] );
           t1_builder_add_point( builder, x, y, 0 );
 
-          x += top[2];
-          y += top[3];
+          x = OVERFLOW_ADD_LONG( x, top[2] );
+          y = OVERFLOW_ADD_LONG( y, top[3] );
           t1_builder_add_point( builder, x, y, 0 );
 
-          x += top[4];
-          y += top[5];
+          x = OVERFLOW_ADD_LONG( x, top[4] );
+          y = OVERFLOW_ADD_LONG( y, top[5] );
           t1_builder_add_point( builder, x, y, 1 );
           break;
 
@@ -1295,12 +1306,14 @@
                FT_SET_ERROR( t1_builder_check_points( builder, 3 ) )   )
             goto Fail;
 
-          y += top[0];
+          y = OVERFLOW_ADD_LONG( y, top[0] );
           t1_builder_add_point( builder, x, y, 0 );
-          x += top[1];
-          y += top[2];
+
+          x = OVERFLOW_ADD_LONG( x, top[1] );
+          y = OVERFLOW_ADD_LONG( y, top[2] );
           t1_builder_add_point( builder, x, y, 0 );
-          x += top[3];
+
+          x = OVERFLOW_ADD_LONG( x, top[3] );
           t1_builder_add_point( builder, x, y, 1 );
           break;
 
@@ -1310,13 +1323,14 @@
           if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) )
             goto Fail;
 
-          y += top[0];
+          y = OVERFLOW_ADD_LONG( y, top[0] );
           goto Add_Line;
 
         case op_vmoveto:
           FT_TRACE4(( " vmoveto" ));
 
-          y += top[0];
+          y = OVERFLOW_ADD_LONG( y, top[0] );
+
           if ( !decoder->flex_state )
           {
             if ( builder->parse_state == T1_Parse_Start )
@@ -1473,7 +1487,7 @@
           /* record vertical hint */
           if ( hinter )
           {
-            top[0] += orig_x;
+            top[0] = OVERFLOW_ADD_LONG( top[0], orig_x );
             hinter->stem( hinter->hints, 0, top );
           }
           break;
@@ -1487,9 +1501,9 @@
             FT_Pos  dx = orig_x;
 
 
-            top[0] += dx;
-            top[2] += dx;
-            top[4] += dx;
+            top[0] = OVERFLOW_ADD_LONG( top[0], dx );
+            top[2] = OVERFLOW_ADD_LONG( top[2], dx );
+            top[4] = OVERFLOW_ADD_LONG( top[4], dx );
             hinter->stem3( hinter->hints, 0, top );
           }
           break;