shithub: freetype+ttf2subf

Download patch

ref: 1ac8f43463397386887414c99c40fd4421d655c8
parent: ec39a8a3914a19a39742778a397c967dbb0ba0d0
author: Werner Lemberg <[email protected]>
date: Thu Aug 12 19:50:37 EDT 2004

* src/otlayout/otcommn.c: Use OTL_CHECK everywhere.
(otl_coverage_validate): Initialize `p',
s/count/num_glyphs/.
s/start_cover/start_coverage/.
(otl_coverage_get_index): Return OTL_Long, not OTL_Int.
Remove unused variables.
(otl_class_definition_validate): s/count/num_glyphs/.
Remove unused variables.
(otl_class_definition_get_value, otl_device_table_get_start,
otl_device_table_get_end, otl_device_table_get_delta,
otl_lookup_get_table, otl_lookup_list_get_count,
otl_lookup_list_get_lookup, otl_lookup_list_get_table,
otl_feature_get_lookups, otl_feature_list_get_count,
otl_feature_list_get_feature, otl_lang_get_count,
otl_lang_get_req_feature, otl_lang_get_features): Commented out
temporarily until we really need it.
(otl_lookup_validate): Removed.
(otl_lookup_table_validate): Renamed to ...
(otl_lookup_validate): This.  Update callers.
(otl_lookup_list_validate): Remove already commented out definition
and move the other definition up.
(otl_feature_validate): Add parameter to pass number of lookups.
Update callers.
Check lookup indices.
(otl_feature_list_validate): Add parameter to pass lookup table.
Update callers.
(otl_lang_validate): Add parameter to pass number of features.
Update callers.
Handle req_feature and check feature indices.
(otl_script_validate): Add parameter to pass number of features.
Update callers.
(otl_script_list_validate): Add parameter to pass feature table.
Update callers.

* src/otlayout/otcommn.h: s/LOCALDEF/LOCAL/.
Comment out the same functions as in otcommn.c.
(otl_script_list_get_script): Removed.

* src/otlayout/otlgsub.c (otl_gsub_lookup1_apply): Change `index' to
type OTL_Long.
(otl_gsub_lookup2_apply, otl_gsub_lookup3_apply): Change `index' to
type OTL_Long.
Fix test.
(otl_gsub_validate): Fix order of validation.

* src/otlayout/otlgpos.c (otl_gpos_validate): Fix order of
validation.

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,53 @@
+2004-08-13  Werner Lemberg  <[email protected]>
+
+	* src/otlayout/otcommn.c: Use OTL_CHECK everywhere.
+	(otl_coverage_validate): Initialize `p',
+	s/count/num_glyphs/.
+	s/start_cover/start_coverage/.
+	(otl_coverage_get_index): Return OTL_Long, not OTL_Int.
+	Remove unused variables.
+	(otl_class_definition_validate): s/count/num_glyphs/.
+	Remove unused variables.
+	(otl_class_definition_get_value, otl_device_table_get_start,
+	otl_device_table_get_end, otl_device_table_get_delta,
+	otl_lookup_get_table, otl_lookup_list_get_count,
+	otl_lookup_list_get_lookup, otl_lookup_list_get_table,
+	otl_feature_get_lookups, otl_feature_list_get_count,
+	otl_feature_list_get_feature, otl_lang_get_count,
+	otl_lang_get_req_feature, otl_lang_get_features): Commented out
+	temporarily until we really need it.
+	(otl_lookup_validate): Removed.
+	(otl_lookup_table_validate): Renamed to ...
+	(otl_lookup_validate): This.  Update callers.
+	(otl_lookup_list_validate): Remove already commented out definition
+	and move the other definition up.
+	(otl_feature_validate): Add parameter to pass number of lookups.
+	Update callers.
+	Check lookup indices.
+	(otl_feature_list_validate): Add parameter to pass lookup table.
+	Update callers.
+	(otl_lang_validate): Add parameter to pass number of features.
+	Update callers.
+	Handle req_feature and check feature indices.
+	(otl_script_validate): Add parameter to pass number of features.
+	Update callers.
+	(otl_script_list_validate): Add parameter to pass feature table.
+	Update callers.
+
+	* src/otlayout/otcommn.h: s/LOCALDEF/LOCAL/.
+	Comment out the same functions as in otcommn.c.
+	(otl_script_list_get_script): Removed.
+
+	* src/otlayout/otlgsub.c (otl_gsub_lookup1_apply): Change `index' to
+	type OTL_Long.
+	(otl_gsub_lookup2_apply, otl_gsub_lookup3_apply): Change `index' to
+	type OTL_Long.
+	Fix test.
+	(otl_gsub_validate): Fix order of validation.
+
+	* src/otlayout/otlgpos.c (otl_gpos_validate): Fix order of
+	validation.
+
 2004-08-12  Werner Lemberg  <[email protected]>
 
 	Make otlayout module compile (without actually working).
