Commit 6fd9512aff9a04d4ecd994d9580736bf6b1726e1

Werner Lemberg 2003-12-31T07:51:30

* src/truetype/ttgload.c (TT_Load_Simple_Glyph): Handle `repeated flags set' correctly. * src/cff/cffobjs.c (cff_face_init): Fix memory leak by deallocating `full' and `weight' properly. * src/cff/cffgload.c (cff_decoder_parse_charstrings) <cff_op_hintmask> [FT_DEBUG_LEVEL_TRACE]: Use `0x' as prefix for tracing output.

diff --git a/ChangeLog b/ChangeLog
index 7d37368..45c195f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2003-12-29  Smith Charles  <smith.charles@free.fr>
+
+	* src/truetype/ttgload.c (TT_Load_Simple_Glyph): Handle `repeated
+	flags set' correctly.
+
+2003-12-29  Werner Lemberg  <wl@gnu.org>
+
+	* src/cff/cffobjs.c (cff_face_init): Fix memory leak by deallocating
+	`full' and `weight' properly.
+	* src/cff/cffgload.c (cff_decoder_parse_charstrings)
+	<cff_op_hintmask> [FT_DEBUG_LEVEL_TRACE]: Use `0x' as prefix for
+	tracing output.
+
 2003-12-26  Werner Lemberg  <wl@gnu.org>
 
 	* include/freetype/internal/sfnt.h (TT_Set_SBit_Strike_Func):
diff --git a/src/cff/cffgload.c b/src/cff/cffgload.c
index a56ee28..7b25915 100644
--- a/src/cff/cffgload.c
+++ b/src/cff/cffgload.c
@@ -1227,7 +1227,7 @@
             for ( maskbyte = 0;
                   maskbyte < (FT_UInt)(( decoder->num_hints + 7 ) >> 3);
                   maskbyte++, ip++ )
-              FT_TRACE4(( "%02X", *ip ));
+              FT_TRACE4(( "0x%02X", *ip ));
           }
 #else
           ip += ( decoder->num_hints + 7 ) >> 3;
diff --git a/src/cff/cffobjs.c b/src/cff/cffobjs.c
index 8d45165..6abb84b 100644
--- a/src/cff/cffobjs.c
+++ b/src/cff/cffobjs.c
@@ -376,7 +376,7 @@
 
       if ( pure_cff )
       {
-        char*  style_name;
+        char*  style_name = NULL;
 
 
         /* Set up num_faces. */
@@ -413,36 +413,37 @@
         root->family_name = cff_index_get_name( &cff->name_index,
                                                 face_index );
 
-        /* assume "Regular" style if we don't know better */
-        style_name = (char *)"Regular";
-
         if ( root->family_name )
         {
           char*  full   = cff_index_get_sid_string( &cff->string_index,
                                                     dict->full_name,
                                                     psnames );
+          char*  fullp  = full;
           char*  family = root->family_name;
 
 
           if ( full )
           {
-            while ( *full )
+            while ( *fullp )
             {
-              if ( *full == *family )
+              if ( *fullp == *family )
               {
                 family++;
-                full++;
+                fullp++;
               }
               else
               {
-                if ( *full == ' ' || *full == '-' )
-                  full++;
+                if ( *fullp == ' ' || *fullp == '-' )
+                  fullp++;
                 else if ( *family == ' ' || *family == '-' )
                   family++;
                 else
                 {
                   if ( !*family )
-                    style_name = full;
+                  {
+                    style_name = cff_strcpy( memory, fullp );
+                    FT_FREE( full );
+                  }
                   break;
                 }
               }
@@ -462,7 +463,11 @@
             root->family_name = cid_font_name;
         }
 
-        root->style_name = cff_strcpy( memory, style_name );
+        if ( style_name )
+          root->style_name = style_name;
+        else
+          /* assume "Regular" style if we don't know better */
+          root->style_name = cff_strcpy( memory, (char *)"Regular" );
 
         /*******************************************************************/
         /*                                                                 */
@@ -506,6 +511,7 @@
             if ( !ft_strcmp( weight, "Bold"  ) ||
                  !ft_strcmp( weight, "Black" ) )
               flags |= FT_STYLE_FLAG_BOLD;
+          FT_FREE( weight );
         }
 
         root->style_flags = flags;
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index 78eb41a..8ff3e6b 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -296,6 +296,7 @@
 
     FT_Byte         *flag, *flag_limit;
     FT_Byte         c, count;
+    FT_Int          n_xlimit;
     FT_Vector       *vec, *vec_limit;
     FT_Pos          x;
     FT_Short        *cont, *cont_limit;
@@ -368,10 +369,36 @@
     stream->cursor += (FT_Int)n_ins;
 
     /* reading the point tags */
+
+    /*********************************************************************/
+    /*                                                                   */
+    /* NOTE:                                                             */
+    /*                                                                   */
+    /* Microsoft documentation says:                                     */
+    /*                                                                   */
+    /* BYTE  flags[n]   Array of flags for each coordinate in outline;   */
+    /*                  `n' is the number of flags.                      */
+    /*                  (But it doesn't say where the `n' comes from.)   */
+    /*                                                                   */
+    /* Apple documentation says:                                         */
+    /*                                                                   */
+    /* uint8  flags[variable]   Array of flags.                          */
+    /*                          (Again it doesn't say where the          */
+    /*                          `variable' comes from)                   */
+    /*                                                                   */
+    /* Most of the time, `n' = `variable' = n_points.  But if a          */
+    /* `repeated flags set' is found (`c & 8' below) the number of       */
+    /* flags sets is smaller than n_points.  So we must carefully read   */
+    /* the flags, avoiding to read beyond the limit of actually stored   */
+    /* bytes.                                                            */
+
     flag       = (FT_Byte*)outline->tags;
     flag_limit = flag + n_points;
 
-    while ( flag < flag_limit )
+    /* scan and expand the flags to reach the first xCoordinate */
+    n_xlimit   = n_points;          /* this is a safety limit for reading */
+
+    for ( ; n_xlimit > 0; n_xlimit-- )
     {
       if ( --byte_len < 0 )
         goto Invalid_Outline;
@@ -386,11 +413,19 @@
         if ( flag + (FT_Int)count > flag_limit )
           goto Invalid_Outline;
 
+        /* adjust n_xlimit by removing the repeated sets */
+        /* from the safety limit                         */
+        n_xlimit -= count;
+
         for ( ; count > 0; count-- )
           *flag++ = c;
       }
     }
 
+    /* check that each point has an associated flags set */
+    if ( flag != flag_limit )
+      goto Invalid_Outline;
+
     /* check that there is enough room to load the coordinates */
     for ( flag = (FT_Byte*)outline->tags; flag < flag_limit; flag++ )
     {