* src/otvalid/otvcommn.c, src/otvalid/otvcommn.h

(otv_Coverage_validate): Add fourth argument to pass an expected
count value.  Update all users.
Check glyph IDs.
(otv_ClassDef_validate): Check `StartGlyph'.

* src/otvalid/otvgsub.c (otv_SingleSubst_validate): More glyph ID
checks.

* src/otvalid/otvmath.c (otv_MathConstants_validate): There are only
56 constants.
(otv_GlyphAssembly_validate, otv_MathGlyphConstruction_validate):
Check glyph IDs.
This commit is contained in:
Werner Lemberg 2007-08-11 15:45:32 +00:00
parent d76fe5a1af
commit 3f1905b191
7 changed files with 115 additions and 43 deletions

View File

@ -1,3 +1,19 @@
2007-08-11 George Williams <gww@silcom.com>
* src/otvalid/otvcommn.c, src/otvalid/otvcommn.h
(otv_Coverage_validate): Add fourth argument to pass an expected
count value. Update all users.
Check glyph IDs.
(otv_ClassDef_validate): Check `StartGlyph'.
* src/otvalid/otvgsub.c (otv_SingleSubst_validate): More glyph ID
checks.
* src/otvalid/otvmath.c (otv_MathConstants_validate): There are only
56 constants.
(otv_GlyphAssembly_validate, otv_MathGlyphConstruction_validate):
Check glyph IDs.
2007-08-08 Werner Lemberg <wl@gnu.org>
* src/otvalid/otvbase.c, src/otvalid/otvcommn.c,

View File

@ -39,10 +39,12 @@
FT_LOCAL_DEF( void )
otv_Coverage_validate( FT_Bytes table,
OTV_Validator valid )
OTV_Validator valid,
FT_Int expected_count )
{
FT_Bytes p = table;
FT_UInt CoverageFormat;
FT_UInt total = 0;
OTV_NAME_ENTER( "Coverage" );
@ -57,6 +59,7 @@
case 1: /* CoverageFormat1 */
{
FT_UInt GlyphCount;
FT_UInt i;
GlyphCount = FT_NEXT_USHORT( p );
@ -64,13 +67,25 @@
OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
OTV_LIMIT_CHECK( GlyphCount * 2 ); /* GlyphArray */
for ( i = 0; i < GlyphCount; ++i )
{
FT_UInt gid;
gid = FT_NEXT_USHORT( p );
if ( gid >= valid->glyph_count )
FT_INVALID_GLYPH_ID;
}
total = GlyphCount;
}
break;
case 2: /* CoverageFormat2 */
{
FT_UInt n, RangeCount;
FT_UInt Start, End, StartCoverageIndex, total = 0, last = 0;
FT_UInt Start, End, StartCoverageIndex, last = 0;
RangeCount = FT_NEXT_USHORT( p );
@ -89,6 +104,9 @@
if ( Start > End || StartCoverageIndex != total )
FT_INVALID_DATA;
if ( End >= valid->glyph_count )
FT_INVALID_GLYPH_ID;
if ( n > 0 && Start <= last )
FT_INVALID_DATA;
@ -102,8 +120,11 @@
FT_INVALID_FORMAT;
}
/* no need to check glyph indices used as input to coverage tables */
/* since even invalid glyph indices return a meaningful result */
/* Generally, a coverage table offset has an associated count field. */
/* The number of glyphs in the table should match this field. If */
/* there is no associated count, a value of -1 tells us not to check. */
if ( expected_count != -1 && (FT_UInt)expected_count != total )
FT_INVALID_DATA;
OTV_EXIT;
}
@ -215,18 +236,21 @@
{
case 1: /* ClassDefFormat1 */
{
FT_UInt StartGlyph;
FT_UInt GlyphCount;
p += 2; /* skip StartGlyph */
OTV_LIMIT_CHECK( 2 );
OTV_LIMIT_CHECK( 4 );
StartGlyph = FT_NEXT_USHORT( p );
GlyphCount = FT_NEXT_USHORT( p );
OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
OTV_LIMIT_CHECK( GlyphCount * 2 ); /* ClassValueArray */
if ( StartGlyph + GlyphCount - 1 >= valid->glyph_count )
FT_INVALID_GLYPH_ID;
}
break;
@ -252,6 +276,9 @@
if ( Start > End || ( n > 0 && Start <= last ) )
FT_INVALID_DATA;
if ( End >= valid->glyph_count )
FT_INVALID_GLYPH_ID;
last = End;
}
}
@ -660,7 +687,7 @@
OTV_TRACE(( " (Count = %d)\n", Count ));
otv_Coverage_validate( table + Coverage, valid );
otv_Coverage_validate( table + Coverage, valid, Count );
OTV_LIMIT_CHECK( Count * 2 );
@ -827,7 +854,7 @@
OTV_TRACE(( " (ClassSetCount = %d)\n", ClassSetCount ));
otv_Coverage_validate( table + Coverage, valid );
otv_Coverage_validate( table + Coverage, valid, -1 );
otv_ClassDef_validate( table + ClassDef, valid );
OTV_LIMIT_CHECK( ClassSetCount * 2 );
@ -875,7 +902,7 @@
OTV_LIMIT_CHECK( GlyphCount * 2 + Count * 4 );
for ( count1 = GlyphCount; count1 > 0; count1-- )
otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid );
otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
for ( ; Count > 0; Count-- )
{
@ -916,7 +943,7 @@
OTV_TRACE(( " (ChainClassSetCount = %d)\n", ChainClassSetCount ));
otv_Coverage_validate( table + Coverage, valid );
otv_Coverage_validate( table + Coverage, valid, -1 );
otv_ClassDef_validate( table + BacktrackClassDef, valid );
otv_ClassDef_validate( table + InputClassDef, valid );
@ -966,7 +993,7 @@
OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 );
for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- )
otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid );
otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
InputGlyphCount = FT_NEXT_USHORT( p );
@ -975,7 +1002,7 @@
OTV_LIMIT_CHECK( InputGlyphCount * 2 + 2 );
for ( count1 = InputGlyphCount; count1 > 0; count1-- )
otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid );
otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
LookaheadGlyphCount = FT_NEXT_USHORT( p );
@ -984,7 +1011,7 @@
OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 );
for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- )
otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid );
otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
count2 = FT_NEXT_USHORT( p );

