freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[freetype2] master 3b3cb32: [truetype] Fix `mmvar' array pointers.


From: Werner LEMBERG
Subject: [freetype2] master 3b3cb32: [truetype] Fix `mmvar' array pointers.
Date: Thu, 21 Sep 2017 03:03:49 -0400 (EDT)

branch: master
commit 3b3cb32dd2340d86d3165961a4bb3dbd44353075
Author: Werner Lemberg <address@hidden>
Commit: Werner Lemberg <address@hidden>

    [truetype] Fix `mmvar' array pointers.
    
    Without this change, clang's AddressSanitizer reports many runtime
    errors due to misaligned addresses.
    
    * src/truetype/ttgxvar.c (TT_Get_MM_Var): Use multiples of pointer
    size for sub-array offsets into `mmvar'.
---
 ChangeLog              | 10 +++++++++
 src/truetype/ttgxvar.c | 56 ++++++++++++++++++++++++++++++++++++++------------
 2 files changed, 53 insertions(+), 13 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index f08b56a..ab5530f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2017-09-21  Werner Lemberg  <address@hidden>
+
+       [truetype] Fix `mmvar' array pointers.
+
+       Without this change, clang's AddressSanitizer reports many runtime
+       errors due to misaligned addresses.
+
+       * src/truetype/ttgxvar.c (TT_Get_MM_Var): Use multiples of pointer
+       size for sub-array offsets into `mmvar'.
+
 2017-09-20  Werner Lemberg  <address@hidden>
 
        [truetype] Integer overflows.
diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c
index 49aa53a..8c56c56 100644
--- a/src/truetype/ttgxvar.c
+++ b/src/truetype/ttgxvar.c
@@ -1997,6 +1997,14 @@
 
     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;
+
+
       FT_TRACE2(( "FVAR " ));
 
       /* both `fvar' and `gvar' must be present */
@@ -2045,13 +2053,34 @@
       /* 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'          */
-      face->blend->mmvar_len =
-        sizeof ( FT_MM_Var ) +
-        fvar_head.axisCount * sizeof ( FT_UShort ) +
-        fvar_head.axisCount * sizeof ( FT_Var_Axis ) +
-        num_instances * sizeof ( FT_Var_Named_Style ) +
-        num_instances * fvar_head.axisCount * sizeof ( FT_Fixed ) +
-        fvar_head.axisCount * 5;
+
+      /* 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;
+
+      face->blend->mmvar_len = mmvar_size       +
+                               axis_flags_size  +
+                               axis_size        +
+                               namedstyle_size  +
+                               next_coords_size +
+                               next_name_size;
 
       if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) )
         goto Exit;
@@ -2071,21 +2100,22 @@
 
       /* alas, no public field in `FT_Var_Axis' for axis flags */
       axis_flags =
-        (FT_UShort*)&( mmvar[1] );
+        (FT_UShort*)( (char*)mmvar + mmvar_size );
       mmvar->axis =
-        (FT_Var_Axis*)&( axis_flags[fvar_head.axisCount] );
+        (FT_Var_Axis*)( (char*)axis_flags + axis_flags_size );
       mmvar->namedstyle =
-        (FT_Var_Named_Style*)&( mmvar->axis[fvar_head.axisCount] );
+        (FT_Var_Named_Style*)( (char*)mmvar->axis + axis_size );
 
-      next_coords =
-        (FT_Fixed*)&( mmvar->namedstyle[num_instances] );
+      next_coords = (FT_Fixed*)( (char*)mmvar->namedstyle +
+                                 namedstyle_size );
       for ( i = 0; i < num_instances; i++ )
       {
         mmvar->namedstyle[i].coords  = next_coords;
         next_coords                 += fvar_head.axisCount;
       }
 
-      next_name = (FT_String*)next_coords;
+      next_name = (FT_String*)( (char*)mmvar->namedstyle +
+                                namedstyle_size + next_coords_size );
       for ( i = 0; i < fvar_head.axisCount; i++ )
       {
         mmvar->axis[i].name  = next_name;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]