Commit d5d3e41daca1bc3f27d83c0ac78107f92ef047a9

Yamato, Masatake (大和正武) 2006-12-30T20:17:30

(gxv_kern_subtable_fmt0_pairs_validate): New function. Checks uniqueness of the gid pairs. (gxv_kern_subtable_fmt0_validate): Move some code to `gxv_kern_subtable_fmt0_pairs_validate'.

diff --git a/ChangeLog b/ChangeLog
index 6f7f737..793b5b2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2006-12-31  Masatake YAMATO  <jet@gyve.org>
+
+	* src/gxvalid/gxvkern.c (gxv_kern_subtable_fmt0_pairs_validate): New function.
+	Checks uniqueness of the gid pairs.
+	(gxv_kern_subtable_fmt0_validate): Move some code to 
+	`gxv_kern_subtable_fmt0_pairs_validate'.
+
 2006-12-22  David Turner  <david@freetype.org>
 
 	* src/autofit/aflatin.c, src/truetype/ttgload.c: removing compiler
diff --git a/src/gxvalid/gxvkern.c b/src/gxvalid/gxvkern.c
index edc9af2..3b0e4b5 100644
--- a/src/gxvalid/gxvkern.c
+++ b/src/gxvalid/gxvkern.c
@@ -106,26 +106,19 @@
   /* ============================= format 0 ============================== */
 
   static void
-  gxv_kern_subtable_fmt0_validate( FT_Bytes       table,
-                                   FT_Bytes       limit,
-                                   GXV_Validator  valid )
+  gxv_kern_subtable_fmt0_pairs_validate( FT_Bytes       table,
+                                         FT_Bytes       limit,
+                                         FT_UShort      nPairs,
+                                         GXV_Validator  valid )
   {
-    FT_Bytes   p = table + GXV_KERN_SUBTABLE_HEADER_SIZE;
-
-    FT_UShort  nPairs;
-    FT_UShort  unitSize;
+    FT_Bytes   p = table;
     FT_UShort  i;
 
+    FT_UShort  last_gid_left  = 0;
+    FT_UShort  last_gid_right = 0;
 
-    GXV_NAME_ENTER( "kern subtable format0" );
 
-    unitSize = 2 + 2 + 2;
-    nPairs   = 0;
-
-    /* nPairs, searchRange, entrySelector, rangeShift */
-    GXV_LIMIT_CHECK( 2 + 2 + 2 + 2 );
-    gxv_BinSrchHeader_validate( p, limit, &unitSize, &nPairs, valid );
-    p += 2 + 2 + 2 + 2;
+    GXV_NAME_ENTER( "kern format 0 paris" );
 
     for ( i = 0; i < nPairs; i++ )
     {
@@ -133,17 +126,30 @@
       FT_UShort  gid_right;
       FT_Short   kernValue;
 
-      /* TODO: should be checked pairs are unique. */
-
 
-      /* left */
       gid_left  = FT_NEXT_USHORT( p );
-      gxv_glyphid_validate( gid_left, valid );
-
-      /* right */
       gid_right = FT_NEXT_USHORT( p );
+
+      GXV_TRACE(( "left gid = %u, right gid = %u\n", gid_left, gid_right ));
+      gxv_glyphid_validate( gid_left, valid );
       gxv_glyphid_validate( gid_right, valid );
 
+      /* A pair of left and right gid must be uniqe and be sorted. */
+      if ( gid_left == last_gid_left )
+      {
+        if ( last_gid_right < gid_right )
+          last_gid_right = gid_right;
+        else
+          FT_INVALID_DATA;
+      }
+      else if ( last_gid_left < gid_left )
+      {
+        last_gid_left  = gid_left;
+        last_gid_right = gid_right;
+      }
+      else
+        FT_INVALID_DATA;
+
       /* skip the kern value */
       kernValue = FT_NEXT_SHORT( p );
     }
@@ -151,6 +157,32 @@
     GXV_EXIT;
   }
 
+  static void
+  gxv_kern_subtable_fmt0_validate( FT_Bytes       table,
+                                   FT_Bytes       limit,
+                                   GXV_Validator  valid )
+  {
+    FT_Bytes   p = table + GXV_KERN_SUBTABLE_HEADER_SIZE;
+
+    FT_UShort  nPairs;
+    FT_UShort  unitSize;
+
+
+    GXV_NAME_ENTER( "kern subtable format0" );
+
+    unitSize = 2 + 2 + 2;
+    nPairs   = 0;
+
+    /* nPairs, searchRange, entrySelector, rangeShift */
+    GXV_LIMIT_CHECK( 2 + 2 + 2 + 2 );
+    gxv_BinSrchHeader_validate( p, limit, &unitSize, &nPairs, valid );
+    p += 2 + 2 + 2 + 2;
+
+    gxv_kern_subtable_fmt0_pairs_validate( p, limit, nPairs, valid );
+
+    GXV_EXIT;
+  }
+
 
   /* ============================= format 1 ============================== */