Commit ce015ec8da96118472e83654ca83c1f95c9c1ff8

suzuki toshiya 2011-06-14T23:49:34

[gxvalid] Fix gcc4.6 compiler warnings in gxvjust.c. * src/gxvalid/gxvjust.c (gxv_just_check_max_gid): New function to unify the checks of too large GID. (gxv_just_wdp_entry_validate): Conditionalize unvalidated variables; `beforeGrowLimit', `beforeShrinkGrowLimit', `afterGrowLimit', `afterShrinkGrowLimit', `growFlags', `shrinkFlags'. Additional check for non-zero values in unused storage `justClass' is added. (gxv_just_actSubrecord_type0_validate): Conditionalize unvalidated variable `order'. GID is checked by gxv_just_check_max_gid(). Additional check for upside-down relationship between `lowerLimit' and `upperLimit' is added. (gxv_just_actSubrecord_type1_validate): GID is checked by gxv_just_check_max_gid(). (gxv_just_actSubrecord_type2_validate): Conditionalize unvalidated variable `substThreshhold'. GID is checked by gxv_just_check_max_gid(). (gxv_just_actSubrecord_type5_validate): GID is checked by gxv_just_check_max_gid(). (gxv_just_classTable_entry_validate): Conditionalize unvalidated variables; `setMark', `dontAdvance', `markClass', `currentClass'.

diff --git a/ChangeLog b/ChangeLog
index ddb43ec..ab5a816 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,31 @@
 2011-06-14  suzuki toshiya  <mpsuzuki@hiroshima-u.ac.jp>
 
+	[gxvalid] Fix gcc4.6 compiler warnings in gxvjust.c.
+
+	* src/gxvalid/gxvjust.c (gxv_just_check_max_gid):
+	New function to unify the checks of too large GID.
+	(gxv_just_wdp_entry_validate): Conditionalize unvalidated
+	variables; `beforeGrowLimit', `beforeShrinkGrowLimit',
+	`afterGrowLimit', `afterShrinkGrowLimit', `growFlags',
+	`shrinkFlags'.  Additional check for non-zero values in
+	unused storage `justClass' is added.
+	(gxv_just_actSubrecord_type0_validate): Conditionalize
+	unvalidated variable `order'.  GID is checked by
+	gxv_just_check_max_gid().  Additional check for upside-down
+	relationship between `lowerLimit' and `upperLimit' is added.
+	(gxv_just_actSubrecord_type1_validate): GID is checked by
+	gxv_just_check_max_gid().
+	(gxv_just_actSubrecord_type2_validate): Conditionalize
+	unvalidated variable `substThreshhold'.  GID is checked by
+	gxv_just_check_max_gid().
+	(gxv_just_actSubrecord_type5_validate): GID is checked by
+	gxv_just_check_max_gid().
+	(gxv_just_classTable_entry_validate): Conditionalize
+	unvalidated variables; `setMark', `dontAdvance',
+	`markClass', `currentClass'.
+
+2011-06-14  suzuki toshiya  <mpsuzuki@hiroshima-u.ac.jp>
+
 	[gxvalid] Preparation to fix gcc4.6 compiler warnings.
 
 	* src/gxvalid/gxvcommn.h (GXV_LOAD_TRACE_VARS): New macro to
diff --git a/src/gxvalid/gxvjust.c b/src/gxvalid/gxvjust.c
index e14f946..ed4f1e9 100644
--- a/src/gxvalid/gxvjust.c
+++ b/src/gxvalid/gxvjust.c
@@ -65,6 +65,23 @@
 #define  GXV_JUST_DATA( a )  GXV_TABLE_DATA( just, a )
 
 
