diff --git a/src/ftxgpos.c b/src/ftxgpos.c index e2a71ed44..a3d163ea5 100644 --- a/src/ftxgpos.c +++ b/src/ftxgpos.c @@ -5872,8 +5872,8 @@ FT_UShort context_length, int nesting_level ) { - FT_Error error = TT_Err_Ok; - FT_UShort i, flags; + FT_Error error = TTO_Err_Not_Covered; + FT_UShort i, flags, lookup_count; TTO_GPOSHeader* gpos = gpi->gpos; TTO_Lookup* lo; @@ -5883,6 +5883,10 @@ if ( nesting_level > TTO_MAX_NESTING_LEVEL ) return TTO_Err_Too_Many_Nested_Contexts; + lookup_count = gpos->LookupList.LookupCount; + if (lookup_index >= lookup_count) + return error; + lo = &gpos->LookupList.Lookup[lookup_index]; flags = lo->LookupFlag; @@ -6049,8 +6053,9 @@ TTO_Feature feature; FT_UInt* properties; FT_UShort* index; + FT_UShort lookup_count; - /* Each feature can only be added once once */ + /* Each feature can only be added once */ if ( !gpos || feature_index >= gpos->FeatureList.FeatureCount || @@ -6063,9 +6068,14 @@ feature = gpos->FeatureList.FeatureRecord[feature_index].Feature; index = feature.LookupListIndex; + lookup_count = gpos->LookupList.LookupCount; for ( i = 0; i < feature.LookupListCount; i++ ) - properties[index[i]] |= property; + { + FT_UShort lookup_index = index[i]; + if (lookup_index < lookup_count) + properties[lookup_index] |= property; + } return TT_Err_Ok; } @@ -6133,7 +6143,7 @@ { FT_Error error, retError = TTO_Err_Not_Covered; GPOS_Instance gpi; - FT_UShort i, j, feature_index; + FT_UShort i, j, feature_index, lookup_count; TTO_Feature feature; if ( !face || !gpos || @@ -6146,6 +6156,8 @@ gpi.r2l = r2l; gpi.dvi = dvi; + lookup_count = gpos->LookupList.LookupCount; + for ( i = 0; i < gpos->FeatureList.ApplyCount; i++ ) { /* index of i'th feature */ @@ -6154,7 +6166,13 @@ for ( j = 0; j < feature.LookupListCount; j++ ) { - error = Do_String_Lookup( &gpi, feature.LookupListIndex[j], buffer ); + FT_UShort lookup_index = feature.LookupListIndex[j]; + + /* Skip nonexistant lookups */ + if (lookup_index >= lookup_count) + continue; + + error = Do_String_Lookup( &gpi, lookup_index, buffer ); if ( error ) { if ( error != TTO_Err_Not_Covered ) diff --git a/src/ftxgsub.c b/src/ftxgsub.c index 50101c582..6f085ccfe 100644 --- a/src/ftxgsub.c +++ b/src/ftxgsub.c @@ -3939,8 +3939,8 @@ FT_UShort context_length, int nesting_level ) { - FT_Error error = TT_Err_Ok; - FT_UShort i, flags; + FT_Error error = TTO_Err_Not_Covered; + FT_UShort i, flags, lookup_count; TTO_Lookup* lo; @@ -3949,6 +3949,10 @@ if ( nesting_level > TTO_MAX_NESTING_LEVEL ) return TTO_Err_Too_Many_Nested_Contexts; + lookup_count = gsub->LookupList.LookupCount; + if (lookup_index >= lookup_count) + return error; + lo = &gsub->LookupList.Lookup[lookup_index]; flags = lo->LookupFlag; @@ -4056,8 +4060,9 @@ TTO_Feature feature; FT_UInt* properties; FT_UShort* index; + FT_UShort lookup_count; - /* Each feature can only be added once once */ + /* Each feature can only be added once */ if ( !gsub || feature_index >= gsub->FeatureList.FeatureCount || @@ -4070,9 +4075,14 @@ feature = gsub->FeatureList.FeatureRecord[feature_index].Feature; index = feature.LookupListIndex; + lookup_count = gsub->LookupList.LookupCount; for ( i = 0; i < feature.LookupListCount; i++ ) - properties[index[i]] |= property; + { + FT_UShort lookup_index = index[i]; + if (lookup_index < lookup_count) + properties[lookup_index] |= property; + } return TT_Err_Ok; } @@ -4120,13 +4130,15 @@ OTL_Buffer buffer ) { FT_Error error, retError = TTO_Err_Not_Covered; - FT_UShort i, j, feature_index; + FT_UShort i, j, feature_index, lookup_count; TTO_Feature feature; if ( !gsub || !buffer || buffer->in_length == 0 || buffer->in_pos >= buffer->in_length ) return TT_Err_Invalid_Argument; + lookup_count = gsub->LookupList.LookupCount; + for ( i = 0; i < gsub->FeatureList.ApplyCount; i++) { feature_index = gsub->FeatureList.ApplyOrder[i]; @@ -4134,7 +4146,13 @@ for ( j = 0; j < feature.LookupListCount; j++ ) { - error = Do_String_Lookup( gsub, feature.LookupListIndex[j], buffer ); + FT_UShort lookup_index = feature.LookupListIndex[j]; + + /* Skip nonexistant lookups */ + if (lookup_index >= lookup_count) + continue; + + error = Do_String_Lookup( gsub, lookup_index, buffer ); if ( error ) { if ( error != TTO_Err_Not_Covered )