--- a/src/otlayout/otlcommn.c
+++ b/src/otlayout/otlcommn.c
@@ -31,12 +31,11 @@
   otl_coverage_validate( OTL_Bytes      table,
                          OTL_Validator  valid )
   {
-    OTL_Bytes  p;
+    OTL_Bytes  p = table;
     OTL_UInt   format;
 
 
-    if ( table + 4 > valid->limit )
-      OTL_INVALID_TOO_SHORT;
+    OTL_CHECK( 4 );
 
     format = OTL_NEXT_USHORT( p );
     switch ( format )
@@ -43,11 +42,10 @@
     {
     case 1:
       {
-        OTL_UInt  count = OTL_NEXT_USHORT( p );
+        OTL_UInt  num_glyphs = OTL_NEXT_USHORT( p );
 
 
-        if ( p + count * 2 >= valid->limit )
-          OTL_INVALID_TOO_SHORT;
+        OTL_CHECK( num_glyphs * 2 );
 
         /* XXX: check glyph indices */
       }
@@ -56,19 +54,19 @@
     case 2:
       {
         OTL_UInt  n, num_ranges = OTL_NEXT_USHORT( p );
-        OTL_UInt  start, end, start_cover, total = 0, last = 0;
+        OTL_UInt  start, end, start_coverage, total = 0, last = 0;
 
 
-        if ( p + num_ranges * 6 >= valid->limit )
-          OTL_INVALID_TOO_SHORT;
+        OTL_CHECK( num_ranges * 6 );
 
+        /* scan range records */
         for ( n = 0; n < num_ranges; n++ )
         {
-          start       = OTL_NEXT_USHORT( p );
-          end         = OTL_NEXT_USHORT( p );
-          start_cover = OTL_NEXT_USHORT( p );
+          start          = OTL_NEXT_USHORT( p );
+          end            = OTL_NEXT_USHORT( p );
+          start_coverage = OTL_NEXT_USHORT( p );
 
-          if ( start > end || start_cover != total )
+          if ( start > end || start_coverage != total )
             OTL_INVALID_DATA;
 
           if ( n > 0 && start <= last )
@@ -124,7 +122,7 @@
   }
 
 
-  OTL_LOCALDEF( OTL_Int )
+  OTL_LOCALDEF( OTL_Long )
   otl_coverage_get_index( OTL_Bytes  table,
                           OTL_UInt   glyph_index )
   {
@@ -148,7 +146,7 @@
           gindex = OTL_PEEK_USHORT( p );
 
           if ( glyph_index == gindex )
-            return (OTL_Int)mid;
+            return (OTL_Long)mid;
 
           if ( glyph_index < gindex )
             max = mid;
@@ -161,7 +159,7 @@
     case 2:
       {
         OTL_UInt  min = 0, max = count, mid;
-        OTL_UInt  start, end, delta, start_cover;
+        OTL_UInt  start, end;
 
 
         table += 4;
@@ -177,7 +175,7 @@
           else if ( glyph_index > end )
             min = mid + 1;
           else
-            return (OTL_Int)( glyph_index + OTL_NEXT_USHORT( p ) - start );
+            return (OTL_Long)( glyph_index + OTL_NEXT_USHORT( p ) - start );
         }
       }
       break;
@@ -206,8 +204,7 @@
     OTL_UInt   format;
 
 
-    if ( p + 4 > valid->limit )
-      OTL_INVALID_TOO_SHORT;
+    OTL_CHECK( 4 );
 
     format = OTL_NEXT_USHORT( p );
     switch ( format )
@@ -214,17 +211,14 @@
     {
     case 1:
       {
-        OTL_UInt  count, start = OTL_NEXT_USHORT( p );
+        OTL_UInt  num_glyphs, start = OTL_NEXT_USHORT( p );
 
 
-        if ( p + 2 > valid->limit )
-          OTL_INVALID_TOO_SHORT;
+        OTL_CHECK( 2 );
+        num_glyphs = OTL_NEXT_USHORT( p );
 
-        count = OTL_NEXT_USHORT( p );
+        OTL_CHECK( num_glyphs * 2 );
 
-        if ( p + count * 2 > valid->limit )
-          OTL_INVALID_TOO_SHORT;
-
         /* XXX: check glyph indices */
       }
       break;
@@ -232,17 +226,17 @@
     case 2:
       {
         OTL_UInt  n, num_ranges = OTL_NEXT_USHORT( p );
-        OTL_UInt  start, end, value, last = 0;
+        OTL_UInt  start, end, last = 0;
 
 
-        if ( p + num_ranges * 6 > valid->limit )
-          OTL_INVALID_TOO_SHORT;
+        OTL_CHECK( num_ranges * 6 );
 
+        /* scan class range records */
         for ( n = 0; n < num_ranges; n++ )
         {
           start = OTL_NEXT_USHORT( p );
           end   = OTL_NEXT_USHORT( p );
-          value = OTL_NEXT_USHORT( p );  /* ignored */
+          p    += 2;                        /* ignored */
 
           if ( start > end || ( n > 0 && start <= last ) )
             OTL_INVALID_DATA;
@@ -258,6 +252,7 @@
   }
 
 
+#if 0
   OTL_LOCALDEF( OTL_UInt )
   otl_class_definition_get_value( OTL_Bytes  table,
                                   OTL_UInt   glyph_index )
@@ -313,6 +308,7 @@
 
     return 0;
   }
+#endif
 
 
   /*************************************************************************/
@@ -331,8 +327,7 @@
     OTL_UInt   start, end, count, format;
 
 
-    if ( p + 8 > valid->limit )
-      OTL_INVALID_TOO_SHORT;
+    OTL_CHECK( 8 );
 
     start  = OTL_NEXT_USHORT( p );
     end    = OTL_NEXT_USHORT( p );
@@ -341,13 +336,13 @@
     if ( format < 1 || format > 3 || end < start )
       OTL_INVALID_DATA;
 
-    count = (OTL_UInt)( end - start + 1 );
+    count = end - start + 1;
 
-    if ( p + ( ( 1 << format ) * count ) / 8 > valid->limit )
-      OTL_INVALID_TOO_SHORT;
+    OTL_CHECK( ( 1 << format ) * count / 8 );
   }
 
 
+#if 0
   OTL_LOCALDEF( OTL_UInt )
   otl_device_table_get_start( OTL_Bytes  table )
   {
@@ -356,8 +351,10 @@
 
     return OTL_PEEK_USHORT( p );
   }
+#endif
 
 
+#if 0
   OTL_LOCALDEF( OTL_UInt )
   otl_device_table_get_end( OTL_Bytes  table )
   {
@@ -366,8 +363,10 @@
 
     return OTL_PEEK_USHORT( p );
   }
+#endif
 
 
+#if 0
   OTL_LOCALDEF( OTL_Int )
   otl_device_table_get_delta( OTL_Bytes  table,
                               OTL_UInt   size )
@@ -422,42 +421,43 @@
 
     return result;
   }
+#endif
 
 
   /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/
-  /*****                      LOOKUP LISTS                             *****/
+  /*****                         LOOKUPS                               *****/
   /*****                                                               *****/
   /*************************************************************************/
   /*************************************************************************/
 
   OTL_LOCALDEF( void )
-  otl_lookup_validate( OTL_Bytes      table,
-                       OTL_Validator  valid )
+  otl_lookup_validate( OTL_Bytes          table,
+                       OTL_UInt           type_count,
+                       OTL_ValidateFunc*  type_funcs,
+                       OTL_Validator      valid )
   {
-    OTL_Bytes  p = table;
-    OTL_UInt   num_tables;
+    OTL_Bytes         p = table;
+    OTL_UInt          lookup_type, lookup_flag, num_subtables;
+    OTL_ValidateFunc  validate;
 
 
-    if ( table + 6 > valid->limit )
-      OTL_INVALID_TOO_SHORT;
+    OTL_CHECK( 6 );
+    lookup_type   = OTL_NEXT_USHORT( p );
+    lookup_flag   = OTL_NEXT_USHORT( p );
+    num_subtables = OTL_NEXT_USHORT( p );
 
-    p += 4;
-    num_tables = OTL_NEXT_USHORT( p );
+    if ( lookup_type == 0 || lookup_type >= type_count )
+      OTL_INVALID_DATA;
 
-    if ( p + num_tables * 2 > valid->limit )
-      OTL_INVALID_TOO_SHORT;
+    validate = type_funcs[lookup_type - 1];
 
-    for ( ; num_tables > 0; num_tables-- )
-    {
-      OTL_UInt offset = OTL_NEXT_USHORT( p );
+    OTL_CHECK( 2 * num_subtables );
 
-      if ( table + offset >= valid->limit )
-        OTL_INVALID_OFFSET;
-    }
-
-    /* XXX: check sub-tables? */
+    /* scan subtables */
+    for ( ; num_subtables > 0; num_subtables-- )
+      validate( table + OTL_NEXT_USHORT( p ), valid );
   }
 
 
@@ -471,6 +471,7 @@
   }
 
 
+#if 0
   OTL_LOCALDEF( OTL_Bytes )
   otl_lookup_get_table( OTL_Bytes  table,
                         OTL_UInt   idx )
@@ -489,6 +490,7 @@
 
     return result;
   }
