Commit b0103677be2eac55f4a9c966d2ab4a5d597a57c6

Werner Lemberg 2017-09-23T00:40:28

[otvalid] Handle `GDEF' v1.2 and v1.3 tables. No validation of variation stuff yet. * src/otvalid/otvgdef.c (otv_MarkGlyphSets_validate): New function. (otv_GDEF_validate): Implement it.

diff --git a/ChangeLog b/ChangeLog
index a06bbbd..74ecf96 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2017-09-23  Werner Lemberg  <wl@gnu.org>
+
+	[otvalid] Handle `GDEF' v1.2 and v1.3 tables.
+
+	No validation of variation stuff yet.
+
+	* src/otvalid/otvgdef.c (otv_MarkGlyphSets_validate): New function.
+	(otv_GDEF_validate): Implement it.
+
 2017-09-22  Werner Lemberg  <wl@gnu.org>
 
 	[otvalid] Handle `BASE' v1.1 table.
diff --git a/src/otvalid/otvgdef.c b/src/otvalid/otvgdef.c
index 27b9a69..71f01a9 100644
--- a/src/otvalid/otvgdef.c
+++ b/src/otvalid/otvgdef.c
@@ -68,7 +68,7 @@
     OTV_LIMIT_CHECK( GlyphCount * 2 );
 
     otvalid->nesting_level++;
-    func          = otvalid->func[otvalid->nesting_level];
+    func            = otvalid->func[otvalid->nesting_level];
     otvalid->extra1 = 0;
 
     for ( ; GlyphCount > 0; GlyphCount-- )
@@ -136,6 +136,40 @@
   /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/
+  /*****                       MARK GLYPH SETS                         *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  static void
+  otv_MarkGlyphSets_validate( FT_Bytes       table,
+                              OTV_Validator  otvalid )
+  {
+    FT_Bytes  p = table;
+    FT_UInt   MarkGlyphSetCount;
+
+
+    OTV_NAME_ENTER( "MarkGlyphSets" );
+
+    p += 2;     /* skip Format */
+
+    OTV_LIMIT_CHECK( 2 );
+    MarkGlyphSetCount = FT_NEXT_USHORT( p );
+
+    OTV_TRACE(( " (MarkGlyphSetCount = %d)\n", MarkGlyphSetCount ));
+
+    OTV_LIMIT_CHECK( MarkGlyphSetCount * 4 );      /* CoverageOffsets */
+
+    for ( ; MarkGlyphSetCount > 0; MarkGlyphSetCount-- )
+      otv_Coverage_validate( table + FT_NEXT_ULONG( p ), otvalid, -1 );
+
+    OTV_EXIT;
+  }
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
   /*****                         GDEF TABLE                            *****/
   /*****                                                               *****/
   /*************************************************************************/
@@ -152,14 +186,18 @@
   {
     OTV_ValidatorRec  otvalidrec;
     OTV_Validator     otvalid = &otvalidrec;
-    FT_Bytes          p     = table;
+    FT_Bytes          p       = table;
     FT_UInt           table_size;
-    FT_Bool           need_MarkAttachClassDef;
+    FT_UShort         version;
+    FT_Bool           need_MarkAttachClassDef = 1;
 
     OTV_OPTIONAL_TABLE( GlyphClassDef );
     OTV_OPTIONAL_TABLE( AttachListOffset );
     OTV_OPTIONAL_TABLE( LigCaretListOffset );
     OTV_OPTIONAL_TABLE( MarkAttachClassDef );
+    OTV_OPTIONAL_TABLE( MarkGlyphSetsDef );
+
+    OTV_OPTIONAL_TABLE32( itemVarStore );
 
 
     otvalid->root = ftvalid;
@@ -167,24 +205,49 @@
     FT_TRACE3(( "validating GDEF table\n" ));
     OTV_INIT;
 
-    OTV_LIMIT_CHECK( 12 );
+    OTV_LIMIT_CHECK( 4 );
 
-    if ( FT_NEXT_ULONG( p ) != 0x10000UL )          /* Version */
+    if ( FT_NEXT_USHORT( p ) != 1 )  /* majorVersion */
       FT_INVALID_FORMAT;
 
-    /* MarkAttachClassDef has been added to the OpenType */
-    /* specification without increasing GDEF's version,  */
-    /* so we use this ugly hack to find out whether the  */
-    /* table is needed actually.                         */
+    version = FT_NEXT_USHORT( p );   /* minorVersion */
 
-    need_MarkAttachClassDef = FT_BOOL(
-      otv_GSUBGPOS_have_MarkAttachmentType_flag( gsub ) ||
-      otv_GSUBGPOS_have_MarkAttachmentType_flag( gpos ) );
+    table_size = 10;
+    switch ( version )
+    {
+    case 0:
+      /* MarkAttachClassDef has been added to the OpenType */
+      /* specification without increasing GDEF's version,  */
+      /* so we use this ugly hack to find out whether the  */
+      /* table is needed actually.                         */
+
+      need_MarkAttachClassDef = FT_BOOL(
+        otv_GSUBGPOS_have_MarkAttachmentType_flag( gsub ) ||
+        otv_GSUBGPOS_have_MarkAttachmentType_flag( gpos ) );
+
+      if ( need_MarkAttachClassDef )
+      {
+        OTV_LIMIT_CHECK( 8 );
+        table_size += 2;
+      }
+      else
+        OTV_LIMIT_CHECK( 6 );  /* OpenType < 1.2 */
 
-    if ( need_MarkAttachClassDef )
-      table_size = 12;              /* OpenType >= 1.2 */
-    else
-      table_size = 10;              /* OpenType < 1.2  */
+      break;
+
+    case 2:
+      OTV_LIMIT_CHECK( 10 );
+      table_size += 4;
+      break;
+
+    case 3:
+      OTV_LIMIT_CHECK( 14 );
+      table_size += 8;
+      break;
+
+    default:
+      FT_INVALID_FORMAT;
+    }
 
     otvalid->glyph_count = glyph_count;
 
@@ -217,6 +280,22 @@
         otv_ClassDef_validate( table + MarkAttachClassDef, otvalid );
     }
 
+    if ( version > 0 )
+    {
+      OTV_OPTIONAL_OFFSET( MarkGlyphSetsDef );
+      OTV_SIZE_CHECK( MarkGlyphSetsDef );
+      if ( MarkGlyphSetsDef )
+        otv_MarkGlyphSets_validate( table + MarkGlyphSetsDef, otvalid );
+    }
+
+    if ( version > 2 )
+    {
+      OTV_OPTIONAL_OFFSET32( itemVarStore );
+      OTV_SIZE_CHECK32( itemVarStore );
+      if ( itemVarStore )
+        OTV_TRACE(( "  [omitting itemVarStore validation]\n" )); /* XXX */
+    }
+
     FT_TRACE4(( "\n" ));
   }