shithub: freetype+ttf2subf

Download patch

ref: b19cdc9c8164cd81801024b024ce132bcb4a29f1
parent: 3b3cb32dd2340d86d3165961a4bb3dbd44353075
author: Werner Lemberg <[email protected]>
date: Thu Sep 21 07:02:35 EDT 2017

[truetype] Fix `mmvar' array pointers, part 2.

The previous commit was incomplete.

* src/truetype/ttgxvar.c: Properly initialize sub-array offsets for
`master' also.

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2017-09-21  Werner Lemberg  <[email protected]>
 
+	[truetype] Fix `mmvar' array pointers, part 2.
+
+	The previous commit was incomplete.
+
+	* src/truetype/ttgxvar.c: Properly initialize sub-array offsets for
+	`master' also.
+
+2017-09-21  Werner Lemberg  <[email protected]>
+
 	[truetype] Fix `mmvar' array pointers.
 
 	Without this change, clang's AddressSanitizer reports many runtime
--- a/src/truetype/ttgxvar.c
+++ b/src/truetype/ttgxvar.c
@@ -1940,11 +1940,11 @@
   TT_Get_MM_Var( TT_Face      face,
                  FT_MM_Var*  *master )
   {
-    FT_Stream            stream = face->root.stream;
-    FT_Memory            memory = face->root.memory;
+    FT_Stream            stream     = face->root.stream;
+    FT_Memory            memory     = face->root.memory;
     FT_ULong             table_len;
-    FT_Error             error  = FT_Err_Ok;
-    FT_ULong             fvar_start;
+    FT_Error             error      = FT_Err_Ok;
+    FT_ULong             fvar_start = 0;
     FT_UInt              i, j;
     FT_MM_Var*           mmvar = NULL;
     FT_Fixed*            next_coords;
@@ -1954,10 +1954,20 @@
     FT_Fixed*            c;
     FT_Var_Named_Style*  ns;
     GX_FVar_Head         fvar_head;
-    FT_Bool              usePsName;
+    FT_Bool              usePsName  = 0;
     FT_UInt              num_instances;
+    FT_UInt              num_axes;
     FT_UShort*           axis_flags;
 
+    FT_Offset  mmvar_size;
+    FT_Offset  axis_flags_size;
+    FT_Offset  axis_size;
+    FT_Offset  namedstyle_size;
+    FT_Offset  next_coords_size;
+    FT_Offset  next_name_size;
+
+    FT_Bool  need_init;
+
     static const FT_Frame_Field  fvar_fields[] =
     {
 
@@ -1995,16 +2005,10 @@
     /* read the font data and set up the internal representation */
     /* if not already done                                       */
 
-    if ( !face->blend )
-    {
-      FT_Offset  mmvar_size;
-      FT_Offset  axis_flags_size;
-      FT_Offset  axis_size;
-      FT_Offset  namedstyle_size;
-      FT_Offset  next_coords_size;
-      FT_Offset  next_name_size;
+    need_init = !face->blend;
 
-
+    if ( need_init )
+    {
       FT_TRACE2(( "FVAR " ));
 
       /* both `fvar' and `gvar' must be present */
@@ -2045,36 +2049,43 @@
       if ( FT_NEW( face->blend ) )
         goto Exit;
 
-      /* `num_instances' holds the number of all named instances, */
-      /* including the default instance which might be missing    */
-      /* in fvar's table of named instances                       */
-      num_instances = face->root.style_flags >> 16;
+      num_axes = fvar_head.axisCount;
+    }
+    else
+      num_axes = face->blend->num_axis;
 
-      /* prepare storage area for MM data; this cannot overflow   */
-      /* 32-bit arithmetic because of the size limits used in the */
-      /* `fvar' table validity check in `sfnt_init_face'          */
+    /* `num_instances' holds the number of all named instances, */
+    /* including the default instance which might be missing    */
+    /* in fvar's table of named instances                       */
+    num_instances = face->root.style_flags >> 16;
 
-      /* the various `*_size' variables, which we also use as     */
-      /* offsets into the `mmlen' array, must be multiples of the */
-      /* pointer size (except the last one); without such an      */
-      /* alignment there might be runtime errors due to           */
-      /* misaligned addresses                                     */
+    /* prepare storage area for MM data; this cannot overflow   */
+    /* 32-bit arithmetic because of the size limits used in the */
+    /* `fvar' table validity check in `sfnt_init_face'          */
+
+    /* the various `*_size' variables, which we also use as     */
+    /* offsets into the `mmlen' array, must be multiples of the */
+    /* pointer size (except the last one); without such an      */
+    /* alignment there might be runtime errors due to           */
+    /* misaligned addresses                                     */
 #undef  ALIGN_SIZE
 #define ALIGN_SIZE( n ) \
           ( ( (n) + sizeof (void*) - 1 ) & ~( sizeof (void*) - 1 ) )
 