+#endif
 
 
   /*************************************************************************/
@@ -499,33 +501,28 @@
   /*************************************************************************/
   /*************************************************************************/
 
-#if 0
   OTL_LOCALDEF( void )
-  otl_lookup_list_validate( OTL_Bytes      table,
-                            OTL_Validator  valid )
+  otl_lookup_list_validate( OTL_Bytes          table,
+                            OTL_UInt           type_count,
+                            OTL_ValidateFunc*  type_funcs,
+                            OTL_Validator      valid )
   {
-    OTL_Bytes  p = table, q;
-    OTL_UInt   num_lookups, offset;
+    OTL_Bytes  p = table;
+    OTL_UInt   num_lookups;
 
 
-    if ( p + 2 > valid->limit )
-      OTL_INVALID_TOO_SHORT;
-
+    OTL_CHECK( 2 );
     num_lookups = OTL_NEXT_USHORT( p );
+    OTL_CHECK( 2 * num_lookups );
 
-    if ( p + num_lookups * 2 > valid->limit )
-      OTL_INVALID_TOO_SHORT;
-
+    /* scan lookup records */
     for ( ; num_lookups > 0; num_lookups-- )
-    {
-      offset = OTL_NEXT_USHORT( p );
-
-      otl_lookup_validate( table + offset, valid );
-    }
+      otl_lookup_validate( table + OTL_NEXT_USHORT( p ),
+                           type_count, type_funcs, valid );
   }
-#endif
 
 
+#if 0
   OTL_LOCALDEF( OTL_UInt )
   otl_lookup_list_get_count( OTL_Bytes  table )
   {
@@ -534,8 +531,10 @@
 
     return OTL_PEEK_USHORT( p );
   }
+#endif
 
 
+#if 0
   OTL_LOCALDEF( OTL_Bytes )
   otl_lookup_list_get_lookup( OTL_Bytes  table,
                               OTL_UInt   idx )
