shithub: freetype+ttf2subf

Download patch

ref: 80ed03e2bbb1c890869f5c8e53571cd091518e96
parent: 1ac8f43463397386887414c99c40fd4421d655c8
author: Werner Lemberg <[email protected]>
date: Fri Aug 13 02:09:08 EDT 2004

* src/otlayout/otlcommn.c (otl_gsubgpos_get_lookup_count): New
function.
* src/otlayout/otlcommn.h: Updated.

* src/otlayout/otlbase.c: Rename counting variables to be more
meaningful.
Add copyright message.
* src/otlayout/otlbase.h: Add copyright message.

* src/otlayout/otlgdef.c: Rename counting variables to be more
meaningful.
Add copyright message.
Use OTL_CHECK everywhere.
(otl_caret_value_validate): Remove unused variable.
(otl_gdef_validate): All tables are optional.
* src/otlayout/otlgdef.h: Add copyright message.

* src/otlayout/otljstf.c: Rename counting variables to be more
meaningful.
Add copyright message.
(otl_jstf_gsub_mods_validate, otl_jstf_gpos_mods_validate): Add
parameter to pass lookup count.
Update all callers.
Check lookup array.
(otl_jstf_max_validate):
s/otl_gpos_subtable_check/otl_gpos_subtable_validate/.
(otl_jstf_priority_validate, otl_jstf_lang_validate,
otl_jstf_script_validate): Add two parameters to pass lookup counts.
Update all callers.
(otl_jstf_validate): Add two parameters to pass GPOS and GSUB
table offsets; use otl_gsubgpos_get_lookup_count to convert extract
lookup counts.
Fix typo.
* src/otlayout/otljstf.h: Updated.
Add copyright message.

* src/otlayout/otlgpos.c (otl_gpos_subtable_validate): New function.
(otl_gpos_validate): Use it.
* src/otlayout/otlgpos.h: Updated.

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,47 @@
 2004-08-13  Werner Lemberg  <[email protected]>
 