-      mmvar_size       = ALIGN_SIZE( sizeof ( FT_MM_Var ) );
-      axis_flags_size  = ALIGN_SIZE( fvar_head.axisCount *
-                                     sizeof ( FT_UShort ) );
-      axis_size        = ALIGN_SIZE( fvar_head.axisCount *
-                                     sizeof ( FT_Var_Axis ) );
-      namedstyle_size  = ALIGN_SIZE( num_instances *
-                                     sizeof ( FT_Var_Named_Style ) );
-      next_coords_size = ALIGN_SIZE( num_instances *
-                                     fvar_head.axisCount *
-                                     sizeof ( FT_Fixed ) );
-      next_name_size   = fvar_head.axisCount * 5;
+    mmvar_size       = ALIGN_SIZE( sizeof ( FT_MM_Var ) );
+    axis_flags_size  = ALIGN_SIZE( num_axes *
+                                   sizeof ( FT_UShort ) );
+    axis_size        = ALIGN_SIZE( num_axes *
+                                   sizeof ( FT_Var_Axis ) );
+    namedstyle_size  = ALIGN_SIZE( num_instances *
+                                   sizeof ( FT_Var_Named_Style ) );
+    next_coords_size = ALIGN_SIZE( num_instances *
+                                   num_axes *
+                                   sizeof ( FT_Fixed ) );
+    next_name_size   = num_axes * 5;
 
+    if ( need_init )
+    {
       face->blend->mmvar_len = mmvar_size       +
                                axis_flags_size  +
                                axis_size        +
@@ -2090,7 +2101,7 @@
       /* the data gets filled in later on                    */
 
       mmvar->num_axis =
-        fvar_head.axisCount;
+        num_axes;
       mmvar->num_designs =
         ~0U;                   /* meaningless in this context; each glyph */
                                /* may have a different number of designs  */
@@ -2111,12 +2122,12 @@
       for ( i = 0; i < num_instances; i++ )
       {
         mmvar->namedstyle[i].coords  = next_coords;
-        next_coords                 += fvar_head.axisCount;
+        next_coords                 += num_axes;
       }
 
       next_name = (FT_String*)( (char*)mmvar->namedstyle +
                                 namedstyle_size + next_coords_size );
-      for ( i = 0; i < fvar_head.axisCount; i++ )
+      for ( i = 0; i < num_axes; i++ )
       {
         mmvar->axis[i].name  = next_name;
         next_name           += 5;
@@ -2128,7 +2139,7 @@
         goto Exit;
 
       a = mmvar->axis;
-      for ( i = 0; i < fvar_head.axisCount; i++ )
+      for ( i = 0; i < num_axes; i++ )
       {
         GX_FVar_Axis  axis_rec;
 
@@ -2178,7 +2189,7 @@
       /* named instance coordinates are stored as design coordinates; */
       /* we have to convert them to normalized coordinates also       */
       if ( FT_NEW_ARRAY( face->blend->normalized_stylecoords,
-                         fvar_head.axisCount * num_instances ) )
+                         num_axes * num_instances ) )
         goto Exit;
 
       if ( fvar_head.instanceCount && !face->blend->avar_loaded )
@@ -2198,7 +2209,7 @@
       {
         /* PostScript names add 2 bytes to the instance record size */
         if ( FT_FRAME_ENTER( ( usePsName ? 6L : 4L ) +
-                             4L * fvar_head.axisCount ) )
+                             4L * num_axes ) )
           goto Exit;
 
         ns->strid       =    FT_GET_USHORT();
@@ -2205,7 +2216,7 @@
         (void) /* flags = */ FT_GET_USHORT();
 
         c = ns->coords;
-        for ( j = 0; j < fvar_head.axisCount; j++, c++ )
+        for ( j = 0; j < num_axes; j++, c++ )
           *c = FT_GET_LONG();
 
         /* valid psid values are 6, [256;32767], and 0xFFFF */
@@ -2214,11 +2225,8 @@
         else
           ns->psid = 0xFFFF;
 
-        ft_var_to_normalized( face,
-                              fvar_head.axisCount,
-                              ns->coords,
-                              nsc );
-        nsc += fvar_head.axisCount;
+        ft_var_to_normalized( face, num_axes, ns->coords, nsc );
+        nsc += num_axes;
 
         FT_FRAME_EXIT();
       }
@@ -2267,7 +2275,7 @@
 
             a = mmvar->axis;
             c = ns->coords;
-            for ( j = 0; j < fvar_head.axisCount; j++, a++, c++ )
+            for ( j = 0; j < num_axes; j++, a++, c++ )
               *c = a->def;
           }
         }
@@ -2288,23 +2296,24 @@
       FT_MEM_COPY( mmvar, face->blend->mmvar, face->blend->mmvar_len );
 
       axis_flags =
-        (FT_UShort*)&( mmvar[1] );
+        (FT_UShort*)( (char*)mmvar + mmvar_size );
       mmvar->axis =
-        (FT_Var_Axis*)&( axis_flags[mmvar->num_axis] );
+        (FT_Var_Axis*)( (char*)axis_flags + axis_flags_size );
       mmvar->namedstyle =
-        (FT_Var_Named_Style*)&( mmvar->axis[mmvar->num_axis] );
+        (FT_Var_Named_Style*)( (char*)mmvar->axis+ axis_size );
 
-      next_coords =
-        (FT_Fixed*)&( mmvar->namedstyle[mmvar->num_namedstyles] );
+      next_coords = (FT_Fixed*)( (char*)mmvar->namedstyle +
+                                 namedstyle_size );
       for ( n = 0; n < mmvar->num_namedstyles; n++ )
       {
         mmvar->namedstyle[n].coords  = next_coords;
-        next_coords                 += mmvar->num_axis;
+        next_coords                 += num_axes;
       }
 
       a         = mmvar->axis;
-      next_name = (FT_String*)next_coords;
-      for ( n = 0; n < mmvar->num_axis; n++ )
+      next_name = (FT_String*)( (char*)mmvar->namedstyle +
+                                namedstyle_size + next_coords_size );
+      for ( n = 0; n < num_axes; n++ )
       {
         a->name = next_name;