@@ -554,8 +553,10 @@
 
     return result;
   }
+#endif
 
 
+#if 0
   OTL_LOCALDEF( OTL_Bytes )
   otl_lookup_list_get_table( OTL_Bytes  table,
                              OTL_UInt   lookup_index,
@@ -570,6 +571,7 @@
 
     return result;
   }
+#endif
 
 
 #if 0
@@ -598,22 +600,21 @@
 
   OTL_LOCALDEF( void )
   otl_feature_validate( OTL_Bytes      table,
+                        OTL_UInt       lookup_count,
                         OTL_Validator  valid )
   {
     OTL_Bytes  p = table;
-    OTL_UInt   feat_params, num_lookups;
+    OTL_UInt   num_lookups;
 
 
-    if ( p + 4 > valid->limit )
-      OTL_INVALID_TOO_SHORT;
+    OTL_CHECK( 4 );
+    p           += 2;                       /* unused */
+    num_lookups  = OTL_NEXT_USHORT( p );
+    OTL_CHECK( 2 * num_lookups );
 
-    feat_params = OTL_NEXT_USHORT( p );  /* ignored */
-    num_lookups = OTL_NEXT_USHORT( p );
-
-    if ( p + num_lookups * 2 > valid->limit )
-      OTL_INVALID_TOO_SHORT;
-
-    /* XXX: check lookup indices */
+    for ( ; num_lookups > 0; num_lookups-- )
+      if ( OTL_NEXT_USHORT( p ) >= lookup_count )
+        OTL_INVALID_DATA;
   }
 
 
@@ -627,6 +628,7 @@
   }
 
 
+#if 0
   OTL_LOCALDEF( OTL_UInt )
   otl_feature_get_lookups( OTL_Bytes  table,
                            OTL_UInt   start,
@@ -651,6 +653,7 @@
 
     return result;
   }
+#endif
 
 
   /*************************************************************************/
@@ -663,30 +666,31 @@
 
   OTL_LOCALDEF( void )
   otl_feature_list_validate( OTL_Bytes      table,
+                             OTL_Bytes      lookups,
                              OTL_Validator  valid )
   {
     OTL_Bytes  p = table;
-    OTL_UInt   num_features, offset;
+    OTL_UInt   num_features, lookup_count;
 
 
-    if ( table + 2 > valid->limit )
-      OTL_INVALID_TOO_SHORT;
-
+    OTL_CHECK( 2 );
     num_features = OTL_NEXT_USHORT( p );
+    OTL_CHECK( 2 * num_features );
 
-    if ( p + num_features * 2 > valid->limit )
-      OTL_INVALID_TOO_SHORT;
+    lookup_count = otl_lookup_get_count( lookups );
 
+    /* scan feature records */
     for ( ; num_features > 0; num_features-- )
     {
-      p     += 4;                       /* skip tag */
-      offset = OTL_NEXT_USHORT( p );
+      p += 4;       /* skip tag */
 
-      otl_feature_validate( table + offset, valid );
+      otl_feature_validate( table + OTL_NEXT_USHORT( p ), lookup_count,
+                            valid );
     }
   }
 
 
+#if 0
   OTL_LOCALDEF( OTL_UInt )
   otl_feature_list_get_count( OTL_Bytes  table )
   {
@@ -695,8 +699,10 @@
 
     return OTL_PEEK_USHORT( p );
   }
+#endif
 
 
+#if 0
   OTL_LOCALDEF( OTL_Bytes )
   otl_feature_list_get_feature( OTL_Bytes  table,
                                 OTL_UInt   idx )
@@ -716,6 +722,7 @@
 
     return result;
   }
+#endif
 
 
 #if 0
@@ -748,39 +755,44 @@
 
   OTL_LOCALDEF( void )
   otl_lang_validate( OTL_Bytes      table,
+                     OTL_UInt       feature_count,
                      OTL_Validator  valid )
   {
     OTL_Bytes  p = table;
-    OTL_UInt   lookup_order;
     OTL_UInt   req_feature;
     OTL_UInt   num_features;
 
 
-    if ( table + 6 >= valid->limit )
-      OTL_INVALID_TOO_SHORT;
+    OTL_CHECK( 6 );
 
-    lookup_order = OTL_NEXT_USHORT( p );
+    p           += 2;                       /* unused */
     req_feature  = OTL_NEXT_USHORT( p );
     num_features = OTL_NEXT_USHORT( p );
 
-    /* XXX: check req_feature if not 0xFFFFU */
+    if ( req_feature != 0xFFFFU && req_feature >= feature_count )
+      OTL_INVALID_DATA;
 
-    if ( p + 2 * num_features >= valid->limit )
-      OTL_INVALID_TOO_SHORT;
+    OTL_CHECK( 2 * num_features );
 
-    /* XXX: check features indices! */
+    for ( ; num_features > 0; num_features-- )
+      if ( OTL_NEXT_USHORT( p ) >= feature_count )
+        OTL_INVALID_DATA;
   }
 
 
+#if 0
   OTL_LOCALDEF( OTL_UInt )
   otl_lang_get_count( OTL_Bytes  table )
   {
     OTL_Bytes  p = table + 4;
 
+
     return OTL_PEEK_USHORT( p );
   }