+	* src/otlayout/otlcommn.c (otl_gsubgpos_get_lookup_count): New
+	function.
+	* src/otlayout/otlcommn.h: Updated.
+
+	* src/otlayout/otlbase.c: Rename counting variables to be more
+	meaningful.
+	Add copyright message.
+	* src/otlayout/otlbase.h: Add copyright message.
+
+	* src/otlayout/otlgdef.c: Rename counting variables to be more
+	meaningful.
+	Add copyright message.
+	Use OTL_CHECK everywhere.
+	(otl_caret_value_validate): Remove unused variable.
+	(otl_gdef_validate): All tables are optional.
+	* src/otlayout/otlgdef.h: Add copyright message.
+
+	* src/otlayout/otljstf.c: Rename counting variables to be more
+	meaningful.
+	Add copyright message.
+	(otl_jstf_gsub_mods_validate, otl_jstf_gpos_mods_validate): Add
+	parameter to pass lookup count.
+	Update all callers.
+	Check lookup array.
+	(otl_jstf_max_validate):
+	s/otl_gpos_subtable_check/otl_gpos_subtable_validate/.
+	(otl_jstf_priority_validate, otl_jstf_lang_validate,
+	otl_jstf_script_validate): Add two parameters to pass lookup counts.
+	Update all callers.
+	(otl_jstf_validate): Add two parameters to pass GPOS and GSUB
+	table offsets; use otl_gsubgpos_get_lookup_count to convert extract
+	lookup counts.
+	Fix typo.
+	* src/otlayout/otljstf.h: Updated.
+	Add copyright message.
+
+	* src/otlayout/otlgpos.c (otl_gpos_subtable_validate): New function.
+	(otl_gpos_validate): Use it.
+	* src/otlayout/otlgpos.h: Updated.
+
+2004-08-13  Werner Lemberg  <[email protected]>
+
 	* src/otlayout/otcommn.c: Use OTL_CHECK everywhere.
 	(otl_coverage_validate): Initialize `p',
 	s/count/num_glyphs/.
--- a/src/otlayout/otlbase.c
+++ b/src/otlayout/otlbase.c
@@ -1,6 +1,25 @@
+/***************************************************************************/
+/*                                                                         */
+/*  otlbase.c                                                              */
+/*                                                                         */
+/*    OpenType layout support, BASE table (body).                          */
+/*                                                                         */
+/*  Copyright 2002, 2004 by                                                */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
 #include "otlbase.h"
 #include "otlcommn.h"
 
+
   static void
   otl_base_coord_validate( OTL_Bytes      table,
                            OTL_Validator  valid )
@@ -8,27 +27,30 @@
     OTL_Bytes  p = table;
     OTL_UInt   format;
 
+
     OTL_CHECK( 4 );
 
     format = OTL_NEXT_USHORT( p );
-    p += 2;
 
+    p += 2;     /* skip coordinate */
+
     switch ( format )
     {
-      case 1:
-        break;
+    case 1:
+      break;
 
-      case 2:
-        OTL_CHECK( 4 );
-        break;
+    case 2:
+      OTL_CHECK( 4 );
+      break;
 
-      case 3:
-        OTL_CHECK( 2 );
-        otl_device_table_validate( table + OTL_PEEK_USHORT( p ), valid );
-        break;
+    case 3:
+      OTL_CHECK( 2 );
 
-      default:
-        OTL_INVALID_DATA;
+      otl_device_table_validate( table + OTL_PEEK_USHORT( p ), valid );
+      break;
+
+    default:
+      OTL_INVALID_DATA;
     }
   }
 
@@ -40,29 +62,31 @@
     OTL_Bytes  p = table;
     OTL_UInt   count;
 
-    OTL_CHECK(2);
 
+    OTL_CHECK( 2 );
+
     count = OTL_NEXT_USHORT( p );
-    OTL_CHECK( count*4 );
+    OTL_CHECK( count * 4 );
   }
 
 
-
   static void
   otl_base_values_validate( OTL_Bytes      table,
                             OTL_Validator  valid )
   {
     OTL_Bytes  p = table;
-    OTL_UInt   count;
+    OTL_UInt   num_coord;
 
+
     OTL_CHECK( 4 );
 
-    p    += 2;  /* skip default index */
-    count = OTL_NEXT_USHORT( p );
+    p        += 2;              /* skip default index */
+    num_coord = OTL_NEXT_USHORT( p );
 
-    OTL_CHECK( count*2 );
+    OTL_CHECK( num_coord * 2 );
 
-    for ( ; count > 0; count-- )
+    /* scan base coordinate records */
+    for ( ; num_coord > 0; num_coord-- )
       otl_base_coord_validate( table + OTL_NEXT_USHORT( p ), valid );
   }
 
@@ -72,13 +96,15 @@
                             OTL_Validator  valid )
   {
     OTL_Bytes  p = table;
-    OTL_UInt   min_coord, max_coord, count;
+    OTL_UInt   min_coord, max_coord, num_minmax;
 
-    OTL_CHECK(6);
-    min_coord = OTL_NEXT_USHORT( p );
-    max_coord = OTL_NEXT_USHORT( p );
-    count     = OTL_NEXT_USHORT( p );
 
+    OTL_CHECK( 6 );
+
+    min_coord  = OTL_NEXT_USHORT( p );
+    max_coord  = OTL_NEXT_USHORT( p );
+    num_minmax = OTL_NEXT_USHORT( p );
+
     if ( min_coord )
       otl_base_coord_validate( table + min_coord, valid );
 
@@ -85,10 +111,13 @@
     if ( max_coord )
       otl_base_coord_validate( table + max_coord, valid );
 
-    OTL_CHECK( count*8 );
-    for ( ; count > 0; count-- )
+    OTL_CHECK( num_minmax * 8 );
+
+    /* scan feature minmax records */
+    for ( ; num_minmax > 0; num_minmax-- )
     {
-      p += 4;  /* ignore tag */
+      p += 4;       /* skip tag */
+
       min_coord = OTL_NEXT_USHORT( p );
       max_coord = OTL_NEXT_USHORT( p );
 
@@ -106,13 +135,14 @@
                             OTL_Validator  valid )
   {
     OTL_Bytes  p = table;
-    OTL_UInt   values, default_minmax, count;
+    OTL_UInt   values, default_minmax, num_langsys;
 
-    OTL_CHECK(6);
 
+    OTL_CHECK( 6 );
+
     values         = OTL_NEXT_USHORT( p );
     default_minmax = OTL_NEXT_USHORT( p );
-    count          = OTL_NEXT_USHORT( p );
+    num_langsys    = OTL_NEXT_USHORT( p );
 
     if ( values )
       otl_base_values_validate( table + values, valid );
@@ -120,10 +150,13 @@
     if ( default_minmax )
       otl_base_minmax_validate( table + default_minmax, valid );
 
-    OTL_CHECK( count*6 );
-    for ( ; count > 0; count-- )
+    OTL_CHECK( num_langsys * 6 );
+
+    /* scan base langsys records */
+    for ( ; num_langsys > 0; num_langsys-- )
     {
-      p += 4;  /* ignore tag */
+      p += 4;       /* skip tag */
+
       otl_base_minmax_validate( table + OTL_NEXT_USHORT( p ), valid );
     }
   }
@@ -134,20 +167,24 @@
                                  OTL_Validator  valid )
   {
     OTL_Bytes  p = table;
-    OTL_UInt   count;
+    OTL_UInt   num_scripts;
 
-    OTL_CHECK(2);
 
-    count = OTL_NEXT_USHORT( p );
-    OTL_CHECK(count*6);
+    OTL_CHECK( 2 );
 
-    for ( ; count > 0; count-- )
+    num_scripts = OTL_NEXT_USHORT( p );
+    OTL_CHECK( num_scripts * 6 );
+
+    /* scan base script records */
+    for ( ; num_scripts > 0; num_scripts-- )
     {
-      p += 4;  /* ignore script tag */
+      p += 4;       /* skip tag */
+
       otl_base_script_validate( table + OTL_NEXT_USHORT( p ), valid );
     }
   }
 
+
   static void
   otl_axis_table_validate( OTL_Bytes      table,
                            OTL_Validator  valid )
@@ -155,8 +192,9 @@
     OTL_Bytes  p = table;
     OTL_UInt   tags;
 
-    OTL_CHECK(4);
 
+    OTL_CHECK( 4 );
+
     tags = OTL_NEXT_USHORT( p );
     if ( tags )
       otl_base_tag_list_validate( table + tags, valid );
@@ -171,8 +209,9 @@
   {
     OTL_Bytes p = table;
 
-    OTL_CHECK(6);
 
+    OTL_CHECK( 6 );
+
     if ( OTL_NEXT_ULONG( p ) != 0x10000UL )
       OTL_INVALID_DATA;
 
@@ -179,3 +218,6 @@
     otl_axis_table_validate( table + OTL_NEXT_USHORT( p ), valid );
     otl_axis_table_validate( table + OTL_NEXT_USHORT( p ), valid );
   }
+
+
+/* END */
--- a/src/otlayout/otlbase.h
+++ b/src/otlayout/otlbase.h
@@ -1,14 +1,37 @@
-#ifndef __OTL_BASE_H__
-#define __OTL_BASE_H__
+/***************************************************************************/
+/*                                                                         */
+/*  otlbase.h                                                              */
+/*                                                                         */
+/*    OpenType layout support, BASE table (specification).                 */
+/*                                                                         */
+/*  Copyright 2002, 2004 by                                                */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
 
+
+#ifndef __OTLBASE_H__
+#define __OTLBASE_H__
+
 #include "otlayout.h"
 
 OTL_BEGIN_HEADER
 
+
   OTL_LOCAL( void )
   otl_base_validate( OTL_Bytes      table,
                      OTL_Validator  valid );
 
+
 OTL_END_HEADER
 
-#endif /* __OTL_BASE_H__ */
+#endif /* __OTLBASE_H__ */
+
+
+/* END */
--- a/src/otlayout/otlcommn.c
+++ b/src/otlayout/otlcommn.c
@@ -19,13 +19,13 @@
 #include "otlayout.h"
 
 
- /*************************************************************************/
- /*************************************************************************/
- /*****                                                               *****/
- /*****                       COVERAGE TABLE                          *****/
- /*****                                                               *****/
- /*************************************************************************/
- /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                       COVERAGE TABLE                          *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
 
   OTL_LOCALDEF( void )
   otl_coverage_validate( OTL_Bytes      table,
@@ -871,12 +871,12 @@
 
 
   OTL_LOCALDEF( void )
-  otl_script_list_validate( OTL_Bytes      list,
+  otl_script_list_validate( OTL_Bytes      table,
                             OTL_Bytes      features,
                             OTL_Validator  valid )
   {
     OTL_UInt   num_scripts, feature_count;
-    OTL_Bytes  p = list;
+    OTL_Bytes  p = table;
 
 
     OTL_CHECK( 2 );
@@ -890,9 +890,27 @@
     {
       p += 4;       /* skip tag */
 
-      otl_script_validate( list + OTL_NEXT_USHORT( p ), feature_count,
+      otl_script_validate( table + OTL_NEXT_USHORT( p ), feature_count,
                            valid );
     }
+  }
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                      UTILITY FUNCTIONS                        *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  OTL_LOCALDEF( OTL_UInt )
+  otl_gsubgpos_get_lookup_count( OTL_Bytes  table )
+  {
+    OTL_Bytes  p = table + 8;
+
+
+    return otl_lookup_get_count( table + OTL_PEEK_USHORT( p ) );
   }
 
 
--- a/src/otlayout/otlcommn.h
+++ b/src/otlayout/otlcommn.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    OpenType layout support, common tables (specification).              */
 /*                                                                         */
-/*  Copyright 2002 by                                                      */
+/*  Copyright 2002, 2004 by                                                */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -34,17 +34,17 @@
 
   /* validate coverage table */
   OTL_LOCAL( void )
-  otl_coverage_validate( OTL_Bytes      base,
+  otl_coverage_validate( OTL_Bytes      table,
                          OTL_Validator  valid );
 
   /* return number of covered glyphs */
   OTL_LOCAL( OTL_UInt )
-  otl_coverage_get_count( OTL_Bytes  base );
+  otl_coverage_get_count( OTL_Bytes  table );
 
   /* Return the coverage index corresponding to a glyph glyph index. */
   /* Return -1 if the glyph isn't covered.                           */
   OTL_LOCAL( OTL_Long )
-  otl_coverage_get_index( OTL_Bytes  base,
+  otl_coverage_get_index( OTL_Bytes  table,
                           OTL_UInt   glyph_index );
 
 
@@ -138,7 +138,7 @@
 
   /* validate lookup list */
   OTL_LOCAL( void )
-  otl_lookup_list_validate( OTL_Bytes          list,
+  otl_lookup_list_validate( OTL_Bytes          table,
                             OTL_UInt           type_count,
                             OTL_ValidateFunc*  type_funcs,
                             OTL_Validator      valid );
@@ -287,10 +287,21 @@
   /* validate a script list             */
   /* features must already be validated */
   OTL_LOCAL( void )
-  otl_script_list_validate( OTL_Bytes          list,
-                            OTL_Bytes          features,
-                            OTL_Validator      valid );
+  otl_script_list_validate( OTL_Bytes      table,
+                            OTL_Bytes      features,
+                            OTL_Validator  valid );
 
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                      UTILITY FUNCTIONS                        *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  OTL_LOCAL( OTL_UInt )
+  otl_gsubgpos_get_lookup_count( OTL_Bytes  table );
 
  /* */
 
--- a/src/otlayout/otlgdef.c
+++ b/src/otlayout/otlgdef.c
@@ -1,14 +1,33 @@
+/***************************************************************************/
+/*                                                                         */
+/*  otlgdef.c                                                              */
+/*                                                                         */
+/*    OpenType layout support, GDEF table (body).                          */
+/*                                                                         */
+/*  Copyright 2002, 2004 by                                                */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
 #include "otlgdef.h"
 #include "otlcommn.h"
 
- /************************************************************************/
- /************************************************************************/
- /*****                                                              *****/
- /*****                      ATTACHMENTS LIST                        *****/
- /*****                                                              *****/
- /************************************************************************/
- /************************************************************************/
 
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                       ATTACHMENTS LIST                        *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
   static void
   otl_attach_point_validate( OTL_Bytes      table,
                              OTL_Validator  valid )
@@ -16,12 +35,11 @@
     OTL_Bytes  p = table;
     OTL_UInt   count;
 
-    if ( p + 2 > valid->limit )
-      OTL_INVALID_TOO_SHORT;
 
+    OTL_CHECK( 2 );
+
     count = OTL_NEXT_USHORT( p );
-    if ( table + count*2 > valid->limit )
-      OTL_INVALID_TOO_SHORT;
+    OTL_CHECK( count * 2 );
   }
 
 
@@ -31,33 +49,33 @@
   {
     OTL_Bytes  p = table;
     OTL_Bytes  coverage;
-    OTL_UInt   count;
+    OTL_UInt   num_glyphs;
 
-    if ( p + 4 > valid->limit )
-      OTL_INVALID_TOO_SHORT;
 
-    coverage = table + OTL_NEXT_USHORT( p );
-    count    = OTL_NEXT_USHORT( p );
+    OTL_CHECK( 4 );
 
+    coverage   = table + OTL_NEXT_USHORT( p );
+    num_glyphs = OTL_NEXT_USHORT( p );
+
     otl_coverage_validate( coverage, valid );
-    if ( count != otl_coverage_get_count( coverage ) )
+    if ( num_glyphs != otl_coverage_get_count( coverage ) )
       OTL_INVALID_DATA;
 
-    if ( p + count*2 > valid->limit )
-      OTL_INVALID_TOO_SHORT;
+    OTL_CHECK( num_glyphs * 2 );
 
-    for ( ; count > 0; count-- )
+    /* scan attach point records */
+    for ( ; num_glyphs > 0; num_glyphs-- )
       otl_attach_point_validate( table + OTL_NEXT_USHORT( p ), valid );
   }
 
 
- /************************************************************************/
- /************************************************************************/
- /*****                                                              *****/
- /*****                      LIGATURE CARETS                         *****/
- /*****                                                              *****/
- /************************************************************************/
- /************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                       LIGATURE CARETS                         *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
 
   static void
   otl_caret_value_validate( OTL_Bytes      table,
@@ -64,32 +82,32 @@
                             OTL_Validator  valid )
   {
     OTL_Bytes  p = table;
-    OTL_Int   format;
+    OTL_Int    format;
 
-    if ( p + 4 > valid->limit )
-      OTL_INVALID_TOO_SHORT;
 
+    OTL_CHECK( 4 );
+
     format = OTL_NEXT_USHORT( p );
     switch ( format )
     {
-      case 1:
-      case 2:
-        break;
+    case 1:
+      /* skip coordinate, no test */
+      break;
 
-      case 3:
-        {
-          OTL_Bytes  device;
+    case 2:
+      /* skip contour point index, no test */
+      break;
 
-          p += 2;
-          if ( p + 2 > valid->limit )
-            OTL_INVALID_TOO_SHORT;
+    case 3:
+      p += 2;           /* skip coordinate */
 
-          otl_device_table_validate( table + OTL_PEEK_USHORT( p ), valid );
-        }
-        break;
+      OTL_CHECK( 2 );
 
-      default:
-        OTL_INVALID_DATA;
+      otl_device_table_validate( table + OTL_PEEK_USHORT( p ), valid );
+      break;
+
+    default:
+      OTL_INVALID_DATA;
     }
   }
 
@@ -99,17 +117,15 @@
                                OTL_Validator  valid )
   {
     OTL_Bytes  p = table;
-    OTL_UInt   count;
+    OTL_UInt   num_carets;
 
-    if ( p + 2 > valid->limit )
-      OTL_INVALID_TOO_SHORT;
 
-    count = OTL_NEXT_USHORT( p );
+    OTL_CHECK( 2 );
+    num_carets = OTL_NEXT_USHORT( p );
+    OTL_CHECK( num_carets * 2 );
 
-    if ( p + count*2 > valid->limit )
-      OTL_INVALID_TOO_SHORT;
-
-    for ( ; count > 0; count-- )
+    /* scan caret value records */
+    for ( ; num_carets > 0; num_carets-- )
       otl_caret_value_validate( table + OTL_NEXT_USHORT( p ), valid );
   }
 
@@ -120,33 +136,33 @@
   {
     OTL_Bytes  p = table;
     OTL_Bytes  coverage;
-    OTL_UInt   count;
+    OTL_UInt   num_ligglyphs;
 
-    if ( p + 4 > valid->limit )
-      OTL_INVALID_TOO_SHORT;
 
-    coverage = table + OTL_NEXT_USHORT( p );
-    count    = OTL_NEXT_USHORT( p );
+    OTL_CHECK( 4 );
 
+    coverage      = table + OTL_NEXT_USHORT( p );
+    num_ligglyphs = OTL_NEXT_USHORT( p );
+
     otl_coverage_validate( coverage, valid );
-    if ( count != otl_coverage_get_count( coverage ) )
+    if ( num_ligglyphs != otl_coverage_get_count( coverage ) )
       OTL_INVALID_DATA;
 
-    if ( p + count*2 > valid->limit )
-      OTL_INVALID_TOO_SHORT;
+    OTL_CHECK( num_ligglyphs * 2 );
 
-    for ( ; count > 0; count-- )
+    /* scan ligature glyph records */
+    for ( ; num_ligglyphs > 0; num_ligglyphs-- )
       otl_ligature_glyph_validate( table + OTL_NEXT_USHORT( p ), valid );
   }
 
 
- /************************************************************************/
- /************************************************************************/
- /*****                                                              *****/
- /*****                         GDEF TABLE                           *****/
- /*****                                                              *****/
- /************************************************************************/
- /************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                         GDEF TABLE                            *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
 
   OTL_APIDEF( void )
   otl_gdef_validate( OTL_Bytes      table,
@@ -153,23 +169,35 @@
                      OTL_Validator  valid )
   {
     OTL_Bytes  p = table;
+    OTL_UInt   val;
 
-    if ( p + 12 > valid->limit )
-      OTL_INVALID_TOO_SHORT;
 
+    OTL_CHECK( 12 );
+
     /* check format */
     if ( OTL_NEXT_ULONG( p ) != 0x00010000UL )
       OTL_INVALID_FORMAT;
 
-    /* validate class definition table */
-    otl_class_definition_validate( table + OTL_NEXT_USHORT( p ), valid );
+    /* validate glyph class definition table */
+    val = OTL_NEXT_USHORT( p );
+    if ( val )
+      otl_class_definition_validate( table + val, valid );
 
     /* validate attachment point list */
-    otl_attach_list_validate( table + OTL_NEXT_USHORT( p ), valid );
+    val = OTL_NEXT_USHORT( p );
+    if ( val )
+      otl_attach_list_validate( table + val, valid );
 
     /* validate ligature caret list */
-    otl_ligature_caret_list_validate( table + OTL_NEXT_USHORT( p ), valid );
+    val = OTL_NEXT_USHORT( p );
+    if ( val )
+      otl_ligature_caret_list_validate( table + val, valid );
 
-    /* validate mark attach class */
-    otl_class_definition_validate( table + OTL_NEXT_USHORT( p ), valid );
+    /* validate mark attachment class definition table */
+    val = OTL_NEXT_USHORT( p );
+    if ( val )
+      otl_class_definition_validate( table + val, valid );
   }
+
+
+/* END */
--- a/src/otlayout/otlgdef.h
+++ b/src/otlayout/otlgdef.h
@@ -1,14 +1,37 @@
-#ifndef __OTL_GDEF_H__
-#define __OTL_GDEF_H__
+/***************************************************************************/
+/*                                                                         */
+/*  otlgdef.h                                                              */
+/*                                                                         */
+/*    OpenType layout support, GDEF table (specification).                 */
+/*                                                                         */
+/*  Copyright 2002, 2004 by                                                */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
 
+
+#ifndef __OTLGDEF_H__
+#define __OTLGDEF_H__
+
 #include "otltable.h"
 
 OTL_BEGIN_HEADER
 
+
   OTL_API( void )
   otl_gdef_validate( OTL_Bytes      table,
                      OTL_Validator  valid );
 
+
 OTL_END_HEADER
 
-#endif /* __OTL_GDEF_H__ */
+#endif /* __OTLGDEF_H__ */
+
+
+/* END */
--- a/src/otlayout/otlgpos.c
+++ b/src/otlayout/otlgpos.c
@@ -936,7 +936,7 @@
     }
   }
 
-  static OTL_ValidateFunc  otl_gpos_validate_funcs[ 9 ] =
+  static OTL_ValidateFunc  otl_gpos_validate_funcs[9] =
   {
     otl_gpos_lookup1_validate,
     otl_gpos_lookup2_validate,
@@ -950,15 +950,23 @@
   };
 
 
- /************************************************************************/
- /************************************************************************/
- /*****                                                              *****/
- /*****                         GPOS TABLE                           *****/
- /*****                                                              *****/
- /************************************************************************/
- /************************************************************************/
+  OTL_LOCALDEF( void )
+  otl_gpos_subtable_validate( OTL_Bytes      table,
+                              OTL_Validator  valid )
+  {
+    otl_lookup_list_validate( table, 9, otl_gpos_validate_funcs, valid );
+  }
 
 
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                          GPOS TABLE                           *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
   OTL_LOCALDEF( void )
   otl_gpos_validate( OTL_Bytes      table,
                      OTL_Validator  valid )
@@ -975,8 +983,7 @@
     features = OTL_NEXT_USHORT( p );
     lookups  = OTL_NEXT_USHORT( p );
 
-    otl_lookup_list_validate( table + lookups, 9, otl_gpos_validate_funcs,
-                              valid );
+    otl_gpos_subtable_validate( table + lookups, valid );
     otl_feature_list_validate( table + features, table + lookups, valid );
     otl_script_list_validate( table + scripts, table + features, valid );
   }
--- a/src/otlayout/otlgpos.h
+++ b/src/otlayout/otlgpos.h
@@ -1,5 +1,5 @@
-#ifndef __OTL_GPOS_H__
-#define __OTL_GPOS_H__
+#ifndef __OTLGPOS_H__
+#define __OTLGPOS_H__
 
 #include "otlayout.h"
 
@@ -6,9 +6,13 @@
 OTL_BEGIN_HEADER
 
   OTL_LOCAL( void )
+  otl_gpos_subtable_validate( OTL_Bytes      table,
+                              OTL_Validator  valid );
+
+  OTL_LOCAL( void )
   otl_gpos_validate( OTL_Bytes      table,
                      OTL_Validator  valid );
 
 OTL_END_HEADER
 
-#endif /* __OTL_GPOS_H__ */
+#endif /* __OTLGPOS_H__ */
--- a/src/otlayout/otlgsub.c
+++ b/src/otlayout/otlgsub.c
@@ -882,3 +882,6 @@
     otl_feature_list_validate( table + features, table + lookups, valid );
     otl_script_list_validate( table + scripts, table + features, valid );
   }
+
+
+/* END */
--- a/src/otlayout/otlgsub.h
+++ b/src/otlayout/otlgsub.h
@@ -1,5 +1,5 @@
-#ifndef __OTL_GSUB_H__
-#define __OTL_GSUB_H__
+#ifndef __OTLGSUB_H__
+#define __OTLGSUB_H__
 
 #include "otlayout.h"
 
@@ -10,7 +10,7 @@
                                                OTL_Bytes    alternates,
                                                OTL_Pointer  data );
 
-  typedef struct OTL_GSUB_AlternateRec_
+  typedef struct  OTL_GSUB_AlternateRec_
   {
     OTL_GSUB_AlternateFunc  handler_func;
     OTL_Pointer             handler_data;
@@ -17,10 +17,12 @@
 
   } OTL_GSUB_AlternateRec, *OTL_GSUB_Alternate;
 
+
   OTL_LOCAL( void )
   otl_gsub_validate( OTL_Bytes      table,
                      OTL_Validator  valid );
 
+
 OTL_END_HEADER
 
-#endif /* __OTL_GSUB_H__ */
+#endif /* __OTLGSUB_H__ */
--- a/src/otlayout/otljstf.c
+++ b/src/otlayout/otljstf.c
@@ -1,49 +1,79 @@
+/***************************************************************************/
+/*                                                                         */
+/*  otljstf.c                                                              */
+/*                                                                         */
+/*    OpenType layout support, JSTF table (body).                          */
+/*                                                                         */
+/*  Copyright 2002, 2004 by                                                */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
 #include "otljstf.h"
 #include "otlcommn.h"
 #include "otlgpos.h"
 
+
   static void
   otl_jstf_extender_validate( OTL_Bytes      table,
                               OTL_Validator  valid )
   {
     OTL_Bytes  p = table;
-    OTL_UInt   count;
+    OTL_UInt   num_glyphs;
 
+
     OTL_CHECK( 2 );
 
-    count = OTL_NEXT_USHORT( p );
+    num_glyphs = OTL_NEXT_USHORT( p );
 
-    OTL_CHECK( count*2 );
+    OTL_CHECK( num_glyphs * 2 );
+
+    /* XXX: check glyph indices */
   }
 
 
   static void
   otl_jstf_gsub_mods_validate( OTL_Bytes      table,
+                               OTL_UInt       lookup_count,
                                OTL_Validator  valid )
   {
     OTL_Bytes  p = table;
-    OTL_UInt   count;
+    OTL_UInt   num_lookups;
 
+
     OTL_CHECK( 2 );
-    count = OTL_NEXT_USHORT( p );
-    OTL_CHECK( count*2 );
+    num_lookups = OTL_NEXT_USHORT( p );
+    OTL_CHECK( num_lookups * 2 );
 
-    /* XXX: check GSUB lookup indices */
+    for ( ; num_lookups > 0; num_lookups-- )
+      if ( OTL_NEXT_USHORT( p ) >= lookup_count )
+        OTL_INVALID_DATA;
   }
 
 
   static void
   otl_jstf_gpos_mods_validate( OTL_Bytes      table,
+                               OTL_UInt       lookup_count,
                                OTL_Validator  valid )
   {
     OTL_Bytes  p = table;
-    OTL_UInt   count;
+    OTL_UInt   num_lookups;
 
+
     OTL_CHECK( 2 );
-    count = OTL_NEXT_USHORT( p );
-    OTL_CHECK( count*2 );
+    num_lookups = OTL_NEXT_USHORT( p );
+    OTL_CHECK( num_lookups * 2 );
 
-    /* XXX: check GPOS lookup indices */
+    for ( ; num_lookups > 0; num_lookups-- )
+      if ( OTL_NEXT_USHORT( p ) >= lookup_count )
+        OTL_INVALID_DATA;
   }
 
 
@@ -52,44 +82,49 @@
                          OTL_Validator  valid )
   {
     OTL_Bytes  p = table;
-    OTL_UInt   count;
+    OTL_UInt   num_lookups;
 
+
     OTL_CHECK( 2 );
+    num_lookups = OTL_NEXT_USHORT( p );
+    OTL_CHECK( num_lookups * 2 );
 
-    count = OTL_NEXT_USHORT( p );
-
-    OTL_CHECK( count*2 );
-    for ( ; count > 0; count-- )
-      otl_gpos_subtable_check( table + OTL_NEXT_USHORT( p ), valid );
+    /* scan subtable records */
+    for ( ; num_lookups > 0; num_lookups-- )
+      /* XXX: check lookup types? */
+      otl_gpos_subtable_validate( table + OTL_NEXT_USHORT( p ), valid );
   }
 
 
   static void
   otl_jstf_priority_validate( OTL_Bytes      table,
+                              OTL_UInt       gsub_lookup_count,
+                              OTL_UInt       gpos_lookup_count,
                               OTL_Validator  valid )
   {
     OTL_Bytes  p = table;
-    OTL_UInt   offset, val;
+    OTL_UInt   val;
 
+
     OTL_CHECK( 20 );
 
     /* shrinkage GSUB enable/disable */
     val = OTL_NEXT_USHORT( p );
     if ( val )
-      otl_jstf_gsub_mods_validate( table + val, valid );
+      otl_jstf_gsub_mods_validate( table + val, gsub_lookup_count, valid );
 
     val = OTL_NEXT_USHORT( p );
     if ( val )
-      otl_jstf_gsub_mods_validate( table + val, valid );
+      otl_jstf_gsub_mods_validate( table + val, gsub_lookup_count, valid );
 
     /* shrinkage GPOS enable/disable */
     val = OTL_NEXT_USHORT( p );
     if ( val )
-      otl_jstf_gpos_mods_validate( table + val, valid );
+      otl_jstf_gpos_mods_validate( table + val, gpos_lookup_count, valid );
 
     val = OTL_NEXT_USHORT( p );
     if ( val )
-      otl_jstf_gpos_mods_validate( table + val, valid );
+      otl_jstf_gpos_mods_validate( table + val, gpos_lookup_count, valid );
 
     /* shrinkage JSTF max */
     val = OTL_NEXT_USHORT( p );
@@ -99,20 +134,20 @@
     /* extension GSUB enable/disable */
     val = OTL_NEXT_USHORT( p );
     if ( val )
-      otl_jstf_gsub_mods_validate( table + val, valid );
+      otl_jstf_gsub_mods_validate( table + val, gsub_lookup_count, valid );
 
     val = OTL_NEXT_USHORT( p );
     if ( val )
-      otl_jstf_gsub_mods_validate( table + val, valid );
+      otl_jstf_gsub_mods_validate( table + val, gsub_lookup_count, valid );
 
     /* extension GPOS enable/disable */
     val = OTL_NEXT_USHORT( p );
     if ( val )
-      otl_jstf_gpos_mods_validate( table + val, valid );
+      otl_jstf_gpos_mods_validate( table + val, gpos_lookup_count, valid );
 
     val = OTL_NEXT_USHORT( p );
     if ( val )
-      otl_jstf_gpos_mods_validate( table + val, valid );
+      otl_jstf_gpos_mods_validate( table + val, gpos_lookup_count, valid );
 
     /* extension JSTF max */
     val = OTL_NEXT_USHORT( p );
@@ -120,47 +155,60 @@
       otl_jstf_max_validate( table + val, valid );
   }
 
+
   static void
   otl_jstf_lang_validate( OTL_Bytes      table,
+                          OTL_UInt       gsub_lookup_count,
+                          OTL_UInt       gpos_lookup_count,
                           OTL_Validator  valid )
   {
     OTL_Bytes  p = table;
-    OTL_UInt   count;
+    OTL_UInt   num_priorities;
 
+
     OTL_CHECK( 2 );
+    num_priorities = OTL_NEXT_USHORT( p );
+    OTL_CHECK( num_priorities * 2 );
 
-    count = OTL_NEXT_USHORT( p );
-
-    OTL_CHECK( count*2 );
-    for ( ; count > 0; count-- )
-      otl_jstf_priority_validate( table + OTL_NEXT_USHORT( p ), valid );
+    /* scan priority records */
+    for ( ; num_priorities > 0; num_priorities-- )
+      otl_jstf_priority_validate( table + OTL_NEXT_USHORT( p ),
+                                  gsub_lookup_count, gpos_lookup_count,
+                                  valid );
   }
 
 
   static void
   otl_jstf_script_validate( OTL_Bytes      table,
+                            OTL_UInt       gsub_lookup_count,
+                            OTL_UInt       gpos_lookup_count,
                             OTL_Validator  valid )
   {
     OTL_Bytes  p = table;
-    OTL_UInt   count, extender, default_lang;
+    OTL_UInt   num_langsys, extender, default_lang;
 
+
     OTL_CHECK( 6 );
     extender     = OTL_NEXT_USHORT( p );
     default_lang = OTL_NEXT_USHORT( p );
-    count        = OTL_NEXT_USHORT( p );
+    num_langsys  = OTL_NEXT_USHORT( p );
 
     if ( extender )
       otl_jstf_extender_validate( table + extender, valid );
 
     if ( default_lang )
-      otl_jstf_lang_validate( table + default_lang, valid );
+      otl_jstf_lang_validate( table + default_lang,
+                              gsub_lookup_count, gpos_lookup_count, valid );
 
-    OTL_CHECK( 6*count );
+    OTL_CHECK( 6 * num_langsys );
 
-    for ( ; count > 0; count-- )
+    /* scan langsys records */
+    for ( ; num_langsys > 0; num_langsys-- )
     {
-      p += 4;  /* ignore tag */
-      otl_jstf_lang_validate( table + OTL_NEXT_USHORT( p ), valid );
+      p += 4;       /* skip tag */
+
+      otl_jstf_lang_validate( table + OTL_NEXT_USHORT( p ),
+                              gsub_lookup_count, gpos_lookup_count, valid );
     }
   }
 
@@ -167,22 +215,34 @@
 
   OTL_LOCALDEF( void )
   otl_jstf_validate( OTL_Bytes      table,
+                     OTL_Bytes      gsub,
+                     OTL_Bytes      gpos,
                      OTL_Validator  valid )
   {
     OTL_Bytes  p = table;
-    OTL_UInt   count;
+    OTL_UInt   num_scripts, gsub_lookup_count, gpos_lookup_count;
 
-    OTL_CHECK( 4 );
 
+    OTL_CHECK( 6 );
+
     if ( OTL_NEXT_ULONG( p ) != 0x10000UL )
       OTL_INVALID_DATA;
 
-    count = OTL_NEXT_USHORT( p );
-    OTL_CHECK( count*6 );
+    num_scripts = OTL_NEXT_USHORT( p );
+    OTL_CHECK( num_scripts * 6 );
 
-    for ( ; count > 0; count++ )
+    gsub_lookup_count = otl_gsubgpos_get_lookup_count( gsub );
+    gpos_lookup_count = otl_gsubgpos_get_lookup_count( gpos );
+
+    /* scan script records */
+    for ( ; num_scripts > 0; num_scripts-- )
     {
-      p += 4;  /* ignore tag */
-      otl_jstf_script_validate( table + OTL_NEXT_USHORT( p ), valid );
+      p += 4;       /* skip tag */
+
+      otl_jstf_script_validate( table + OTL_NEXT_USHORT( p ),
+                                gsub_lookup_count, gpos_lookup_count, valid );
     }
   }
+
+
+/* END */
--- a/src/otlayout/otljstf.h
+++ b/src/otlayout/otljstf.h
@@ -1,14 +1,42 @@
-#ifndef __OTL_JSTF_H__
-#define __OTL_JSTF_H__
+/***************************************************************************/
+/*                                                                         */
+/*  otljstf.h                                                              */
+/*                                                                         */
+/*    OpenType layout support, JSTF table (specification).                 */
+/*                                                                         */
+/*  Copyright 2002, 2004 by                                                */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
 
+
+#ifndef __OTLJSTF_H__
+#define __OTLJSTF_H__
+
 #include "otlayout.h"
 
+
 OTL_BEGIN_HEADER
 
+
+  /* validate JSTF table                            */
+  /* GSUB and GPOS tables must already be validated */
   OTL_LOCAL( void )
   otl_jstf_validate( OTL_Bytes      table,
+                     OTL_Bytes      gsub,
+                     OTL_Bytes      gpos,
                      OTL_Validator  valid );
 
+
 OTL_END_HEADER
 
-#endif /* __OTL_JSTF_H__ */
+#endif /* __OTLJSTF_H__ */
+
+
+/* END */