Commit 56be3ac9b13701a5b004c548e5ead5197cfab7d3

suzuki toshiya 2011-06-14T23:53:12

[gxvalid] Fix gcc4.6 compiler warnings in gxvmort*.c. * src/gxvalid/gxvmort.c (gxv_mort_subtables_validate): Conditionalize unvalidated variable `subFeatureFlags'. (gxv_mort_chain_validate): Conditionalize unvalidated variable `defaultFlags'. * src/gxvalid/gxmort0.c (gxv_mort_subtable_type0_entry_validate): Check the conflict of the marks for the glyphs. * src/gxvalid/gxmort1.c (gxv_mort_subtable_type1_offset_to_subst_validate): Local variables `min_gid', `max_gid' are replaced by variables in the validator. (gxv_mort_subtable_type1_entry_validate): Conditionalize unvalidated variables; `setMark', `dontAdvance'. (gxv_mort_subtable_type1_substTable_validate): Validate the GID by the min/max GIDs in the validator. * src/gxvalid/gxvmort2.c (gxv_mort_subtable_type2_ligActionOffset_validate): Conditionalize unvalidated variables; `last', `store'. Checking for overrunning offset is added. (gxv_mort_subtable_type2_entry_validate): Conditionalize unvalidated variables; `setComponent', `dontAdvance'. (gxv_mort_subtable_type2_ligatureTable_validate): Check if the GID for ligature does not exceed the max GID in `maxp' table. * src/gxvalid/gxvmort5.c (gxv_mort_subtable_type5_InsertList_validate): Conditionalize unvalidated loading of `insert_glyphID' array. (gxv_mort_subtable_type5_entry_validate): Conditionalize unvalidated variables; `setMark', `dontAdvance', `currentIsKashidaLike', `markedIsKashidaLike', `currentInsertBefore', `markedInsertBefore'.

diff --git a/ChangeLog b/ChangeLog
index 8c6ce42..fdc8c42 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,47 @@
 2011-06-14  suzuki toshiya  <mpsuzuki@hiroshima-u.ac.jp>
 