+#endif
 
 
+#if 0
   OTL_LOCALDEF( OTL_UInt )
   otl_lang_get_req_feature( OTL_Bytes  table )
   {
@@ -789,8 +801,10 @@
 
     return OTL_PEEK_USHORT( p );
   }
+#endif
 
 
+#if 0
   OTL_LOCALDEF( OTL_UInt )
   otl_lang_get_features( OTL_Bytes  table,
                          OTL_UInt   start,
@@ -813,10 +827,9 @@
 
     return result;
   }
+#endif
 
 
-
-
   /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/
@@ -825,9 +838,9 @@
   /*************************************************************************/
   /*************************************************************************/
 
-
   OTL_LOCALDEF( void )
   otl_script_validate( OTL_Bytes      table,
+                       OTL_UInt       feature_count,
                        OTL_Validator  valid )
   {
     OTL_UInt   default_lang, num_langs;
@@ -834,8 +847,7 @@
     OTL_Bytes  p = table;
 
 
-    if ( table + 4 > valid->limit )
-      OTL_INVALID_TOO_SHORT;
+    OTL_CHECK( 4 );
 
     default_lang = OTL_NEXT_USHORT( p );
     num_langs    = OTL_NEXT_USHORT( p );
@@ -846,18 +858,14 @@
         OTL_INVALID_OFFSET;
     }
 
-    if ( p + num_langs * 6 >= valid->limit )
-      OTL_INVALID_OFFSET;
+    OTL_CHECK( num_langs * 6 );
 
+    /* scan langsys records */
     for ( ; num_langs > 0; num_langs-- )
     {
-      OTL_UInt  offset;
+      p += 4;       /* skip tag */
 
-
-      p     += 4;  /* skip tag */
-      offset = OTL_NEXT_USHORT( p );
-
-      otl_lang_validate( table + offset, valid );
+      otl_lang_validate( table + OTL_NEXT_USHORT( p ), feature_count, valid );
     }
   }
 
@@ -864,83 +872,28 @@
 
   OTL_LOCALDEF( void )
   otl_script_list_validate( OTL_Bytes      list,
+                            OTL_Bytes      features,
                             OTL_Validator  valid )
   {
-    OTL_UInt   num_scripts;
+    OTL_UInt   num_scripts, feature_count;
     OTL_Bytes  p = list;
 
 
-    if ( list + 2 > valid->limit )
-      OTL_INVALID_TOO_SHORT;
-
+    OTL_CHECK( 2 );
     num_scripts = OTL_NEXT_USHORT( p );
+    OTL_CHECK( num_scripts * 6 );
 
-    if ( p + num_scripts * 6 > valid->limit )
-      OTL_INVALID_TOO_SHORT;
+    feature_count = otl_feature_get_count( features );
 
+    /* scan script records */
     for ( ; num_scripts > 0; num_scripts-- )
     {
-      OTL_UInt  offset;
+      p += 4;       /* skip tag */
 
-
-      p     += 4;                       /* skip tag */
-      offset = OTL_NEXT_USHORT( p );
-
-      otl_script_validate( list + offset, valid );
+      otl_script_validate( list + OTL_NEXT_USHORT( p ), feature_count,
+                           valid );
     }
   }
 
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*****                                                               *****/
-  /*****                         LOOKUP LISTS                          *****/
-  /*****                                                               *****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-  static void
-  otl_lookup_table_validate( OTL_Bytes          table,
-                             OTL_UInt           type_count,
-                             OTL_ValidateFunc*  type_funcs,
-                             OTL_Validator      valid )
-  {
-    OTL_Bytes         p = table;
-    OTL_UInt          lookup_type, lookup_flag, count;
-    OTL_ValidateFunc  validate;
-
-    OTL_CHECK( 6 );
-    lookup_type = OTL_NEXT_USHORT( p );
-    lookup_flag = OTL_NEXT_USHORT( p );
-    count       = OTL_NEXT_USHORT( p );
-
-    if ( lookup_type == 0 || lookup_type >= type_count )
-      OTL_INVALID_DATA;
-
-    validate = type_funcs[ lookup_type - 1 ];
-
-    OTL_CHECK( 2*count );
-    for ( ; count > 0; count-- )
-      validate( table + OTL_NEXT_USHORT( p ), valid );
-  }
-
-
-  OTL_LOCALDEF( void )
-  otl_lookup_list_validate( OTL_Bytes          table,
-                            OTL_UInt           type_count,
-                            OTL_ValidateFunc*  type_funcs,
-                            OTL_Validator      valid )
-  {
-    OTL_Bytes  p = table;
-    OTL_UInt   count;
-
-    OTL_CHECK( 2 );
-    count = OTL_NEXT_USHORT( p );
-
-    OTL_CHECK( 2*count );
-    for ( ; count > 0; count-- )
-      otl_lookup_table_validate( table + OTL_NEXT_USHORT( p ),
-                                 type_count, type_funcs, valid );
-  }
 
 /* END */
--- a/src/otlayout/otlcommn.h
+++ b/src/otlayout/otlcommn.h
@@ -33,17 +33,17 @@
   /*************************************************************************/
 
   /* validate coverage table */
-  OTL_LOCALDEF( void )
+  OTL_LOCAL( void )
   otl_coverage_validate( OTL_Bytes      base,
                          OTL_Validator  valid );
 
   /* return number of covered glyphs */