View File

@ -4,7 +4,7 @@
/* */
/* OpenType common tables validation (specification). */
/* */
/* Copyright 2004, 2005 by */
/* Copyright 2004, 2005, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -215,7 +215,8 @@ FT_BEGIN_HEADER
FT_LOCAL( void )
otv_Coverage_validate( FT_Bytes table,
OTV_Validator valid );
OTV_Validator valid,
FT_Int expected_count );
/* return first covered glyph */
FT_LOCAL( FT_UInt )

View File

@ -61,7 +61,7 @@
OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
otv_Coverage_validate( Coverage, valid );
otv_Coverage_validate( Coverage, valid, GlyphCount );
if ( GlyphCount != otv_Coverage_get_count( Coverage ) )
FT_INVALID_DATA;

View File

@ -124,8 +124,8 @@
Array1 = FT_NEXT_USHORT( p );
Array2 = FT_NEXT_USHORT( p );
otv_Coverage_validate( table + Coverage1, valid );
otv_Coverage_validate( table + Coverage2, valid );
otv_Coverage_validate( table + Coverage1, valid, -1 );
otv_Coverage_validate( table + Coverage2, valid, -1 );
otv_MarkArray_validate( table + Array1, valid );
@ -376,7 +376,7 @@
Coverage = FT_NEXT_USHORT( p );
ValueFormat = FT_NEXT_USHORT( p );
otv_Coverage_validate( table + Coverage, valid );
otv_Coverage_validate( table + Coverage, valid, -1 );
otv_ValueRecord_validate( p, ValueFormat, valid ); /* Value */
}
break;
@ -395,7 +395,7 @@
len_value = otv_value_length( ValueFormat );
otv_Coverage_validate( table + Coverage, valid );
otv_Coverage_validate( table + Coverage, valid, ValueCount );
OTV_LIMIT_CHECK( ValueCount * len_value );
@ -498,7 +498,7 @@
OTV_TRACE(( " (PairSetCount = %d)\n", PairSetCount ));
otv_Coverage_validate( table + Coverage, valid );
otv_Coverage_validate( table + Coverage, valid, -1 );
OTV_LIMIT_CHECK( PairSetCount * 2 );
@ -530,7 +530,7 @@
len_value1 = otv_value_length( ValueFormat1 );
len_value2 = otv_value_length( ValueFormat2 );
otv_Coverage_validate( table + Coverage, valid );
otv_Coverage_validate( table + Coverage, valid, -1 );
otv_ClassDef_validate( table + ClassDef1, valid );
otv_ClassDef_validate( table + ClassDef2, valid );
@ -605,7 +605,7 @@
OTV_TRACE(( " (EntryExitCount = %d)\n", EntryExitCount ));
otv_Coverage_validate( table + Coverage, valid );
otv_Coverage_validate( table + Coverage, valid, EntryExitCount );
OTV_LIMIT_CHECK( EntryExitCount * 4 );

View File

