* 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.
This commit is contained in:
parent
b5a0a34be7
commit
46b5c4ac31
78
ChangeLog
78
ChangeLog
|
@ -1,3 +1,81 @@
|
|||
2004-08-16 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
* 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 <wl@gnu.org>
|
||||
|
||||
* src/otlayout/otlgpos.c (otl_liga_mark2_validate): Add parameter
|
||||
|
|
|
@ -189,6 +189,8 @@ OTL_BEGIN_HEADER
|
|||
} OTL_ValidatorRec;
|
||||
|
||||
typedef void (*OTL_ValidateFunc)( OTL_Bytes table,
|
||||
OTL_UInt lookup_count,
|
||||
OTL_UInt glyph_count,
|
||||
OTL_Validator valid );
|
||||
|
||||
OTL_API( void )
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -86,6 +86,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 )
|
||||
{
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -37,6 +37,14 @@ OTL_BEGIN_HEADER
|
|||
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_BEGIN_HEADER
|
|||
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_BEGIN_HEADER
|
|||
otl_lookup_list_validate( OTL_Bytes table,
|
||||
OTL_UInt type_count,
|
||||
OTL_ValidateFunc* type_funcs,
|
||||
OTL_UInt glyph_count,
|
||||
OTL_Validator valid );
|
||||
|
||||
#if 0
|
||||
|
|
|
@ -173,11 +173,16 @@
|
|||
|
||||
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 );
|
||||
|
@ -270,11 +275,16 @@
|
|||
|
||||
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 );
|
||||
|
@ -354,11 +364,16 @@
|
|||
|
||||
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 );
|
||||
|
@ -430,11 +445,16 @@
|
|||
|
||||
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 );
|
||||
|
@ -466,6 +486,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
/***** *****/
|
||||
|
@ -529,11 +550,16 @@
|
|||
|
||||
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 );
|
||||
|
@ -576,11 +602,16 @@
|
|||
|
||||
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 );
|
||||
|
@ -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,7 +670,14 @@
|
|||
|
||||
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 */
|
||||
|
@ -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,17 +702,22 @@
|
|||
|
||||
/* 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 );
|
||||
|
@ -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,37 +840,54 @@
|
|||
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 */
|
||||
}
|
||||
|
||||
|
||||
/* 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 );
|
||||
|
@ -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,33 +936,39 @@
|
|||
|
||||
/* 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;
|
||||
|
||||
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( 2 * num_backtrack_glyphs + 2 );
|
||||
num_backtrack_glyphs = OTL_NEXT_USHORT( p );
|
||||
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 );
|
||||
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -26,10 +26,12 @@ OTL_BEGIN_HEADER
|
|||
|
||||
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 );
|
||||
|
||||
|
||||
|
|
|
@ -57,11 +57,15 @@
|
|||
|
||||
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,22 +226,28 @@
|
|||
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 );
|
||||
|
@ -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,28 +355,35 @@
|
|||
|
||||
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 );
|
||||
|
@ -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,21 +512,26 @@
|
|||
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 );
|
||||
|
@ -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,64 +618,26 @@
|
|||
OTL_CHECK( 2 );
|
||||
num_subrules = OTL_NEXT_USHORT( p );
|
||||
|
||||
OTL_CHECK( 2 * num_subrules );
|
||||
|
||||
/* 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 );
|
||||
OTL_CHECK( num_subrules * 2 );
|
||||
|
||||
/* 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 );
|
||||
|
@ -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,30 +676,42 @@
|
|||
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 );
|
||||
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,33 +743,42 @@
|
|||
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 */
|
||||
}
|
||||
|
||||
|
||||
/* 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,21 +788,26 @@
|
|||
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 );
|
||||
|
@ -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,37 +852,43 @@
|
|||
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;
|
||||
|
||||
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,12 +969,16 @@
|
|||
|
||||
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;
|
||||
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 );
|
||||
|
@ -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 );
|
||||
|
||||
for ( ; num_glyphs > 0; num_glyphs-- )
|
||||
if ( OTL_NEXT_USHORT( p ) >= glyph_count )
|
||||
OTL_INVALID_DATA;
|
||||
|
||||
/* XXX: check glyph indices */
|
||||
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 );
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ OTL_BEGIN_HEADER
|
|||
|
||||
OTL_LOCAL( void )
|
||||
otl_gsub_validate( OTL_Bytes table,
|
||||
OTL_UInt glyph_count,
|
||||
OTL_Validator valid );
|
||||
|
||||
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue