Commit 7d1d3b9a0e9310376a559ad2eac8a9dc4c60ce59

Werner Lemberg 2019-08-26T09:08:56

[type1] Fix `FT_Get_Var_Axis_Flags' (#56804). * src/type1/t1load.c (T1_Get_MM_Var): Allocate space for axis flags. Also remove redundant assignment.

diff --git a/ChangeLog b/ChangeLog
index aea6278..fdd4e2b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,11 @@
-2019-06-26  Alexei Podtelezhnikov  <apodtele@gmail.com>
+2019-08-26  Werner Lemberg  <wl@gnu.org>
+
+	[type1] Fix `FT_Get_Var_Axis_Flags' (#56804).
+
+	* src/type1/t1load.c (T1_Get_MM_Var): Allocate space for axis flags.
+	Also remove redundant assignment.
+
+2019-07-24  Alexei Podtelezhnikov  <apodtele@gmail.com>
 
 	* src/base/ftbbox.c (cubic_peak): Sanitize left shift (#56586).
 
diff --git a/docs/CHANGES b/docs/CHANGES
index f36cb19..4b098af 100644
--- a/docs/CHANGES
+++ b/docs/CHANGES
@@ -1,6 +1,19 @@
 
 CHANGES BETWEEN 2.10.0 and 2.10.1
 
+  I. IMPORTANT CHANGES
+
+
+  II. MISCELLANEOUS
+
+  - Function  `FT_Get_Var_Axis_Flags' returned random data for  Type 1
+    MM fonts.
+
+
+======================================================================
+
+CHANGES BETWEEN 2.10.0 and 2.10.1
+
   I. IMPORTANT BUG FIXES
 
   - The bytecode hinting of OpenType variation fonts was flawed, since
diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c
index 78d87dc..9ce61df 100644
--- a/src/truetype/ttgxvar.c
+++ b/src/truetype/ttgxvar.c
@@ -2127,7 +2127,7 @@
     /* `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 */
+    /* offsets into the `mmvar' 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                                     */
diff --git a/src/type1/t1load.c b/src/type1/t1load.c
index 5cffdfa..64540ee 100644
--- a/src/type1/t1load.c
+++ b/src/type1/t1load.c
@@ -309,31 +309,55 @@
     FT_UInt          i;
     FT_Fixed         axiscoords[T1_MAX_MM_AXIS];
     PS_Blend         blend = face->blend;
+    FT_UShort*       axis_flags;
+
+    FT_Offset  mmvar_size;
+    FT_Offset  axis_flags_size;
+    FT_Offset  axis_size;
 
 
     error = T1_Get_Multi_Master( face, &mmaster );
     if ( error )
       goto Exit;
-    if ( FT_ALLOC( mmvar,
-                   sizeof ( FT_MM_Var ) +
-                     mmaster.num_axis * sizeof ( FT_Var_Axis ) ) )
+
+    /* the various `*_size' variables, which we also use as     */
+    /* offsets into the `mmvar' 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( mmaster.num_axis *
+                                  sizeof ( FT_UShort ) );
+    axis_size       = mmaster.num_axis * sizeof ( FT_Var_Axis );
+
+    if ( FT_ALLOC( mmvar, mmvar_size +
+                          axis_flags_size +
+                          axis_size ) )
       goto Exit;
 
     mmvar->num_axis        = mmaster.num_axis;
     mmvar->num_designs     = mmaster.num_designs;
     mmvar->num_namedstyles = 0;                           /* Not supported */
-    mmvar->axis            = (FT_Var_Axis*)&mmvar[1];
-                                      /* Point to axes after MM_Var struct */
-    mmvar->namedstyle      = NULL;
+
+    /* while axis flags are meaningless here, we have to provide the array */
+    /* to make `FT_Get_Var_Axis_Flags' work: the function expects that the */
+    /* values directly follow the data of `FT_MM_Var'                      */
+    axis_flags = (FT_UShort*)( (char*)mmvar + mmvar_size );
+    for ( i = 0; i < mmaster.num_axis; i++ )
+      axis_flags[i] = 0;
+
+    mmvar->axis       = (FT_Var_Axis*)( (char*)axis_flags + axis_flags_size );
+    mmvar->namedstyle = NULL;
 
     for ( i = 0; i < mmaster.num_axis; i++ )
     {
       mmvar->axis[i].name    = mmaster.axis[i].name;
       mmvar->axis[i].minimum = INT_TO_FIXED( mmaster.axis[i].minimum );
       mmvar->axis[i].maximum = INT_TO_FIXED( mmaster.axis[i].maximum );
-      mmvar->axis[i].def     = ( mmvar->axis[i].minimum +
-                                   mmvar->axis[i].maximum ) / 2;
-                            /* Does not apply.  But this value is in range */
       mmvar->axis[i].strid   = ~0U;                      /* Does not apply */
       mmvar->axis[i].tag     = ~0U;                      /* Does not apply */