-  OTL_LOCALDEF( OTL_UInt )
+  OTL_LOCAL( OTL_UInt )
   otl_coverage_get_count( OTL_Bytes  base );
 
   /* Return the coverage index corresponding to a glyph glyph index. */
   /* Return -1 if the glyph isn't covered.                           */
-  OTL_LOCALDEF( OTL_Int )
+  OTL_LOCAL( OTL_Long )
   otl_coverage_get_index( OTL_Bytes  base,
                           OTL_UInt   glyph_index );
 
@@ -57,14 +57,16 @@
   /*************************************************************************/
 
   /* validate class definition table */
-  OTL_LOCALDEF( void )
+  OTL_LOCAL( void )
   otl_class_definition_validate( OTL_Bytes      table,
                                  OTL_Validator  valid );
 
+#if 0
   /* return class value for a given glyph index */
-  OTL_LOCALDEF( OTL_UInt )
+  OTL_LOCAL( OTL_UInt )
   otl_class_definition_get_value( OTL_Bytes  table,
                                   OTL_UInt   glyph_index );
+#endif
 
 
   /*************************************************************************/
@@ -76,22 +78,28 @@
   /*************************************************************************/
 
   /* validate a device table */
-  OTL_LOCALDEF( void )
+  OTL_LOCAL( void )
   otl_device_table_validate( OTL_Bytes      table,
                              OTL_Validator  valid );
 
+#if 0
   /* return a device table's first size */
-  OTL_LOCALDEF( OTL_UInt )
+  OTL_LOCAL( OTL_UInt )
   otl_device_table_get_start( OTL_Bytes  table );
+#endif
 
+#if 0
   /* return a device table's last size */
-  OTL_LOCALDEF( OTL_UInt )
+  OTL_LOCAL( OTL_UInt )
   otl_device_table_get_end( OTL_Bytes  table );
+#endif
 
+#if 0
   /* return pixel adjustment for a given size */
-  OTL_LOCALDEF( OTL_Int )
+  OTL_LOCAL( OTL_Int )
   otl_device_table_get_delta( OTL_Bytes  table,
                               OTL_UInt   size );
+#endif
 
 
   /*************************************************************************/
@@ -102,20 +110,22 @@
   /*************************************************************************/
   /*************************************************************************/
 
-  /* validate lookup table */
-  OTL_LOCALDEF( void )
-  otl_lookup_validate( OTL_Bytes      table,
-                       OTL_Validator  valid );
+  OTL_LOCAL( void )
+  otl_lookup_validate( OTL_Bytes          table,
+                       OTL_UInt           type_count,
+                       OTL_ValidateFunc*  type_funcs,
+                       OTL_Validator      valid );
 
   /* return number of sub-tables in a lookup */
-  OTL_LOCALDEF( OTL_UInt )
+  OTL_LOCAL( OTL_UInt )
   otl_lookup_get_count( OTL_Bytes  table );
 
-
+#if 0
   /* return lookup sub-table */
-  OTL_LOCALDEF( OTL_Bytes )
+  OTL_LOCAL( OTL_Bytes )
   otl_lookup_get_table( OTL_Bytes  table,
                         OTL_UInt   idx );
+#endif
 
 
   /*************************************************************************/
@@ -126,31 +136,37 @@
   /*************************************************************************/
   /*************************************************************************/
 
-#if 0
   /* validate lookup list */
-  OTL_LOCALDEF( void )
-  otl_lookup_list_validate( OTL_Bytes      table,
-                            OTL_Validator  valid );
-#endif
+  OTL_LOCAL( void )
+  otl_lookup_list_validate( OTL_Bytes          list,
+                            OTL_UInt           type_count,
+                            OTL_ValidateFunc*  type_funcs,
+                            OTL_Validator      valid );
 
+#if 0
   /* return number of lookups in list */
-  OTL_LOCALDEF( OTL_UInt )
+  OTL_LOCAL( OTL_UInt )
   otl_lookup_list_get_count( OTL_Bytes  table );
+#endif
 
+#if 0
   /* return a given lookup from a list */
-  OTL_LOCALDEF( OTL_Bytes )
+  OTL_LOCAL( OTL_Bytes )
   otl_lookup_list_get_lookup( OTL_Bytes  table,
                               OTL_UInt   idx );
+#endif
 
+#if 0
   /* return lookup sub-table from a list */
-  OTL_LOCALDEF( OTL_Bytes )
+  OTL_LOCAL( OTL_Bytes )
   otl_lookup_list_get_table( OTL_Bytes  table,
                              OTL_UInt   lookup_index,
                              OTL_UInt   table_index );
+#endif
 
 #if 0
   /* iterate over lookup list */
-  OTL_LOCALDEF( void )
+  OTL_LOCAL( void )
   otl_lookup_list_foreach( OTL_Bytes        table,
                            OTL_ForeachFunc  func,
                            OTL_Pointer      func_data );
@@ -166,21 +182,24 @@
   /*************************************************************************/
 
   /* validate feature table */
-  OTL_LOCALDEF( void )
+  OTL_LOCAL( void )
   otl_feature_validate( OTL_Bytes      table,
+                        OTL_UInt       lookup_count,
                         OTL_Validator  valid );
 
   /* return feature's lookup count */
-  OTL_LOCALDEF( OTL_UInt )
+  OTL_LOCAL( OTL_UInt )
   otl_feature_get_count( OTL_Bytes  table );
 