+  /* GX just table does not define their subset of GID */
+  static void
+  gxv_just_check_max_gid( FT_UShort         gid,
+                          const FT_String*  msg_tag,
+                          GXV_Validator     valid )
+  {
+    if ( gid < valid->face->num_glyphs )
+      return;
+
+    GXV_TRACE(( "just table includes too large %s"
+                " GID=%d > %d (in maxp)\n",
+                msg_tag, gid, valid->face->num_glyphs ));
+    if ( valid->root->level >= FT_VALIDATE_PARANOID )
+      FT_INVALID_GLYPH_ID;
+  }
+
+
   static void
   gxv_just_wdp_entry_validate( FT_Bytes       table,
                                FT_Bytes       limit,
@@ -72,24 +89,38 @@
   {
     FT_Bytes   p = table;
     FT_ULong   justClass;
+#ifdef GXV_LOAD_UNUSED_VARS
     FT_Fixed   beforeGrowLimit;
     FT_Fixed   beforeShrinkGrowLimit;
     FT_Fixed   afterGrowLimit;
     FT_Fixed   afterShrinkGrowLimit;
     FT_UShort  growFlags;
     FT_UShort  shrinkFlags;
+#endif
 
 
     GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 + 4 + 2 + 2 );
     justClass             = FT_NEXT_ULONG( p );
+#ifndef GXV_LOAD_UNUSED_VARS
+    p += 4 + 4 + 4 + 4 + 2 + 2;
+#else
     beforeGrowLimit       = FT_NEXT_ULONG( p );
     beforeShrinkGrowLimit = FT_NEXT_ULONG( p );
     afterGrowLimit        = FT_NEXT_ULONG( p );
     afterShrinkGrowLimit  = FT_NEXT_ULONG( p );
     growFlags             = FT_NEXT_USHORT( p );
     shrinkFlags           = FT_NEXT_USHORT( p );
+#endif
 
-    /* TODO: decode flags for human readability */
+    /* According to Apple spec, only 7bits in justClass is used */
+    if ( valid->root->level >= FT_VALIDATE_PARANOID &&
+         ( justClass & 0xFFFFFF80 ) != 0            )
+    {
+      GXV_TRACE(( "just table includes non-zero value"
+                  " in unused justClass higher bits"
+                  " of WidthDeltaPair" ));
+      FT_INVALID_DATA;
+    }
 
     valid->subtable_length = p - table;
   }
@@ -153,8 +184,9 @@
 
     FT_Fixed   lowerLimit;
     FT_Fixed   upperLimit;
-
+#ifdef GXV_LOAD_UNUSED_VARS
     FT_UShort  order;
+#endif
     FT_UShort  decomposedCount;
 
     FT_UInt    i;
@@ -163,9 +195,21 @@
     GXV_LIMIT_CHECK( 4 + 4 + 2 + 2 );
     lowerLimit      = FT_NEXT_ULONG( p );
     upperLimit      = FT_NEXT_ULONG( p );
+#ifdef GXV_LOAD_UNUSED_VARS
     order           = FT_NEXT_USHORT( p );
+#else
+    p += 2;
+#endif
     decomposedCount = FT_NEXT_USHORT( p );
 
+    if ( valid->root->level >= FT_VALIDATE_PARANOID &&
+         lowerLimit >= upperLimit                   )
+    {
+      GXV_TRACE(( "just table includes invalid range spec:"
+                  " lowerLimit(%d) > upperLimit(%d)\n"     ));
+      FT_INVALID_DATA;
+    }
+
     for ( i = 0; i < decomposedCount; i++ )
     {
       FT_UShort glyphs;
@@ -173,6 +217,7 @@
 
       GXV_LIMIT_CHECK( 2 );
       glyphs = FT_NEXT_USHORT( p );
+      gxv_just_check_max_gid( glyphs, "type0:glyphs", valid );
     }
 
     valid->subtable_length = p - table;
@@ -191,6 +236,8 @@
     GXV_LIMIT_CHECK( 2 );
     addGlyph = FT_NEXT_USHORT( p );
 
+    gxv_just_check_max_gid( addGlyph, "type1:addGlyph", valid );
+
     valid->subtable_length = p - table;
   }
 
@@ -201,16 +248,27 @@
                                         GXV_Validator  valid )
   {
     FT_Bytes   p = table;
+#ifdef GXV_LOAD_UNUSED_VARS
     FT_Fixed   substThreshhold; /* Apple misspelled "Threshhold" */
+#endif
     FT_UShort  addGlyph;
     FT_UShort  substGlyph;
 
 
     GXV_LIMIT_CHECK( 4 + 2 + 2 );
+#ifdef GXV_LOAD_UNUSED_VARS
     substThreshhold = FT_NEXT_ULONG( p );
+#else
+    p += 4;
+#endif
     addGlyph        = FT_NEXT_USHORT( p );
     substGlyph      = FT_NEXT_USHORT( p );
 
+    if ( addGlyph != 0xFFFF )
+      gxv_just_check_max_gid( addGlyph, "type2:addGlyph", valid );
+
+    gxv_just_check_max_gid( substGlyph, "type2:substGlyph", valid );
+
     valid->subtable_length = p - table;
   }
 
