ref: 46b5c4ac313b074bedd683a0f1fb25ad2b5e9664
parent: b5a0a34be7f8512a1b94859de99f94e4fa8dc6d9
author: Werner Lemberg <[email protected]>
date: Tue Aug 17 19:02:06 EDT 2004
* src/otlayout/otlgpos.c (otl_gpos_lookup1_validate, otl_gpos_lookup2_validate, otl_gpos_lookup3_validate, otl_gpos_lookup4_validate, otl_gpos_lookup5_validate, otl_gpos_lookup6_validate, otl_gpos_lookup9_validate, otl_gpos_validate): Update function arguments. (otl_gpos_lookup7_validate, otl_gpos_lookup8_validate): Update function arguments. Handle NULL offsets correctly. Check sequence and lookup indices for format 3. (otl_pos_rule_validate, otl_chain_pos_rule_validate): Add argument to pass lookup count. Check sequence and glyph indices. (otl_gpos_subtable_validate): Update function arguments. Update callers. * src/otlayout/otlgpos.h: Updated. * src/otlayout/otlgsub.c (otl_gsub_lookup1_validate, otl_gsub_lookup3_validate, otl_gsub_lookup8_validate): Update function arguments. Add glyph index checks. (otl_sequence_validate, otl_alternate_set_validate, otl_ligature_validate): Add argument to pass glyph count. Update callers. Add glyph index check. (otl_gsub_lookup2_validate, otl_gsub_lookup4_validate): Update function arguments. (otl_ligature_set_validate): Add argument to pass glyph count. Update caller. (otl_sub_class_rule_validate, otl_sub_class_rule_set_validate): Removed. (otl_sub_rule_validate, otl_chain_sub_rule_validate): Add argument to pass lookup count. Update callers. Add lookup index check. (otl_sub_rule_set_validate, otl_chain_sub_rule_set_validate): Add argument to pass lookup count. Update callers. (otl_gsub_lookup5_validate): Update function arguments. Handle NULL offsets correctly. Don't call otl_sub_class_rule_set_validate but otl_sub_rule_set_validate. Check sequence and lookup indices for format 3. (otl_gsub_lookup6_validate): Update function arguments. Handle NULL offsets correctly. Check sequence and lookup indices for format 3. (otl_gsub_lookup7_validate, otl_gsub_validate): Update function arguments. * src/otlayout/otlgsub.h: Updated. * src/otlayout/otlbase.c (otl_base_validate): Handle NULL offsets correctly. * src/otlayout/otlcommn.c (otl_class_definition_validate): Fix compiler warning. (otl_coverage_get_first, otl_coverage_get_last): New functions. (otl_lookup_validate): Add arguments to pass lookup and glyph counts. Update callers. (otl_lookup_list_validate): Add argument to pass glyph count. Update callers. * src/otlayout/otlcommn.h: Updated. * src/otlayout/otljstf.c (otl_jstf_extender_validate, otl_jstf_max_validate, otl_jstf_script_validate, otl_jstf_priority_validate, otl_jstf_lang_validate): Add parameter to validate glyph indices. Update callers. (otl_jstf_validate): Add parameter which specifies number of glyphs in font. * src/otlayout/otljstf.h: Updated.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,81 @@
+2004-08-16 Werner Lemberg <[email protected]>
+
+ * src/otlayout/otlgpos.c (otl_gpos_lookup1_validate,
+ otl_gpos_lookup2_validate, otl_gpos_lookup3_validate,
+ otl_gpos_lookup4_validate, otl_gpos_lookup5_validate,
+ otl_gpos_lookup6_validate, otl_gpos_lookup9_validate,
+ otl_gpos_validate): Update
+ function arguments.
+ (otl_gpos_lookup7_validate, otl_gpos_lookup8_validate): Update
+ function arguments.
+ Handle NULL offsets correctly.
+ Check sequence and lookup indices for format 3.
+ (otl_pos_rule_validate, otl_chain_pos_rule_validate): Add argument
+ to pass lookup count.
+ Check sequence and glyph indices.
+ (otl_gpos_subtable_validate): Update function arguments.
+ Update callers.
+
+ * src/otlayout/otlgpos.h: Updated.
+
+ * src/otlayout/otlgsub.c (otl_gsub_lookup1_validate,
+ otl_gsub_lookup3_validate, otl_gsub_lookup8_validate): Update
+ function arguments.
+ Add glyph index checks.
+ (otl_sequence_validate, otl_alternate_set_validate,
+ otl_ligature_validate): Add argument to pass glyph count.
+ Update callers.
+ Add glyph index check.
+ (otl_gsub_lookup2_validate, otl_gsub_lookup4_validate): Update
+ function arguments.
+ (otl_ligature_set_validate): Add argument to pass glyph count.
+ Update caller.
+ (otl_sub_class_rule_validate,
+ otl_sub_class_rule_set_validate): Removed.
+ (otl_sub_rule_validate, otl_chain_sub_rule_validate): Add argument
+ to pass lookup count.
+ Update callers.
+ Add lookup index check.
+ (otl_sub_rule_set_validate, otl_chain_sub_rule_set_validate): Add
+ argument to pass lookup count.
+ Update callers.
+ (otl_gsub_lookup5_validate): Update function arguments.
+ Handle NULL offsets correctly.
+ Don't call otl_sub_class_rule_set_validate but
+ otl_sub_rule_set_validate.
+ Check sequence and lookup indices for format 3.
+ (otl_gsub_lookup6_validate): Update function arguments.
+ Handle NULL offsets correctly.
+ Check sequence and lookup indices for format 3.
+ (otl_gsub_lookup7_validate, otl_gsub_validate): Update function
+ arguments.
+
+ * src/otlayout/otlgsub.h: Updated.
+
+ * src/otlayout/otlbase.c (otl_base_validate): Handle NULL offsets
+ correctly.
+
+ * src/otlayout/otlcommn.c (otl_class_definition_validate): Fix
+ compiler warning.
+ (otl_coverage_get_first, otl_coverage_get_last): New functions.
+ (otl_lookup_validate): Add arguments to pass lookup and glyph
+ counts.
+ Update callers.
+ (otl_lookup_list_validate): Add argument to pass glyph count.
+ Update callers.
+
+ * src/otlayout/otlcommn.h: Updated.
+
+ * src/otlayout/otljstf.c (otl_jstf_extender_validate,
+ otl_jstf_max_validate, otl_jstf_script_validate,
+ otl_jstf_priority_validate, otl_jstf_lang_validate): Add parameter
+ to validate glyph indices.
+ Update callers.
+ (otl_jstf_validate): Add parameter which specifies number of glyphs
+ in font.
+
+ * src/otlayout/otljstf.h: Updated.
+
2004-08-15 Werner Lemberg <[email protected]>
* src/otlayout/otlgpos.c (otl_liga_mark2_validate): Add parameter
--- a/src/otlayout/otlayout.h
+++ b/src/otlayout/otlayout.h
@@ -189,6 +189,8 @@
} OTL_ValidatorRec;
typedef void (*OTL_ValidateFunc)( OTL_Bytes table,
+ OTL_UInt lookup_count,
+ OTL_UInt glyph_count,
OTL_Validator valid );
OTL_API( void )
--- a/src/otlayout/otlbase.c
+++ b/src/otlayout/otlbase.c
@@ -208,6 +208,7 @@
OTL_Validator valid )
{
OTL_Bytes p = table;
+ OTL_UInt val;
OTL_CHECK( 6 );
@@ -215,8 +216,15 @@
if ( OTL_NEXT_ULONG( p ) != 0x10000UL )
OTL_INVALID_DATA;
- otl_axis_table_validate( table + OTL_NEXT_USHORT( p ), valid );
- otl_axis_table_validate( table + OTL_NEXT_USHORT( p ), valid );
+ /* validate horizontal axis table */
+ val = OTL_NEXT_USHORT( p );
+ if ( val )
+ otl_axis_table_validate( table + val, valid );
+
+ /* validate vertical axis table */
+ val = OTL_NEXT_USHORT( p );
+ if ( val )
+ otl_axis_table_validate( table + val, valid );
}
--- a/src/otlayout/otlcommn.c
+++ b/src/otlayout/otlcommn.c
@@ -87,6 +87,47 @@
OTL_LOCALDEF( OTL_UInt )
+ otl_coverage_get_first( OTL_Bytes table )
+ {
+ OTL_Bytes p = table;
+
+
+ p += 4; /* skip format and count */
+
+ return OTL_NEXT_USHORT( p );
+ }
+
+
+ OTL_LOCALDEF( OTL_UInt )
+ otl_coverage_get_last( OTL_Bytes table )
+ {
+ OTL_Bytes p = table;
+ OTL_UInt format = OTL_NEXT_USHORT( p );
+ OTL_UInt count = OTL_NEXT_USHORT( p );
+ OTL_UInt result;
+
+
+ switch ( format )
+ {
+ case 1:
+ p += ( count - 1 ) * 2;
+ result = OTL_NEXT_USHORT( p );
+ break;
+
+ case 2:
+ p += ( count - 1 ) * 6 + 2;
+ result = OTL_NEXT_USHORT( p );
+ break;
+
+ default:
+ ;
+ }
+
+ return result;
+ }
+
+
+ OTL_LOCALDEF( OTL_UInt )
otl_coverage_get_count( OTL_Bytes table )
{
OTL_Bytes p = table;
@@ -215,14 +256,15 @@
{
case 1:
{
- OTL_UInt num_glyphs, start = OTL_NEXT_USHORT( p );
+ OTL_UInt num_glyphs;
+ p += 2; /* skip start_glyph */
+
OTL_CHECK( 2 );
num_glyphs = OTL_NEXT_USHORT( p );
OTL_CHECK( num_glyphs * 2 );
-
}
break;
@@ -442,6 +484,8 @@
otl_lookup_validate( OTL_Bytes table,
OTL_UInt type_count,
OTL_ValidateFunc* type_funcs,
+ OTL_UInt lookup_count,
+ OTL_UInt glyph_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
@@ -463,7 +507,8 @@
/* scan subtables */
for ( ; num_subtables > 0; num_subtables-- )
- validate( table + OTL_NEXT_USHORT( p ), valid );
+ validate( table + OTL_NEXT_USHORT( p ), lookup_count, glyph_count,
+ valid );
}
@@ -511,10 +556,11 @@
otl_lookup_list_validate( OTL_Bytes table,
OTL_UInt type_count,
OTL_ValidateFunc* type_funcs,
+ OTL_UInt glyph_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
- OTL_UInt num_lookups;
+ OTL_UInt num_lookups, count;
OTL_CHECK( 2 );
@@ -522,9 +568,10 @@
OTL_CHECK( 2 * num_lookups );
/* scan lookup records */
- for ( ; num_lookups > 0; num_lookups-- )
+ for ( count = num_lookups; count > 0; count-- )
otl_lookup_validate( table + OTL_NEXT_USHORT( p ),
- type_count, type_funcs, valid );
+ type_count, type_funcs,
+ num_lookups, glyph_count, valid );
}
--- a/src/otlayout/otlcommn.h
+++ b/src/otlayout/otlcommn.h
@@ -37,6 +37,14 @@
otl_coverage_validate( OTL_Bytes table,
OTL_Validator valid );
+ /* return first covered glyph */
+ OTL_LOCAL( OTL_UInt )
+ otl_coverage_get_first( OTL_Bytes table );
+
+ /* return last covered glyph */
+ OTL_LOCAL( OTL_UInt )
+ otl_coverage_get_last( OTL_Bytes table );
+
/* return number of covered glyphs */
OTL_LOCAL( OTL_UInt )
otl_coverage_get_count( OTL_Bytes table );
@@ -116,6 +124,8 @@
otl_lookup_validate( OTL_Bytes table,
OTL_UInt type_count,
OTL_ValidateFunc* type_funcs,
+ OTL_UInt lookup_count,
+ OTL_UInt glyph_count,
OTL_Validator valid );
/* return number of sub-tables in a lookup */
@@ -143,6 +153,7 @@
otl_lookup_list_validate( OTL_Bytes table,
OTL_UInt type_count,
OTL_ValidateFunc* type_funcs,
+ OTL_UInt glyph_count,
OTL_Validator valid );
#if 0
--- a/src/otlayout/otlgpos.c
+++ b/src/otlayout/otlgpos.c
@@ -173,12 +173,17 @@
static void
otl_gpos_lookup1_validate( OTL_Bytes table,
+ OTL_UInt lookup_count,
+ OTL_UInt glyph_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
OTL_UInt format;
+ OTL_UNUSED( lookup_count );
+ OTL_UNUSED( glyph_count );
+
OTL_CHECK( 2 );
format = OTL_NEXT_USHORT( p );
switch ( format )
@@ -270,12 +275,17 @@
static void
otl_gpos_lookup2_validate( OTL_Bytes table,
+ OTL_UInt lookup_count,
+ OTL_UInt glyph_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
OTL_UInt format;
+ OTL_UNUSED( lookup_count );
+ OTL_UNUSED( glyph_count );
+
OTL_CHECK( 2 );
format = OTL_NEXT_USHORT( p );
switch ( format )
@@ -354,12 +364,17 @@
static void
otl_gpos_lookup3_validate( OTL_Bytes table,
+ OTL_UInt lookup_count,
+ OTL_UInt glyph_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
OTL_UInt format;
+ OTL_UNUSED( lookup_count );
+ OTL_UNUSED( glyph_count );
+
OTL_CHECK( 2 );
format = OTL_NEXT_USHORT( p );
switch ( format )
@@ -430,12 +445,17 @@
static void
otl_gpos_lookup4_validate( OTL_Bytes table,
+ OTL_UInt lookup_count,
+ OTL_UInt glyph_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
OTL_UInt format;
+ OTL_UNUSED( lookup_count );
+ OTL_UNUSED( glyph_count );
+
OTL_CHECK( 2 );
format = OTL_NEXT_USHORT( p );
switch ( format )
@@ -466,6 +486,7 @@
}
}
+
/*************************************************************************/
/*************************************************************************/
/***** *****/
@@ -529,12 +550,17 @@
static void
otl_gpos_lookup5_validate( OTL_Bytes table,
+ OTL_UInt lookup_count,
+ OTL_UInt glyph_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
OTL_UInt format;
+ OTL_UNUSED( lookup_count );
+ OTL_UNUSED( glyph_count );
+
OTL_CHECK( 2 );
format = OTL_NEXT_USHORT( p );
switch ( format )
@@ -576,12 +602,17 @@
static void
otl_gpos_lookup6_validate( OTL_Bytes table,
+ OTL_UInt lookup_count,
+ OTL_UInt glyph_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
OTL_UInt format;
+ OTL_UNUSED( lookup_count );
+ OTL_UNUSED( glyph_count );
+
OTL_CHECK( 2 );
format = OTL_NEXT_USHORT( p );
switch ( format )
@@ -623,6 +654,7 @@
/* used for both format 1 and 2 */
static void
otl_pos_rule_validate( OTL_Bytes table,
+ OTL_UInt lookup_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
@@ -638,8 +670,15 @@
OTL_CHECK( ( num_glyphs - 1 ) * 2 + num_pos * 4 );
- /* XXX: check pos lookups */
+ for ( ; num_pos > 0; num_pos-- )
+ {
+ if ( OTL_NEXT_USHORT( p ) >= num_glyphs )
+ OTL_INVALID_DATA;
+ if ( OTL_NEXT_USHORT( p ) >= lookup_count )
+ OTL_INVALID_DATA;
+ }
+
/* no need to check glyph indices/classes used as input for this */
/* context rule since even invalid glyph indices/classes return a */
/* meaningful result */
@@ -649,6 +688,7 @@
/* used for both format 1 and 2 */
static void
otl_pos_rule_set_validate( OTL_Bytes table,
+ OTL_UInt lookup_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
@@ -662,18 +702,23 @@
/* scan posrule records */
for ( ; num_posrules > 0; num_posrules-- )
- otl_pos_rule_validate( table + OTL_NEXT_USHORT( p ), valid );
+ otl_pos_rule_validate( table + OTL_NEXT_USHORT( p ), lookup_count,
+ valid );
}
static void
otl_gpos_lookup7_validate( OTL_Bytes table,
+ OTL_UInt lookup_count,
+ OTL_UInt glyph_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
OTL_UInt format;
+ OTL_UNUSED( glyph_count );
+
OTL_CHECK( 2 );
format = OTL_NEXT_USHORT( p );
switch ( format )
@@ -693,7 +738,8 @@
/* scan posrule set records */
for ( ; num_posrule_sets > 0; num_posrule_sets-- )
- otl_pos_rule_set_validate( table + OTL_NEXT_USHORT( p ), valid );
+ otl_pos_rule_set_validate( table + OTL_NEXT_USHORT( p ),
+ lookup_count, valid );
}
break;
@@ -714,13 +760,19 @@
/* scan pos class set rules */
for ( ; num_posclass_sets > 0; num_posclass_sets-- )
- otl_pos_rule_set_validate( table + OTL_NEXT_USHORT( p ), valid );
+ {
+ OTL_UInt offset = OTL_NEXT_USHORT( p );
+
+
+ if ( offset )
+ otl_pos_rule_set_validate( table + offset, lookup_count, valid );
+ }
}
break;
case 3:
{
- OTL_UInt num_glyphs, num_pos;
+ OTL_UInt num_glyphs, num_pos, count;
OTL_CHECK( 4 );
@@ -729,10 +781,17 @@
OTL_CHECK( num_glyphs * 2 + num_pos * 4 );
- for ( ; num_glyphs > 0; num_glyphs-- )
+ for ( count = num_glyphs; count > 0; count-- )
otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid );
- /* XXX: check pos lookups */
+ for ( ; num_pos > 0; num_pos-- )
+ {
+ if ( OTL_NEXT_USHORT( p ) >= num_glyphs )
+ OTL_INVALID_DATA;
+
+ if ( OTL_NEXT_USHORT( p ) >= lookup_count )
+ OTL_INVALID_DATA;
+ }
}
break;
@@ -753,6 +812,7 @@
/* used for both format 1 and 2 */
static void
otl_chain_pos_rule_validate( OTL_Bytes table,
+ OTL_UInt lookup_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
@@ -780,7 +840,18 @@
num_pos = OTL_NEXT_USHORT( p );
OTL_CHECK( num_pos * 4 );
- /* XXX: check pos lookups */
+ for ( ; num_pos > 0; num_pos-- )
+ {
+ if ( OTL_NEXT_USHORT( p ) >= num_input_glyphs )
+ OTL_INVALID_DATA;
+
+ if ( OTL_NEXT_USHORT( p ) >= lookup_count )
+ OTL_INVALID_DATA;
+ }
+
+ /* no need to check glyph indices/classes used as input for this */
+ /* context rule since even invalid glyph indices/classes return a */
+ /* meaningful result */
}
@@ -787,31 +858,37 @@
/* used for both format 1 and 2 */
static void
otl_chain_pos_rule_set_validate( OTL_Bytes table,
+ OTL_UInt lookup_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
- OTL_UInt count;
+ OTL_UInt num_chain_subrules;
OTL_CHECK( 2 );
- count = OTL_NEXT_USHORT( p );
+ num_chain_subrules = OTL_NEXT_USHORT( p );
- OTL_CHECK( 2 * count );
+ OTL_CHECK( num_chain_subrules * 2 );
/* scan chain pos rule records */
- for ( ; count > 0; count-- )
- otl_chain_pos_rule_validate( table + OTL_NEXT_USHORT( p ), valid );
+ for ( ; num_chain_subrules > 0; num_chain_subrules-- )
+ otl_chain_pos_rule_validate( table + OTL_NEXT_USHORT( p ),
+ lookup_count, valid );
}
static void
otl_gpos_lookup8_validate( OTL_Bytes table,
+ OTL_UInt lookup_count,
+ OTL_UInt glyph_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
OTL_UInt format;
+ OTL_UNUSED( glyph_count );
+
OTL_CHECK( 2 );
format = OTL_NEXT_USHORT( p );
switch ( format )
@@ -832,7 +909,7 @@
/* scan chain pos ruleset records */
for ( ; num_chain_pos_rulesets > 0; num_chain_pos_rulesets-- )
otl_chain_pos_rule_set_validate( table + OTL_NEXT_USHORT( p ),
- valid );
+ lookup_count, valid );
}
break;
@@ -859,8 +936,14 @@
/* scan chainpos class set records */
for ( ; num_chainpos_class_sets > 0; num_chainpos_class_sets-- )
- otl_chain_pos_rule_set_validate( table + OTL_NEXT_USHORT( p ),
- valid );
+ {
+ OTL_UInt offset = OTL_NEXT_USHORT( p );
+
+
+ if ( offset )
+ otl_chain_pos_rule_set_validate( table + offset, lookup_count,
+ valid );
+ }
}
break;
@@ -867,25 +950,25 @@
case 3:
{
OTL_UInt num_backtrack_glyphs, num_input_glyphs;
- OTL_UInt num_lookahead_glyphs, num_pos;
+ OTL_UInt num_lookahead_glyphs, num_pos, count;
OTL_CHECK( 2 );
+
num_backtrack_glyphs = OTL_NEXT_USHORT( p );
+ OTL_CHECK( num_backtrack_glyphs * 2 + 2 );
- OTL_CHECK( 2 * num_backtrack_glyphs + 2 );
-
for ( ; num_backtrack_glyphs > 0; num_backtrack_glyphs-- )
otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid );
num_input_glyphs = OTL_NEXT_USHORT( p );
- OTL_CHECK( 2 * num_input_glyphs + 2 );
+ OTL_CHECK( num_input_glyphs * 2 + 2 );
- for ( ; num_input_glyphs > 0; num_input_glyphs-- )
+ for ( count = num_input_glyphs; count > 0; count-- )
otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid );
num_lookahead_glyphs = OTL_NEXT_USHORT( p );
- OTL_CHECK( 2 * num_lookahead_glyphs + 2 );
+ OTL_CHECK( num_lookahead_glyphs * 2 + 2 );
for ( ; num_lookahead_glyphs > 0; num_lookahead_glyphs-- )
otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid );
@@ -893,7 +976,14 @@
num_pos = OTL_NEXT_USHORT( p );
OTL_CHECK( num_pos * 4 );
- /* XXX: check pos lookups */
+ for ( ; num_pos > 0; num_pos-- )
+ {
+ if ( OTL_NEXT_USHORT( p ) >= num_input_glyphs )
+ OTL_INVALID_DATA;
+
+ if ( OTL_NEXT_USHORT( p ) >= lookup_count )
+ OTL_INVALID_DATA;
+ }
}
break;
@@ -913,6 +1003,8 @@
static void
otl_gpos_lookup9_validate( OTL_Bytes table,
+ OTL_UInt lookup_count,
+ OTL_UInt glyph_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
@@ -937,7 +1029,7 @@
OTL_INVALID_DATA;
validate = otl_gpos_validate_funcs[lookup_type - 1];
- validate( table + lookup_offset, valid );
+ validate( table + lookup_offset, lookup_count, glyph_count, valid );
}
break;
@@ -963,9 +1055,11 @@
OTL_LOCALDEF( void )
otl_gpos_subtable_validate( OTL_Bytes table,
+ OTL_UInt glyph_count,
OTL_Validator valid )
{
- otl_lookup_list_validate( table, 9, otl_gpos_validate_funcs, valid );
+ otl_lookup_list_validate( table, 9, otl_gpos_validate_funcs,
+ glyph_count, valid );
}
@@ -979,6 +1073,7 @@
OTL_LOCALDEF( void )
otl_gpos_validate( OTL_Bytes table,
+ OTL_UInt glyph_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
@@ -994,7 +1089,7 @@
features = OTL_NEXT_USHORT( p );
lookups = OTL_NEXT_USHORT( p );
- otl_gpos_subtable_validate( table + lookups, valid );
+ otl_gpos_subtable_validate( table + lookups, glyph_count, 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
@@ -26,10 +26,12 @@
OTL_LOCAL( void )
otl_gpos_subtable_validate( OTL_Bytes table,
+ OTL_UInt glyph_count,
OTL_Validator valid );
OTL_LOCAL( void )
otl_gpos_validate( OTL_Bytes table,
+ OTL_UInt glyph_count,
OTL_Validator valid );
--- a/src/otlayout/otlgsub.c
+++ b/src/otlayout/otlgsub.c
@@ -57,12 +57,16 @@
static void
otl_gsub_lookup1_validate( OTL_Bytes table,
+ OTL_UInt lookup_count,
+ OTL_UInt glyph_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
OTL_UInt format;
+ OTL_UNUSED( lookup_count );
+
OTL_CHECK( 2 );
format = OTL_NEXT_USHORT( p );
@@ -69,12 +73,26 @@
switch ( format )
{
case 1:
- OTL_CHECK( 4 );
+ {
+ OTL_Bytes coverage;
+ OTL_Int delta;
+ OTL_Long idx;
- otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid );
- /* skip delta glyph ID */
+ OTL_CHECK( 4 );
+ coverage = table + OTL_NEXT_USHORT( p );
+ delta = OTL_NEXT_SHORT( p );
+ otl_coverage_validate( coverage, valid );
+
+ idx = otl_coverage_get_first( coverage ) + delta;
+ if ( idx < 0 )
+ OTL_INVALID_DATA;
+
+ idx = otl_coverage_get_last( coverage ) + delta;
+ if ( (OTL_UInt)idx >= glyph_count )
+ OTL_INVALID_DATA;
+ }
break;
case 2:
@@ -88,11 +106,11 @@
otl_coverage_validate( table + coverage, valid );
- OTL_CHECK( 2 * num_glyphs );
+ OTL_CHECK( num_glyphs * 2 );
- /* We don't check that there are at most `num_glyphs' */
- /* elements in the coverage table. This is delayed */
- /* to the lookup function. */
+ for ( ; num_glyphs > 0; num_glyphs-- )
+ if ( OTL_NEXT_USHORT( p ) >= glyph_count )
+ OTL_INVALID_DATA;
}
break;
@@ -198,6 +216,7 @@
static void
otl_sequence_validate( OTL_Bytes table,
+ OTL_UInt glyph_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
@@ -207,23 +226,29 @@
OTL_CHECK( 2 );
num_glyphs = OTL_NEXT_USHORT( p );
- /* XXX: according to the spec, `num_glyphs' should be > 0; */
- /* we can deal with these cases pretty well, however */
+ /* according to the specification, `num_glyphs' should be > 0; */
+ /* we can deal with these cases pretty well, however */
- OTL_CHECK( 2 * num_glyphs );
+ OTL_CHECK( num_glyphs * 2 );
- /* XXX: check glyph indices */
+ for ( ; num_glyphs > 0; num_glyphs-- )
+ if ( OTL_NEXT_USHORT( p ) >= glyph_count )
+ OTL_INVALID_DATA;
}
static void
otl_gsub_lookup2_validate( OTL_Bytes table,
+ OTL_UInt lookup_count,
+ OTL_UInt glyph_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
OTL_UInt format;
+ OTL_UNUSED( lookup_count );
+
OTL_CHECK( 2 );
format = OTL_NEXT_USHORT( p );
switch ( format )
@@ -243,7 +268,8 @@
/* scan sequence records */
for ( ; num_sequences > 0; num_sequences-- )
- otl_sequence_validate( table + OTL_NEXT_USHORT( p ), valid );
+ otl_sequence_validate( table + OTL_NEXT_USHORT( p ), glyph_count,
+ valid );
}
break;
@@ -329,29 +355,36 @@
static void
otl_alternate_set_validate( OTL_Bytes table,
+ OTL_UInt glyph_count,
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( 2 * count );
+ OTL_CHECK( num_glyphs * 2 );
- /* XXX: check glyph indices */
+ for ( ; num_glyphs > 0; num_glyphs-- )
+ if ( OTL_NEXT_USHORT( p ) >= glyph_count )
+ OTL_INVALID_DATA;
}
static void
otl_gsub_lookup3_validate( OTL_Bytes table,
+ OTL_UInt lookup_count,
+ OTL_UInt glyph_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
OTL_UInt format;
+ OTL_UNUSED( lookup_count );
+
OTL_CHECK( 2 );
format = OTL_NEXT_USHORT( p );
switch ( format )
@@ -367,11 +400,12 @@
otl_coverage_validate( table + coverage, valid );
- OTL_CHECK( 2 * num_alternate_sets );
+ OTL_CHECK( num_alternate_sets * 2 );
/* scan alternate set records */
for ( ; num_alternate_sets > 0; num_alternate_sets-- )
- otl_alternate_set_validate( table + OTL_NEXT_USHORT( p ), valid );
+ otl_alternate_set_validate( table + OTL_NEXT_USHORT( p ),
+ glyph_count, valid );
}
break;
@@ -442,6 +476,7 @@
static void
otl_ligature_validate( OTL_Bytes table,
+ OTL_UInt glyph_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
@@ -455,14 +490,19 @@
if ( num_components == 0 )
OTL_INVALID_DATA;
- OTL_CHECK( 2 * ( num_components - 1 ) );
+ num_components--;
- /* XXX: check glyph indices */
+ OTL_CHECK( num_components * 2 );
+
+ for ( ; num_components > 0; num_components-- )
+ if ( OTL_NEXT_USHORT( p ) >= glyph_count )
+ OTL_INVALID_DATA;
}
static void
otl_ligature_set_validate( OTL_Bytes table,
+ OTL_UInt glyph_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
@@ -472,22 +512,27 @@
OTL_CHECK( 2 );
num_ligatures = OTL_NEXT_USHORT( p );
- OTL_CHECK( 2 * num_ligatures );
+ OTL_CHECK( num_ligatures * 2 );
/* scan ligature records */
for ( ; num_ligatures > 0; num_ligatures-- )
- otl_ligature_validate( table + OTL_NEXT_USHORT( p ), valid );
+ otl_ligature_validate( table + OTL_NEXT_USHORT( p ), glyph_count,
+ valid );
}
static void
otl_gsub_lookup4_validate( OTL_Bytes table,
+ OTL_UInt lookup_count,
+ OTL_UInt glyph_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
OTL_UInt format;
+ OTL_UNUSED( lookup_count);
+
OTL_CHECK( 2 );
format = OTL_NEXT_USHORT( p );
switch ( format )
@@ -503,11 +548,12 @@
otl_coverage_validate( table + coverage, valid );
- OTL_CHECK( 2 * num_ligsets );
+ OTL_CHECK( num_ligsets * 2 );
/* scan ligature set records */
for ( ; num_ligsets > 0; num_ligsets-- )
- otl_ligature_set_validate( table + OTL_NEXT_USHORT( p ), valid );
+ otl_ligature_set_validate( table + OTL_NEXT_USHORT( p ),
+ glyph_count, valid );
}
break;
@@ -525,8 +571,10 @@
/*************************************************************************/
/*************************************************************************/
+ /* used for both format 1 and 2 */
static void
otl_sub_rule_validate( OTL_Bytes table,
+ OTL_UInt lookup_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
@@ -542,12 +590,25 @@
OTL_CHECK( ( num_glyphs - 1 ) * 2 + num_subst * 4 );
- /* XXX: check glyph indices and subst lookups */
+ for ( ; num_subst > 0; num_subst-- )
+ {
+ if ( OTL_NEXT_USHORT( p ) >= num_glyphs )
+ OTL_INVALID_DATA;
+
+ if ( OTL_NEXT_USHORT( p ) >= lookup_count )
+ OTL_INVALID_DATA;
+ }
+
+ /* no need to check glyph indices/classes used as input for this */
+ /* context rule since even invalid glyph indices/classes return a */
+ /* meaningful result */
}
+ /* used for both format 1 and 2 */
static void
otl_sub_rule_set_validate( OTL_Bytes table,
+ OTL_UInt lookup_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
@@ -557,65 +618,27 @@
OTL_CHECK( 2 );
num_subrules = OTL_NEXT_USHORT( p );
- OTL_CHECK( 2 * num_subrules );
+ OTL_CHECK( num_subrules * 2 );
- /* scan sub rule records */
- for ( ; num_subrules > 0; num_subrules-- )
- otl_sub_rule_validate( table + OTL_NEXT_USHORT( p ), valid );
- }
-
-
- static void
- otl_sub_class_rule_validate( OTL_Bytes table,
- OTL_Validator valid )
- {
- OTL_Bytes p = table;
- OTL_UInt num_glyphs, num_subst;
-
-
- OTL_CHECK( 4 );
- num_glyphs = OTL_NEXT_USHORT( p );
- num_subst = OTL_NEXT_USHORT( p );
-
- if ( num_glyphs == 0 )
- OTL_INVALID_DATA;
-
- OTL_CHECK( ( num_glyphs - 1 ) * 2 + num_subst * 4 );
-
- /* XXX: check subst lookups */
-
- /* no need to check glyph indices used as input for this context */
- /* rule since even invalid glyph indices return a meaningful result */
- }
-
-
- static void
- otl_sub_class_rule_set_validate( OTL_Bytes table,
- OTL_Validator valid )
- {
- OTL_Bytes p = table;
- OTL_UInt num_subrules;
-
-
- OTL_CHECK( 2 );
- num_subrules = OTL_NEXT_USHORT( p );
-
- OTL_CHECK( 2 * num_subrules );
-
/* scan subrule records */
for ( ; num_subrules > 0; num_subrules-- )
- otl_sub_class_rule_validate( table + OTL_NEXT_USHORT( p ), valid );
+ otl_sub_rule_validate( table + OTL_NEXT_USHORT( p ), lookup_count,
+ valid );
}
static void
otl_gsub_lookup5_validate( OTL_Bytes table,
+ OTL_UInt lookup_count,
+ OTL_UInt glyph_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
OTL_UInt format;
+ OTL_UNUSED( glyph_count );
+
OTL_CHECK( 2 );
format = OTL_NEXT_USHORT( p );
switch ( format )
@@ -631,11 +654,12 @@
otl_coverage_validate( table + coverage, valid );
- OTL_CHECK( 2 * num_subrulesets );
+ OTL_CHECK( num_subrulesets * 2 );
/* scan subrule set records */
for ( ; num_subrulesets > 0; num_subrulesets-- )
- otl_sub_rule_set_validate( table + OTL_NEXT_USHORT( p ), valid );
+ otl_sub_rule_set_validate( table + OTL_NEXT_USHORT( p ),
+ lookup_count, valid );
}
break;
@@ -652,18 +676,23 @@
otl_coverage_validate( table + coverage, valid );
otl_class_definition_validate( table + class_def, valid );
- OTL_CHECK( 2 * num_subclass_sets );
+ OTL_CHECK( num_subclass_sets * 2 );
/* scan subclass set records */
for ( ; num_subclass_sets > 0; num_subclass_sets-- )
- otl_sub_class_rule_set_validate( table + OTL_NEXT_USHORT( p ),
- valid );
+ {
+ OTL_UInt offset = OTL_NEXT_USHORT( p );
+
+
+ if ( offset )
+ otl_sub_rule_set_validate( table + offset, lookup_count, valid );
+ }
}
break;
case 3:
{
- OTL_UInt num_glyphs, num_subst;
+ OTL_UInt num_glyphs, num_subst, count;
OTL_CHECK( 4 );
@@ -670,12 +699,19 @@
num_glyphs = OTL_NEXT_USHORT( p );
num_subst = OTL_NEXT_USHORT( p );
- OTL_CHECK( 2 * num_glyphs + 4 * num_subst );
+ OTL_CHECK( num_glyphs * 2 + num_subst * 4 );
- for ( ; num_glyphs > 0; num_glyphs-- )
+ for ( count = num_glyphs; count > 0; count-- )
otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid );
- /* XXX: check subst lookups */
+ for ( ; num_subst > 0; num_subst-- )
+ {
+ if ( OTL_NEXT_USHORT( p ) >= num_glyphs )
+ OTL_INVALID_DATA;
+
+ if ( OTL_NEXT_USHORT( p ) >= lookup_count )
+ OTL_INVALID_DATA;
+ }
}
break;
@@ -696,6 +732,7 @@
/* used for both format 1 and 2 */
static void
otl_chain_sub_rule_validate( OTL_Bytes table,
+ OTL_UInt lookup_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
@@ -706,27 +743,35 @@
OTL_CHECK( 2 );
num_backtrack_glyphs = OTL_NEXT_USHORT( p );
- OTL_CHECK( 2 * num_backtrack_glyphs + 2 );
- p += 2 * num_backtrack_glyphs;
+ OTL_CHECK( num_backtrack_glyphs * 2 + 2 );
+ p += num_backtrack_glyphs * 2;
num_input_glyphs = OTL_NEXT_USHORT( p );
if ( num_input_glyphs == 0 )
OTL_INVALID_DATA;
- OTL_CHECK( 2 * num_input_glyphs );
- p += 2 * ( num_input_glyphs - 1 );
+ OTL_CHECK( num_input_glyphs * 2 );
+ p += ( num_input_glyphs - 1 ) * 2;
num_lookahead_glyphs = OTL_NEXT_USHORT( p );
- OTL_CHECK( 2 * num_lookahead_glyphs + 2 );
- p += 2 * num_lookahead_glyphs;
+ OTL_CHECK( num_lookahead_glyphs * 2 + 2 );
+ p += num_lookahead_glyphs * 2;
num_subst = OTL_NEXT_USHORT( p );
- OTL_CHECK( 4 * num_subst );
+ OTL_CHECK( num_subst * 4 );
- /* XXX: check subst lookups */
+ for ( ; num_subst > 0; num_subst-- )
+ {
+ if ( OTL_NEXT_USHORT( p ) >= num_input_glyphs )
+ OTL_INVALID_DATA;
- /* no need to check glyph indices used as input for this context */
- /* rule since even invalid glyph indices return a meaningful result */
+ if ( OTL_NEXT_USHORT( p ) >= lookup_count )
+ OTL_INVALID_DATA;
+ }
+
+ /* no need to check glyph indices/classes used as input for this */
+ /* context rule since even invalid glyph indices/classes return a */
+ /* meaningful result */
}
@@ -733,6 +778,7 @@
/* used for both format 1 and 2 */
static void
otl_chain_sub_rule_set_validate( OTL_Bytes table,
+ OTL_UInt lookup_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
@@ -742,22 +788,27 @@
OTL_CHECK( 2 );
num_chain_subrules = OTL_NEXT_USHORT( p );
- OTL_CHECK( 2 * num_chain_subrules );
+ OTL_CHECK( num_chain_subrules * 2 );
- /* scan chain subrule records */
+ /* scan chain subst rule records */
for ( ; num_chain_subrules > 0; num_chain_subrules-- )
- otl_chain_sub_rule_validate( table + OTL_NEXT_USHORT( p ), valid );
+ otl_chain_sub_rule_validate( table + OTL_NEXT_USHORT( p ),
+ lookup_count, valid );
}
static void
otl_gsub_lookup6_validate( OTL_Bytes table,
+ OTL_UInt lookup_count,
+ OTL_UInt glyph_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
OTL_UInt format;
+ OTL_UNUSED( glyph_count );
+
OTL_CHECK( 2 );
format = OTL_NEXT_USHORT( p );
switch ( format )
@@ -773,12 +824,12 @@
otl_coverage_validate( table + coverage, valid );
- OTL_CHECK( 2 * num_chain_subrulesets );
+ OTL_CHECK( num_chain_subrulesets * 2 );
/* scan chain subrule set records */
for ( ; num_chain_subrulesets > 0; num_chain_subrulesets-- )
otl_chain_sub_rule_set_validate( table + OTL_NEXT_USHORT( p ),
- valid );
+ lookup_count, valid );
}
break;
@@ -801,12 +852,18 @@
otl_class_definition_validate( table + input_class, valid );
otl_class_definition_validate( table + ahead_class, valid );
- OTL_CHECK( 2 * num_chain_subclass_sets );
+ OTL_CHECK( num_chain_subclass_sets * 2 );
/* scan chain subclass set records */
for ( ; num_chain_subclass_sets > 0; num_chain_subclass_sets-- )
- otl_chain_sub_rule_set_validate( table + OTL_NEXT_USHORT( p ),
- valid );
+ {
+ OTL_UInt offset = OTL_NEXT_USHORT( p );
+
+
+ if ( offset )
+ otl_chain_sub_rule_set_validate( table + offset, lookup_count,
+ valid );
+ }
}
break;
@@ -813,25 +870,25 @@
case 3:
{
OTL_UInt num_backtrack_glyphs, num_input_glyphs;
- OTL_UInt num_lookahead_glyphs, num_subst;
+ OTL_UInt num_lookahead_glyphs, num_subst, count;
OTL_CHECK( 2 );
num_backtrack_glyphs = OTL_NEXT_USHORT( p );
- OTL_CHECK( 2 * num_backtrack_glyphs + 2 );
+ OTL_CHECK( num_backtrack_glyphs * 2 + 2 );
for ( ; num_backtrack_glyphs > 0; num_backtrack_glyphs-- )
otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid );
num_input_glyphs = OTL_NEXT_USHORT( p );
- OTL_CHECK( 2 * num_input_glyphs + 2 );
+ OTL_CHECK( num_input_glyphs * 2 + 2 );
- for ( ; num_input_glyphs > 0; num_input_glyphs-- )
+ for ( count = num_input_glyphs; count > 0; count-- )
otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid );
num_lookahead_glyphs = OTL_NEXT_USHORT( p );
- OTL_CHECK( 2 * num_lookahead_glyphs + 2 );
+ OTL_CHECK( num_lookahead_glyphs * 2 + 2 );
for ( ; num_lookahead_glyphs > 0; num_lookahead_glyphs-- )
otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid );
@@ -839,7 +896,14 @@
num_subst = OTL_NEXT_USHORT( p );
OTL_CHECK( num_subst * 4 );
- /* XXX: check subst lookups */
+ for ( ; num_subst > 0; num_subst-- )
+ {
+ if ( OTL_NEXT_USHORT( p ) >= num_input_glyphs )
+ OTL_INVALID_DATA;
+
+ if ( OTL_NEXT_USHORT( p ) >= lookup_count )
+ OTL_INVALID_DATA;
+ }
}
break;
@@ -859,6 +923,8 @@
static void
otl_gsub_lookup7_validate( OTL_Bytes table,
+ OTL_UInt lookup_count,
+ OTL_UInt glyph_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
@@ -883,7 +949,7 @@
OTL_INVALID_DATA;
validate = otl_gsub_validate_funcs[lookup_type - 1];
- validate( table + lookup_offset, valid );
+ validate( table + lookup_offset, lookup_count, glyph_count, valid );
}
break;
@@ -903,6 +969,8 @@
static void
otl_gsub_lookup8_validate( OTL_Bytes table,
+ OTL_UInt lookup_count,
+ OTL_UInt glyph_count,
OTL_Validator valid )
{
OTL_Bytes p = table, coverage;
@@ -909,7 +977,9 @@
OTL_UInt format;
OTL_UInt num_backtrack_glyphs, num_lookahead_glyphs, num_glyphs;
+ OTL_UNUSED( lookup_count );
+
OTL_CHECK( 2 );
format = OTL_NEXT_USHORT( p );
switch ( format )
@@ -922,13 +992,13 @@
otl_coverage_validate( coverage, valid );
- OTL_CHECK( 2 * num_backtrack_glyphs + 2 );
+ OTL_CHECK( num_backtrack_glyphs * 2 + 2 );
for ( ; num_backtrack_glyphs > 0; num_backtrack_glyphs-- )
otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid );
num_lookahead_glyphs = OTL_NEXT_USHORT( p );
- OTL_CHECK( 2 * num_lookahead_glyphs + 2 );
+ OTL_CHECK( num_lookahead_glyphs * 2 + 2 );
for ( ; num_lookahead_glyphs > 0; num_lookahead_glyphs-- )
otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid );
@@ -937,9 +1007,12 @@
if ( num_glyphs != otl_coverage_get_count( coverage ) )
OTL_INVALID_DATA;
- OTL_CHECK( 2 * num_glyphs );
+ OTL_CHECK( num_glyphs * 2 );
- /* XXX: check glyph indices */
+ for ( ; num_glyphs > 0; num_glyphs-- )
+ if ( OTL_NEXT_USHORT( p ) >= glyph_count )
+ OTL_INVALID_DATA;
+
break;
default:
@@ -971,6 +1044,7 @@
OTL_LOCALDEF( void )
otl_gsub_validate( OTL_Bytes table,
+ OTL_UInt glyph_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
@@ -987,7 +1061,7 @@
lookups = OTL_NEXT_USHORT( p );
otl_lookup_list_validate( table + lookups, 8, otl_gsub_validate_funcs,
- valid );
+ glyph_count, valid );
otl_feature_list_validate( table + features, table + lookups, valid );
otl_script_list_validate( table + scripts, table + features, valid );
}
--- a/src/otlayout/otlgsub.h
+++ b/src/otlayout/otlgsub.h
@@ -40,6 +40,7 @@
OTL_LOCAL( void )
otl_gsub_validate( OTL_Bytes table,
+ OTL_UInt glyph_count,
OTL_Validator valid );
--- a/src/otlayout/otljstf.c
+++ b/src/otlayout/otljstf.c
@@ -23,6 +23,7 @@
static void
otl_jstf_extender_validate( OTL_Bytes table,
+ OTL_UInt glyph_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
@@ -35,7 +36,9 @@
OTL_CHECK( num_glyphs * 2 );
- /* XXX: check glyph indices */
+ for ( ; num_glyphs > 0; num_glyphs-- )
+ if ( OTL_NEXT_USHORT( p ) >= glyph_count )
+ OTL_INVALID_DATA;
}
@@ -63,6 +66,7 @@
static void
otl_jstf_max_validate( OTL_Bytes table,
+ OTL_UInt glyph_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
@@ -76,7 +80,8 @@
/* scan subtable records */
for ( ; num_lookups > 0; num_lookups-- )
/* XXX: check lookup types? */
- otl_gpos_subtable_validate( table + OTL_NEXT_USHORT( p ), valid );
+ otl_gpos_subtable_validate( table + OTL_NEXT_USHORT( p ), glyph_count,
+ valid );
}
@@ -84,6 +89,7 @@
otl_jstf_priority_validate( OTL_Bytes table,
OTL_UInt gsub_lookup_count,
OTL_UInt gpos_lookup_count,
+ OTL_UInt glyph_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
@@ -117,7 +123,7 @@
/* shrinkage JSTF max */
val = OTL_NEXT_USHORT( p );
if ( val )
- otl_jstf_max_validate( table + val, valid );
+ otl_jstf_max_validate( table + val, glyph_count, valid );
/* extension GSUB enable/disable */
val = OTL_NEXT_USHORT( p );
@@ -144,7 +150,7 @@
/* extension JSTF max */
val = OTL_NEXT_USHORT( p );
if ( val )
- otl_jstf_max_validate( table + val, valid );
+ otl_jstf_max_validate( table + val, glyph_count, valid );
}
@@ -152,6 +158,7 @@
otl_jstf_lang_validate( OTL_Bytes table,
OTL_UInt gsub_lookup_count,
OTL_UInt gpos_lookup_count,
+ OTL_UInt glyph_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
@@ -166,7 +173,7 @@
for ( ; num_priorities > 0; num_priorities-- )
otl_jstf_priority_validate( table + OTL_NEXT_USHORT( p ),
gsub_lookup_count, gpos_lookup_count,
- valid );
+ glyph_count, valid );
}
@@ -174,6 +181,7 @@
otl_jstf_script_validate( OTL_Bytes table,
OTL_UInt gsub_lookup_count,
OTL_UInt gpos_lookup_count,
+ OTL_UInt glyph_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
@@ -186,11 +194,12 @@
num_langsys = OTL_NEXT_USHORT( p );
if ( extender )
- otl_jstf_extender_validate( table + extender, valid );
+ otl_jstf_extender_validate( table + extender, glyph_count, valid );
if ( default_lang )
otl_jstf_lang_validate( table + default_lang,
- gsub_lookup_count, gpos_lookup_count, valid );
+ gsub_lookup_count, gpos_lookup_count,
+ glyph_count, valid );
OTL_CHECK( 6 * num_langsys );
@@ -200,7 +209,8 @@
p += 4; /* skip tag */
otl_jstf_lang_validate( table + OTL_NEXT_USHORT( p ),
- gsub_lookup_count, gpos_lookup_count, valid );
+ gsub_lookup_count, gpos_lookup_count,
+ glyph_count, valid );
}
}
@@ -209,6 +219,7 @@
otl_jstf_validate( OTL_Bytes table,
OTL_Bytes gsub,
OTL_Bytes gpos,
+ OTL_UInt glyph_count,
OTL_Validator valid )
{
OTL_Bytes p = table;
@@ -239,7 +250,8 @@
p += 4; /* skip tag */
otl_jstf_script_validate( table + OTL_NEXT_USHORT( p ),
- gsub_lookup_count, gpos_lookup_count, valid );
+ gsub_lookup_count, gpos_lookup_count,
+ glyph_count, valid );
}
}
--- a/src/otlayout/otljstf.h
+++ b/src/otlayout/otljstf.h
@@ -25,13 +25,14 @@
OTL_BEGIN_HEADER
- /* validate JSTF table */
- /* GSUB and GPOS tables must already be validated; if table is */
- /* missing, set value to 0 */
+ /* validate JSTF table */
+ /* GSUB and GPOS tables should already be validated; */
+ /* if missing, set corresponding argument to 0 */
OTL_LOCAL( void )
otl_jstf_validate( OTL_Bytes table,
OTL_Bytes gsub,
OTL_Bytes gpos,
+ OTL_UInt glyph_count,
OTL_Validator valid );