+#if 0
   /* get several lookups indices from a feature. returns the number of */
   /* lookups grabbed                                                   */
-  OTL_LOCALDEF( OTL_UInt )
+  OTL_LOCAL( OTL_UInt )
   otl_feature_get_lookups( OTL_Bytes  table,
                            OTL_UInt   start,
                            OTL_UInt   count,
                            OTL_UInt  *lookups );
+#endif
 
 
   /*************************************************************************/
@@ -191,24 +210,29 @@
   /*************************************************************************/
   /*************************************************************************/
 
-  /* validate a feature list */
-  OTL_LOCALDEF( void )
+  /* validate a feature list           */
+  /* lookups must already be validated */
+  OTL_LOCAL( void )
   otl_feature_list_validate( OTL_Bytes      table,
+                             OTL_Bytes      lookups,
                              OTL_Validator  valid );
 
+#if 0
   /* return number of features in list */
-  OTL_LOCALDEF( OTL_UInt )
+  OTL_LOCAL( OTL_UInt )
   otl_feature_list_get_count( OTL_Bytes  table );
+#endif
 
-
+#if 0
   /* return a given feature from a list */
-  OTL_LOCALDEF( OTL_Bytes )
+  OTL_LOCAL( OTL_Bytes )
   otl_feature_list_get_feature( OTL_Bytes  table,
                                 OTL_UInt   idx );
+#endif
 
 #if 0
   /* iterate over all features in a list */
-  OTL_LOCALDEF( void )
+  OTL_LOCAL( void )
   otl_feature_list_foreach( OTL_Bytes        table,
                             OTL_ForeachFunc  func,
                             OTL_Pointer      func_data );
@@ -225,22 +249,26 @@
 
   OTL_LOCAL( void )
   otl_lang_validate( OTL_Bytes      table,
+                     OTL_UInt       feature_count,
                      OTL_Validator  valid );
 
-
+#if 0
   OTL_LOCAL( OTL_UInt )
   otl_lang_get_req_feature( OTL_Bytes  table );
+#endif
 
-
+#if 0
   OTL_LOCAL( OTL_UInt )
   otl_lang_get_count( OTL_Bytes  table );
+#endif
 
-
+#if 0
   OTL_LOCAL( OTL_UInt )
   otl_lang_get_features( OTL_Bytes  table,
                          OTL_UInt   start,
                          OTL_UInt   count,
                          OTL_UInt  *features );
+#endif
 
 
   /*************************************************************************/
@@ -252,26 +280,17 @@
   /*************************************************************************/
 
   OTL_LOCAL( void )
-  otl_script_list_validate( OTL_Bytes          list,
-                            OTL_Validator      valid );
+  otl_script_validate( OTL_Bytes      table,
+                       OTL_UInt       feature_count,
+                       OTL_Validator  valid );
 
-  OTL_LOCAL( OTL_Bytes )
-  otl_script_list_get_script( OTL_Bytes  table );
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*****                                                               *****/
-  /*****                         LOOKUP LISTS                          *****/
-  /*****                                                               *****/
-  /*************************************************************************/
-  /*************************************************************************/
-
+  /* validate a script list             */
+  /* features must already be validated */
   OTL_LOCAL( void )
-  otl_lookup_list_validate( OTL_Bytes          list,
-                            OTL_UInt           type_count,
-                            OTL_ValidateFunc*  type_funcs,
+  otl_script_list_validate( OTL_Bytes          list,
+                            OTL_Bytes          features,
                             OTL_Validator      valid );
+
 
  /* */
 
--- a/src/otlayout/otlgpos.c
+++ b/src/otlayout/otlgpos.c
@@ -975,9 +975,8 @@
     features = OTL_NEXT_USHORT( p );
     lookups  = OTL_NEXT_USHORT( p );
 
-    otl_script_list_validate ( table + scripts, valid );
-    otl_feature_list_validate( table + features, valid );
-
     otl_lookup_list_validate( table + lookups, 9, otl_gpos_validate_funcs,
                               valid );
+    otl_feature_list_validate( table + features, table + lookups, valid );
+    otl_script_list_validate( table + scripts, table + features, valid );
   }
--- a/src/otlayout/otlgsub.c
+++ b/src/otlayout/otlgsub.c
@@ -89,7 +89,7 @@
     OTL_Bytes  p = table;
     OTL_Bytes  coverage;
     OTL_UInt   format, gindex, property;
-    OTL_Int    index;
+    OTL_Long   index;
     OTL_Bool   subst = 0;
 
     if ( parser->context_len != 0xFFFFU && parser->context_len < 1 )
@@ -109,37 +109,41 @@
     {
       switch ( format )
       {
-        case 1:
-          {
-            OTL_Int  delta = OTL_NEXT_SHORT(p);
+      case 1:
+        {
+          OTL_Int  delta = OTL_NEXT_SHORT( p );
 
-            gindex = ( gindex + delta ) & 0xFFFFU;
-            otl_parser_replace_1( parser, gindex );
-            subst = 1;
-          }
-          break;
 
-        case 2:
-          {
-            OTL_UInt  count = OTL_NEXT_USHORT(p);
+          gindex = ( gindex + delta ) & 0xFFFFU;
+          otl_parser_replace_1( parser, gindex );
+          subst = 1;
+        }
+        break;
 
-            if ( (OTL_UInt) index < count )
-            {
-              p += index*2;
-              otl_parser_replace_1( parser, OTL_PEEK_USHORT(p) );
-              subst = 1;
-            }
+      case 2:
+        {
+          OTL_UInt  count = OTL_NEXT_USHORT( p );
+
+
+          if ( (OTL_UInt)index < count )
+          {
+            p += index * 2;
+            otl_parser_replace_1( parser, OTL_PEEK_USHORT( p ) );
+            subst = 1;
           }
-          break;
+        }
+        break;
 
-        default:
-          ;
+      default:
+        ;
       }
     }
+
   Exit:
     return subst;
   }
 