@@ -234,6 +292,21 @@
     maximumLimit   = FT_NEXT_ULONG( p );
 
     valid->subtable_length = p - table;
+
+    if ( variantsAxis != 0x64756374 ) /* 'duct' */
+      GXV_TRACE(( "variantsAxis 0x%08x is non default value",
+                   variantsAxis ));
+
+    if ( minimumLimit > noStretchValue )
+      GXV_TRACE(( "type4:minimumLimit 0x%08x > noStretchValue 0x%08x\n",
+                  minimumLimit, noStretchValue ));
+    else if ( noStretchValue > maximumLimit )
+      GXV_TRACE(( "type4:noStretchValue 0x%08x > maximumLimit 0x%08x\n",
+                  noStretchValue, maximumLimit ));
+    else if ( valid->root->level < FT_VALIDATE_PARANOID )
+      return;
+
+    FT_INVALID_DATA;
   }
 
 
@@ -251,6 +324,11 @@
     flags = FT_NEXT_USHORT( p );
     glyph = FT_NEXT_USHORT( p );
 
+    if ( flags )
+      GXV_TRACE(( "type5: nonzero value 0x%04x in unused flags\n",
+                   flags ));
+    gxv_just_check_max_gid( glyph, "type5:glyph", valid );
+
     valid->subtable_length = p - table;
   }
 
@@ -274,6 +352,11 @@
     actionType   = FT_NEXT_USHORT( p );
     actionLength = FT_NEXT_ULONG( p );
 
+    /* actionClass is related with justClass using 7bit only */
+    if ( valid->root->level >= FT_VALIDATE_PARANOID &&
+         ( actionClass & 0xFF80 ) != 0              )
+      FT_INVALID_DATA;
+
     if ( actionType == 0 )
       gxv_just_actSubrecord_type0_validate( p, limit, valid );
     else if ( actionType == 1 )
@@ -389,10 +472,13 @@
     FT_Bytes                        limit,
     GXV_Validator                   valid )
   {
+#ifdef GXV_LOAD_UNUSED_VARS
+    /* TODO: validate markClass & currentClass */
     FT_UShort  setMark;
     FT_UShort  dontAdvance;
     FT_UShort  markClass;
     FT_UShort  currentClass;
+#endif
 
     FT_UNUSED( state );
     FT_UNUSED( glyphOffset_p );
@@ -400,13 +486,14 @@
     FT_UNUSED( limit );
     FT_UNUSED( valid );
 
-
+#ifndef GXV_LOAD_UNUSED_VARS
+    FT_UNUSED( flags );
+#else
     setMark      = (FT_UShort)( ( flags >> 15 ) & 1    );
     dontAdvance  = (FT_UShort)( ( flags >> 14 ) & 1    );
     markClass    = (FT_UShort)( ( flags >> 7  ) & 0x7F );
     currentClass = (FT_UShort)(   flags         & 0x7F );
-
-    /* TODO: validate markClass & currentClass */
+#endif
   }
 
 
@@ -428,9 +515,15 @@
     coverage        = FT_NEXT_USHORT( p );
     subFeatureFlags = FT_NEXT_ULONG( p );
 
-    GXV_TRACE(( "  justClassTable: coverage = 0x%04x (%s)",
-                coverage,
-                ( 0x4000 & coverage ) == 0 ? "ascending" : "descending" ));
+    GXV_TRACE(( "  justClassTable: coverage = 0x%04x (%s) ", coverage ));
+    if ( ( coverage & 0x4000 ) == 0  )
+      GXV_TRACE(( "ascending\n" ));
+    else
+      GXV_TRACE(( "descending\n" ));
+
+    if ( subFeatureFlags )
+      GXV_TRACE(( "  justClassTable: nonzero value (0x%08x)"
+                  " in unused subFeatureFlags\n", subFeatureFlags ));
 
     valid->statetable.optdata               = NULL;
     valid->statetable.optdata_load_func     = NULL;
@@ -557,7 +650,6 @@
   {
     FT_Bytes           p     = table;
     FT_Bytes           limit = 0;
-    FT_Offset          table_size;
 
     GXV_ValidatorRec   validrec;
     GXV_Validator      valid = &validrec;
@@ -582,7 +674,6 @@
     GXV_INIT;
 
     limit      = valid->root->limit;
-    table_size = limit - table;
 
     GXV_LIMIT_CHECK( 4 + 2 + 2 + 2 );
     version     = FT_NEXT_ULONG( p );