Commit a5acdce10076b0ad717b9b8eb455f811ed1d1f45

Werner Lemberg 2018-07-22T12:11:52

[cid] Sanitize `BlueShift' and `BlueFuzz'. This code is taken from the type1 module. Reported as https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9510 * src/cid/cidload.c (parse_fd_array): Set some private dict default values. (cid_face_open): Do the sanitizing. Fix some tracing messages.

diff --git a/ChangeLog b/ChangeLog
index dc31288..635a401 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2018-07-22  Werner Lemberg  <wl@gnu.org>
+
+	[cid] Sanitize `BlueShift' and `BlueFuzz'.
+
+	This code is taken from the type1 module.
+
+	Reported as
+
+	  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9510
+
+	* src/cid/cidload.c (parse_fd_array): Set some private dict default
+	values.
+	(cid_face_open): Do the sanitizing.
+	Fix some tracing messages.
+
 2018-07-21  Werner Lemberg  <wl@gnu.org>
 
 	[pcf] Fix handling of the undefined glyph.
diff --git a/src/cid/cidload.c b/src/cid/cidload.c
index 8f2a312..057a8b0 100644
--- a/src/cid/cidload.c
+++ b/src/cid/cidload.c
@@ -270,14 +270,18 @@
 
       cid->num_dicts = num_dicts;
 
-      /* don't forget to set a few defaults */
+      /* set some default values (the same as for Type 1 fonts) */
       for ( n = 0; n < cid->num_dicts; n++ )
       {
         CID_FaceDict  dict = cid->font_dicts + n;
 
 
-        /* default value for lenIV */
-        dict->private_dict.lenIV = 4;
+        dict->private_dict.blue_shift       = 7;
+        dict->private_dict.blue_fuzz        = 1;
+        dict->private_dict.lenIV            = 4;
+        dict->private_dict.expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
+        dict->private_dict.blue_scale       = (FT_Fixed)(
+                                                0.039625 * 0x10000L * 1000 );
       }
     }
 
@@ -764,7 +768,7 @@
 
     if ( cid->fd_bytes < 0 || cid->gd_bytes < 1 )
     {
-      FT_ERROR(( "cid_parse_dict:"
+      FT_ERROR(( "cid_face_open:"
                  " Invalid `FDBytes' or `GDBytes' value\n" ));
       error = FT_THROW( Invalid_File_Format );
       goto Exit;
@@ -773,7 +777,7 @@
     /* allow at most 32bit offsets */
     if ( cid->fd_bytes > 4 || cid->gd_bytes > 4 )
     {
-      FT_ERROR(( "cid_parse_dict:"
+      FT_ERROR(( "cid_face_open:"
                  " Values of `FDBytes' or `GDBytes' larger than 4\n"
                  "               "
                  " are not supported\n" ));
@@ -789,17 +793,36 @@
       CID_FaceDict  dict = cid->font_dicts + n;
 
 
+      /* the upper limits are ad-hoc values */
+      if ( dict->private_dict.blue_shift > 1000 ||
+           dict->private_dict.blue_shift < 0    )
+      {
+        FT_TRACE2(( "cid_face_open:"
+                    " setting unlikely BlueShift value %d to default (7)\n",
+                    dict->private_dict.blue_shift ));
+        dict->private_dict.blue_shift = 7;
+      }
+
+      if ( dict->private_dict.blue_fuzz > 1000 ||
+           dict->private_dict.blue_fuzz < 0    )
+      {
+        FT_TRACE2(( "cid_face_open:"
+                    " setting unlikely BlueFuzz value %d to default (1)\n",
+                    dict->private_dict.blue_fuzz ));
+        dict->private_dict.blue_fuzz = 1;
+      }
+
       if ( dict->sd_bytes < 0                        ||
            ( dict->num_subrs && dict->sd_bytes < 1 ) )
       {
-        FT_ERROR(( "cid_parse_dict: Invalid `SDBytes' value\n" ));
+        FT_ERROR(( "cid_face_open: Invalid `SDBytes' value\n" ));
         error = FT_THROW( Invalid_File_Format );
         goto Exit;
       }
 
       if ( dict->sd_bytes > 4 )
       {
-        FT_ERROR(( "cid_parse_dict:"
+        FT_ERROR(( "cid_face_open:"
                    " Values of `SDBytes' larger than 4"
                    " are not supported\n" ));
         error = FT_THROW( Invalid_File_Format );
@@ -808,7 +831,7 @@
 
       if ( dict->subrmap_offset > binary_length )
       {
-        FT_ERROR(( "cid_parse_dict: Invalid `SubrMapOffset' value\n" ));
+        FT_ERROR(( "cid_face_open: Invalid `SubrMapOffset' value\n" ));
         error = FT_THROW( Invalid_File_Format );
         goto Exit;
       }
@@ -819,7 +842,7 @@
              dict->num_subrs > ( binary_length - dict->subrmap_offset ) /
                                  (FT_UInt)dict->sd_bytes                 ) )
       {
-        FT_ERROR(( "cid_parse_dict: Invalid `SubrCount' value\n" ));
+        FT_ERROR(( "cid_face_open: Invalid `SubrCount' value\n" ));
         error = FT_THROW( Invalid_File_Format );
         goto Exit;
       }
@@ -827,7 +850,7 @@
 
     if ( cid->cidmap_offset > binary_length )
     {
-      FT_ERROR(( "cid_parse_dict: Invalid `CIDMapOffset' value\n" ));
+      FT_ERROR(( "cid_face_open: Invalid `CIDMapOffset' value\n" ));
       error = FT_THROW( Invalid_File_Format );
       goto Exit;
     }
@@ -836,7 +859,7 @@
          cid->cid_count >
            ( binary_length - cid->cidmap_offset ) / entry_len )
     {
-      FT_ERROR(( "cid_parse_dict: Invalid `CIDCount' value\n" ));
+      FT_ERROR(( "cid_face_open: Invalid `CIDCount' value\n" ));
       error = FT_THROW( Invalid_File_Format );
       goto Exit;
     }