+
  /************************************************************************/
  /************************************************************************/
  /*****                                                              *****/
@@ -225,7 +229,8 @@
   {
     OTL_Bytes  p = table;
     OTL_Bytes  coverage, sequence;
-    OTL_UInt   format, gindex, index, property, context_len, seq_count, count;
+    OTL_UInt   format, gindex, property, context_len, seq_count, count;
+    OTL_Long   index;
     OTL_Bool   subst = 0;
 
     if ( parser->context_len != 0xFFFFU && parser->context_len < 1 )
@@ -237,18 +242,18 @@
     if ( parser->error )
       goto Exit;
 
-    p        += 2;  /* skip format */
-    coverage  = table + OTL_NEXT_USHORT(p);
-    seq_count = OTL_NEXT_USHORT(p);
+    p        += 2;                              /* skip format */
+    coverage  = table + OTL_NEXT_USHORT( p );
+    seq_count = OTL_NEXT_USHORT( p );
     index     = otl_coverage_get_index( coverage, gindex );
 
-    if ( (OTL_UInt) index >= seq_count )
+    if ( (OTL_UInt)index >= seq_count || index < 0 )
       goto Exit;
 
-    p       += index*2;
-    sequence = table + OTL_PEEK_USHORT(p);
+    p       += index * 2;
+    sequence = table + OTL_PEEK_USHORT( p );
     p        = sequence;
-    count    = OTL_NEXT_USHORT(p);
+    count    = OTL_NEXT_USHORT( p );
 
     otl_parser_replace_n( parser, count, p );
     subst = 1;
@@ -257,6 +262,7 @@
     return subst;
   }
 
+
  /************************************************************************/
  /************************************************************************/
  /*****                                                              *****/
@@ -341,7 +347,8 @@
   {
     OTL_Bytes  p = table;
     OTL_Bytes  coverage, alternates;
-    OTL_UInt   format, gindex, index, property, seq_count, count;
+    OTL_UInt   format, gindex, property, seq_count, count;
+    OTL_Long   index;
     OTL_Bool   subst = 0;
 
     OTL_GSUB_Alternate  alternate = parser->alternate;
@@ -358,18 +365,18 @@
     if ( parser->error )
       goto Exit;
 
-    p        += 2;  /* skip format */
-    coverage  = table + OTL_NEXT_USHORT(p);
-    seq_count = OTL_NEXT_USHORT(p);
+    p        += 2;                              /* skip format */
+    coverage  = table + OTL_NEXT_USHORT( p );
+    seq_count = OTL_NEXT_USHORT( p );
     index     = otl_coverage_get_index( coverage, gindex );
 
-    if ( (OTL_UInt) index >= seq_count )
+    if ( (OTL_UInt)index >= seq_count || index < 0 )
       goto Exit;
 
-    p         += index*2;
-    alternates = table + OTL_PEEK_USHORT(p);
+    p         += index * 2;
+    alternates = table + OTL_PEEK_USHORT( p );
     p          = alternates;
-    count      = OTL_NEXT_USHORT(p);
+    count      = OTL_NEXT_USHORT( p );
 
     gindex = alternate->handler_func(
                  gindex, count, p, alternate->handler_data );
@@ -870,9 +877,8 @@
     features = OTL_NEXT_USHORT( p );
     lookups  = OTL_NEXT_USHORT( p );
 
-    otl_script_list_validate ( table + scripts, valid );
-    otl_feature_list_validate( table + features, valid );
-
     otl_lookup_list_validate( table + lookups, 7, otl_gsub_validate_funcs,
                               valid );
+    otl_feature_list_validate( table + features, table + lookups, valid );
+    otl_script_list_validate( table + scripts, table + features, valid );
   }
--- a/src/otlayout/otlparse.c
+++ b/src/otlayout/otlparse.c
@@ -25,6 +25,7 @@
     }
   }
 
+
 #define  OTL_STRING_ENSURE(str,count,parser)                   \
            OTL_BEGIN_STMNT                                     \
              if ( (str)->length + (count) > (str)->capacity )  \
@@ -52,11 +53,16 @@
     otl_longjmp( parser->jump_buffer, 1 );
   }
 
-  OTL_LOCAL( void )
+
+  OTL_LOCALDEF( void )
   otl_parser_check_property( OTL_Parser  parser,
                              OTL_UInt    gindex,
-                             OTL_UInt   *aproperty );
+                             OTL_UInt   *aproperty )
+  {
+    /* XXX: to do */
+  }
 
+
   OTL_LOCALDEF( void )
   otl_parser_replace_1( OTL_Parser  parser,
                         OTL_UInt    gindex )
@@ -89,6 +95,7 @@
     out->cursor  = out->length;
     in->cursor  += 1;
   }
+
 
   OTL_LOCALDEF( void )
   otl_parser_replace_n( OTL_Parser  parser,