@ -68,15 +68,19 @@
Coverage = table + FT_NEXT_USHORT( p );
DeltaGlyphID = FT_NEXT_SHORT( p );
otv_Coverage_validate( Coverage, valid );
otv_Coverage_validate( Coverage, valid, -1 );
idx = otv_Coverage_get_first( Coverage ) + DeltaGlyphID;
if ( idx < 0 )
FT_INVALID_DATA;
if ( idx < 0 ||
idx + DeltaGlyphID < 0 ||
(FT_UInt)idx + DeltaGlyphID >= valid->glyph_count )
FT_INVALID_GLYPH_ID;
idx = otv_Coverage_get_last( Coverage ) + DeltaGlyphID;
if ( (FT_UInt)idx >= valid->glyph_count )
FT_INVALID_DATA;
if ( (FT_UInt)idx >= valid->glyph_count ||
idx + DeltaGlyphID < 0 ||
(FT_UInt)idx + DeltaGlyphID >= valid->glyph_count )
FT_INVALID_GLYPH_ID;
}
break;
@ -91,14 +95,14 @@
OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
otv_Coverage_validate( table + Coverage, valid );
otv_Coverage_validate( table + Coverage, valid, GlyphCount );
OTV_LIMIT_CHECK( GlyphCount * 2 );
/* Substitute */
for ( ; GlyphCount > 0; GlyphCount-- )
if ( FT_NEXT_USHORT( p ) >= valid->glyph_count )
FT_INVALID_DATA;
FT_INVALID_GLYPH_ID;
}
break;
@ -476,12 +480,12 @@
OTV_TRACE(( " (BacktrackGlyphCount = %d)\n", BacktrackGlyphCount ));
otv_Coverage_validate( Coverage, valid );
otv_Coverage_validate( Coverage, valid, -1 );
OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 );
for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- )
otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid );
otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
LookaheadGlyphCount = FT_NEXT_USHORT( p );
@ -490,7 +494,7 @@
OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 );
for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- )
otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid );
otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
GlyphCount = FT_NEXT_USHORT( p );

View File

@ -55,12 +55,12 @@
OTV_NAME_ENTER( "MathConstants" );
/* 57 constants, 52 have device tables */
OTV_LIMIT_CHECK( 2 * ( 57 + 52 ) );
table_size = 2 * ( 57 + 52 );
/* 56 constants, 51 have device tables */
OTV_LIMIT_CHECK( 2 * ( 56 + 51 ) );
table_size = 2 * ( 56 + 51 );
p += 4 * 2; /* First 4 constants have no device tables */
for ( i = 0; i < 52; ++i )
for ( i = 0; i < 51; ++i )
{
p += 2; /* skip the value */
OTV_OPTIONAL_OFFSET( DeviceTableOffset );
@ -106,7 +106,7 @@
table_size = 4 + 4 * cnt;
OTV_SIZE_CHECK( Coverage );
otv_Coverage_validate( table + Coverage, valid );
otv_Coverage_validate( table + Coverage, valid, cnt );
for ( i = 0; i < cnt; ++i )
{
@ -194,7 +194,7 @@
table_size = 4 + 8 * cnt;
OTV_SIZE_CHECK( Coverage );
otv_Coverage_validate( table + Coverage, valid );
otv_Coverage_validate( table + Coverage, valid, cnt );
for ( i = 0; i < cnt; ++i )
{
@ -248,7 +248,7 @@
if ( ExtendedShapeCoverage ) {
OTV_NAME_ENTER( "ExtendedShapeCoverage" );
otv_Coverage_validate( table + ExtendedShapeCoverage, valid );
otv_Coverage_validate( table + ExtendedShapeCoverage, valid, -1 );
OTV_EXIT;
}
@ -273,6 +273,7 @@
{
FT_Bytes p = table;
FT_UInt pcnt, table_size;
FT_UInt i;
OTV_OPTIONAL_TABLE( DeviceTableOffset );
@ -292,6 +293,17 @@
if ( DeviceTableOffset )
otv_Device_validate( table + DeviceTableOffset, valid );
for ( i = 0; i < pcnt; ++i )
{
FT_UInt gid;
gid = FT_NEXT_USHORT( p );
if ( gid >= valid->glyph_count )
FT_INVALID_GLYPH_ID;
p += 2*4; /* skip the Start, End, Full, and Flags fields */
}
/* OTV_EXIT; */
}
@ -302,6 +314,7 @@
{
FT_Bytes p = table;
FT_UInt vcnt, table_size;
FT_UInt i;
OTV_OPTIONAL_TABLE( GlyphAssembly );
@ -316,6 +329,17 @@
OTV_LIMIT_CHECK( 4 * vcnt );
table_size = 4 + 4 * vcnt;
for ( i = 0; i < vcnt; ++i )
{
FT_UInt gid;
gid = FT_NEXT_USHORT( p );
if ( gid >= valid->glyph_count )
FT_INVALID_GLYPH_ID;
p += 2; /* skip the size */
}
OTV_SIZE_CHECK( GlyphAssembly );
if ( GlyphAssembly )
otv_GlyphAssembly_validate( table+GlyphAssembly, valid );
@ -351,11 +375,11 @@
OTV_SIZE_CHECK( VCoverage );
if ( VCoverage )
otv_Coverage_validate( table + VCoverage, valid );
otv_Coverage_validate( table + VCoverage, valid, vcnt );
OTV_SIZE_CHECK( HCoverage );
if ( HCoverage )
otv_Coverage_validate( table + HCoverage, valid );
otv_Coverage_validate( table + HCoverage, valid, hcnt );
for ( i = 0; i < vcnt; ++i )
{