+	[gxvalid] Fix gcc4.6 compiler warnings in gxvmort*.c.
+
+	* src/gxvalid/gxvmort.c (gxv_mort_subtables_validate):
+	Conditionalize unvalidated variable `subFeatureFlags'.
+	(gxv_mort_chain_validate): Conditionalize unvalidated
+	variable `defaultFlags'.
+
+	* src/gxvalid/gxmort0.c
+	(gxv_mort_subtable_type0_entry_validate): Check the
+	conflict of the marks for the glyphs.
+
+	* src/gxvalid/gxmort1.c
+	(gxv_mort_subtable_type1_offset_to_subst_validate):
+	Local variables `min_gid', `max_gid' are replaced by
+	variables in the validator.
+	(gxv_mort_subtable_type1_entry_validate): Conditionalize
+	unvalidated variables; `setMark', `dontAdvance'.
+	(gxv_mort_subtable_type1_substTable_validate):
+	Validate the GID by the min/max GIDs in the validator.
+
+	* src/gxvalid/gxvmort2.c
+	(gxv_mort_subtable_type2_ligActionOffset_validate):
+	Conditionalize unvalidated variables; `last', `store'.
+	Checking for overrunning offset is added.
+	(gxv_mort_subtable_type2_entry_validate):
+	Conditionalize unvalidated variables; `setComponent',
+	`dontAdvance'.
+	(gxv_mort_subtable_type2_ligatureTable_validate):
+	Check if the GID for ligature does not exceed the
+	max GID in `maxp' table.
+
+	* src/gxvalid/gxvmort5.c
+	(gxv_mort_subtable_type5_InsertList_validate):
+	Conditionalize unvalidated loading of `insert_glyphID'
+	array.  (gxv_mort_subtable_type5_entry_validate):
+	Conditionalize unvalidated variables; `setMark',
+	`dontAdvance', `currentIsKashidaLike',
+	`markedIsKashidaLike', `currentInsertBefore',
+	`markedInsertBefore'.
+
+2011-06-14  suzuki toshiya  <mpsuzuki@hiroshima-u.ac.jp>
+
 	[gxvalid] Fix gcc4.6 compiler warnings in gxvkern.c.
 
 	* src/gxvalid/gxvkern.c
diff --git a/src/gxvalid/gxvmort.c b/src/gxvalid/gxvmort.c
index 0aa0663..50393b9 100644
--- a/src/gxvalid/gxvmort.c
+++ b/src/gxvalid/gxvmort.c
@@ -176,7 +176,9 @@
     {
       FT_UShort  length;
       FT_UShort  coverage;
+#ifdef GXV_LOAD_UNUSED_VARS
       FT_ULong   subFeatureFlags;
+#endif
       FT_UInt    type;
       FT_UInt    rest;
 
@@ -184,7 +186,11 @@
       GXV_LIMIT_CHECK( 2 + 2 + 4 );
       length          = FT_NEXT_USHORT( p );
       coverage        = FT_NEXT_USHORT( p );
+#ifdef GXV_LOAD_UNUSED_VARS
       subFeatureFlags = FT_NEXT_ULONG( p );
+#else
+      p += 4;
+#endif
 
       GXV_TRACE(( "validating chain subtable %d/%d (%d bytes)\n",
                   i + 1, nSubtables, length ));
@@ -204,6 +210,7 @@
       func( p, p + rest, valid );
 
       p += rest;
+      /* TODO: validate subFeatureFlags */
     }
 
     valid->subtable_length = p - table;
@@ -218,7 +225,9 @@
                            GXV_Validator  valid )
   {
     FT_Bytes   p = table;
+#ifdef GXV_LOAD_UNUSED_VARS
     FT_ULong   defaultFlags;
+#endif
     FT_ULong   chainLength;
     FT_UShort  nFeatureFlags;
     FT_UShort  nSubtables;
@@ -227,7 +236,11 @@
     GXV_NAME_ENTER( "mort chain header" );
 
     GXV_LIMIT_CHECK( 4 + 4 + 2 + 2 );
+#ifdef GXV_LOAD_UNUSED_VARS
     defaultFlags  = FT_NEXT_ULONG( p );
+#else
+    p += 4;
+#endif
     chainLength   = FT_NEXT_ULONG( p );
     nFeatureFlags = FT_NEXT_USHORT( p );
     nSubtables    = FT_NEXT_USHORT( p );
@@ -238,6 +251,7 @@
     gxv_mort_subtables_validate( p, table + chainLength, nSubtables, valid );
     valid->subtable_length = chainLength;
 
+    /* TODO: validate defaultFlags */
     GXV_EXIT;
   }
 
diff --git a/src/gxvalid/gxvmort0.c b/src/gxvalid/gxvmort0.c
index 0453062..65606ad 100644
--- a/src/gxvalid/gxvmort0.c
+++ b/src/gxvalid/gxvmort0.c
@@ -98,10 +98,27 @@
     GXV_TRACE(( " %02d", verb ));
     GXV_TRACE(( " %s\n", GXV_Mort_IndicScript_Msg[verb] ));
 
+    if ( markFirst > 0 && markLast > 0 )
+    {
+      GXV_TRACE(( "  [odd] a glyph is marked as the first and last"
+                  "  in Indic rearrangement\n" ));
+      if ( valid->root->level >= FT_VALIDATE_PARANOID )
+        FT_INVALID_DATA;
+    }
+
+    if ( markFirst > 0 && dontAdvance > 0 )
+    {
+      GXV_TRACE(( "  [odd] the first glyph is marked as dontAdvance"
+                  " in Indic rearrangement\n" ));
+      if ( valid->root->level >= FT_VALIDATE_PARANOID )
+        FT_INVALID_DATA;
+    }
+
     if ( 0 < reserved )
     {
       GXV_TRACE(( " non-zero bits found in reserved range\n" ));
-      FT_INVALID_DATA;
+      if ( valid->root->level >= FT_VALIDATE_PARANOID )
+        FT_INVALID_DATA;
     }
     else
       GXV_TRACE(( "\n" ));
diff --git a/src/gxvalid/gxvmort1.c b/src/gxvalid/gxvmort1.c
index 696d850..512f6a9 100644
--- a/src/gxvalid/gxvmort1.c
+++ b/src/gxvalid/gxvmort1.c
@@ -106,8 +106,6 @@
   {
     FT_UShort  substTable;
     FT_UShort  substTable_limit;
-    FT_UShort  min_gid;
-    FT_UShort  max_gid;
 
     FT_UNUSED( tag );
     FT_UNUSED( state );
@@ -121,9 +119,10 @@
                    ((GXV_mort_subtable_type1_StateOptRec *)
                     (valid->statetable.optdata))->substitutionTable_length );
 
-    min_gid = (FT_UShort)( ( substTable       - wordOffset * 2 ) / 2 );
-    max_gid = (FT_UShort)( ( substTable_limit - wordOffset * 2 ) / 2 );
-    max_gid = (FT_UShort)( FT_MAX( max_gid, valid->face->num_glyphs ) );
+    valid->min_gid = (FT_UShort)( ( substTable       - wordOffset * 2 ) / 2 );
+    valid->max_gid = (FT_UShort)( ( substTable_limit - wordOffset * 2 ) / 2 );
+    valid->max_gid = (FT_UShort)( FT_MAX( valid->max_gid,
+                                          valid->face->num_glyphs ) );
 
     /* XXX: check range? */
 
@@ -140,8 +139,10 @@
     FT_Bytes                        limit,
     GXV_Validator                   valid )
   {
+#ifdef GXV_LOAD_UNUSED_VARS
     FT_UShort  setMark;
     FT_UShort  dontAdvance;
+#endif
     FT_UShort  reserved;
     FT_Short   markOffset;
     FT_Short   currentOffset;
@@ -150,8 +151,10 @@
     FT_UNUSED( limit );
 
 
+#ifdef GXV_LOAD_UNUSED_VARS
     setMark       = (FT_UShort)(   flags >> 15            );
     dontAdvance   = (FT_UShort)( ( flags >> 14 ) & 1      );
+#endif
     reserved      = (FT_Short)(    flags         & 0x3FFF );
 
     markOffset    = (FT_Short)( glyphOffset_p->ul >> 16 );
@@ -200,11 +203,11 @@
       if ( dst_gid >= 0xFFFFU )
         continue;
 
-      if ( dst_gid > valid->face->num_glyphs )
+      if ( dst_gid < valid->min_gid || valid->max_gid < dst_gid )
       {
-        GXV_TRACE(( "substTable include too large gid[%d]=%d >"
-                    " max defined gid #%d\n",
-                    i, dst_gid, valid->face->num_glyphs ));
+        GXV_TRACE(( "substTable include a strange gid[%d]=%d >"
+                    " out of define range (%d..%d)\n",
+                    i, dst_gid, valid->min_gid, valid->max_gid ));
         if ( valid->root->level >= FT_VALIDATE_PARANOID )
           FT_INVALID_GLYPH_ID;
       }
diff --git a/src/gxvalid/gxvmort2.c b/src/gxvalid/gxvmort2.c
index 6f77cf3..97a1f60 100644
--- a/src/gxvalid/gxvmort2.c
+++ b/src/gxvalid/gxvmort2.c
@@ -171,16 +171,42 @@
     {
       /* validate entry in ligActionTable */
       FT_ULong   lig_action;
+#ifdef GXV_LOAD_UNUSED_VARS
       FT_UShort  last;
       FT_UShort  store;
+#endif
       FT_ULong   offset;
 
 
       lig_action = FT_NEXT_ULONG( p );
+#ifdef GXV_LOAD_UNUSED_VARS
       last   = (FT_UShort)( ( lig_action >> 31 ) & 1 );
       store  = (FT_UShort)( ( lig_action >> 30 ) & 1 );
+#endif
 
+      /* Apple spec defines this offset as a word offset */
       offset = lig_action & 0x3FFFFFFFUL;
+      if ( offset * 2 < optdata->ligatureTable )
+      {
+        GXV_TRACE(( "too short offset 0x%08x:"
+                    " 2 x offset < ligatureTable (%d byte rewind)\n",
+                     offset, optdata->ligatureTable - offset * 2 ));
+
+        if ( valid->root->level >= FT_VALIDATE_PARANOID )
+          FT_INVALID_OFFSET;
+      } else if ( offset * 2 >
+                  optdata->ligatureTable + optdata->ligatureTable_length )
+      {
+        GXV_TRACE(( "too long offset 0x%08x:"
+                    " 2 x offset > ligatureTable + ligatureTable_length"
+                    " (%d byte overrun)\n",
+                     offset,
+                     optdata->ligatureTable + optdata->ligatureTable_length
+                     - offset * 2 ));
+
+        if ( valid->root->level >= FT_VALIDATE_PARANOID )
+          FT_INVALID_OFFSET;
+      }
     }
   }
 
@@ -194,8 +220,10 @@
     FT_Bytes                        limit,
     GXV_Validator                   valid )
   {
+#ifdef GXV_LOAD_UNUSED_VARS
     FT_UShort setComponent;
     FT_UShort dontAdvance;
+#endif
     FT_UShort offset;
 
     FT_UNUSED( state );
@@ -203,8 +231,10 @@
     FT_UNUSED( limit );
 
 
+#ifdef GXV_LOAD_UNUSED_VARS
     setComponent = (FT_UShort)( ( flags >> 15 ) & 1 );
     dontAdvance  = (FT_UShort)( ( flags >> 14 ) & 1 );
+#endif
 
     offset = (FT_UShort)( flags & 0x3FFFU );
 
@@ -237,6 +267,10 @@
 
         GXV_LIMIT_CHECK( 2 );
         lig_gid = FT_NEXT_USHORT( p );
+
+        if ( valid->root->level >= FT_VALIDATE_PARANOID &&
+             valid->face->num_glyphs < lig_gid          )
+          FT_INVALID_GLYPH_ID;
       }
     }
     GXV_EXIT;
diff --git a/src/gxvalid/gxvmort5.c b/src/gxvalid/gxvmort5.c
index ec0bcb6..32cfb03 100644
--- a/src/gxvalid/gxvmort5.c
+++ b/src/gxvalid/gxvmort5.c
@@ -121,6 +121,9 @@
          offset < optdata->entryTable + *(optdata->entryTable_length_p) )
       GXV_TRACE(( " offset runs into EntryTable" ));
 
+#ifndef GXV_LOAD_TRACE_VARS
+    GXV_LIMIT_CHECK( count * 2 );
+#else
     while ( p < table + offset + ( count * 2 ) )
     {
       FT_UShort insert_glyphID;
@@ -130,8 +133,8 @@
       insert_glyphID = FT_NEXT_USHORT( p );
       GXV_TRACE(( " 0x%04x", insert_glyphID ));
     }
-
     GXV_TRACE(( "\n" ));
+#endif
   }
 
 
@@ -144,12 +147,14 @@
     FT_Bytes                        limit,
     GXV_Validator                   valid )
   {
+#ifdef GXV_LOAD_UNUSED_VARS
     FT_Bool    setMark;
     FT_Bool    dontAdvance;
     FT_Bool    currentIsKashidaLike;
     FT_Bool    markedIsKashidaLike;
     FT_Bool    currentInsertBefore;
     FT_Bool    markedInsertBefore;
+#endif
     FT_Byte    currentInsertCount;
     FT_Byte    markedInsertCount;
     FT_UShort  currentInsertList;
@@ -158,12 +163,14 @@
     FT_UNUSED( state );
 
 
+#ifdef GXV_LOAD_UNUSED_VARS
     setMark              = FT_BOOL( ( flags >> 15 ) & 1 );
     dontAdvance          = FT_BOOL( ( flags >> 14 ) & 1 );
     currentIsKashidaLike = FT_BOOL( ( flags >> 13 ) & 1 );
     markedIsKashidaLike  = FT_BOOL( ( flags >> 12 ) & 1 );
     currentInsertBefore  = FT_BOOL( ( flags >> 11 ) & 1 );
     markedInsertBefore   = FT_BOOL( ( flags >> 10 ) & 1 );
+#endif
 
     currentInsertCount   = (FT_Byte)( ( flags >> 5 ) & 0x1F   );
     markedInsertCount    = (FT_Byte)(   flags        & 0x001F );