summaryrefslogtreecommitdiff
path: root/src/freetype2/otvalid
diff options
context:
space:
mode:
authorscuri <scuri>2009-10-20 17:20:18 +0000
committerscuri <scuri>2009-10-20 17:20:18 +0000
commit27a4f9c4ac45ff65f941964f7351b64b1e6a9f35 (patch)
tree2f68c5d9ce5bf6cbc320ac17aef0a65a3ceb99a1 /src/freetype2/otvalid
parent2b70507615b2611fce4294c65bec7264644e2665 (diff)
*** empty log message ***
Diffstat (limited to 'src/freetype2/otvalid')
-rw-r--r--src/freetype2/otvalid/otvalid.c3
-rw-r--r--src/freetype2/otvalid/otvalid.h8
-rw-r--r--src/freetype2/otvalid/otvbase.c6
-rw-r--r--src/freetype2/otvalid/otvcommn.c65
-rw-r--r--src/freetype2/otvalid/otvcommn.h57
-rw-r--r--src/freetype2/otvalid/otvgdef.c11
-rw-r--r--src/freetype2/otvalid/otvgpos.c52
-rw-r--r--src/freetype2/otvalid/otvgsub.c35
-rw-r--r--src/freetype2/otvalid/otvjstf.c4
-rw-r--r--src/freetype2/otvalid/otvmath.c452
-rw-r--r--src/freetype2/otvalid/otvmod.c52
-rw-r--r--src/freetype2/otvalid/otvmod.h4
12 files changed, 646 insertions, 103 deletions
diff --git a/src/freetype2/otvalid/otvalid.c b/src/freetype2/otvalid/otvalid.c
index 2f85f60..d5c2b75 100644
--- a/src/freetype2/otvalid/otvalid.c
+++ b/src/freetype2/otvalid/otvalid.c
@@ -4,7 +4,7 @@
/* */
/* FreeType validator for OpenType tables (body only). */
/* */
-/* Copyright 2004 by */
+/* Copyright 2004, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -25,6 +25,7 @@
#include "otvgpos.c"
#include "otvgsub.c"
#include "otvjstf.c"
+#include "otvmath.c"
#include "otvmod.c"
/* END */
diff --git a/src/freetype2/otvalid/otvalid.h b/src/freetype2/otvalid/otvalid.h
index 38f030f..eb99b9c 100644
--- a/src/freetype2/otvalid/otvalid.h
+++ b/src/freetype2/otvalid/otvalid.h
@@ -4,7 +4,7 @@
/* */
/* OpenType table validation (specification only). */
/* */
-/* Copyright 2004 by */
+/* Copyright 2004, 2008 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -42,6 +42,7 @@ FT_BEGIN_HEADER
otv_GDEF_validate( FT_Bytes table,
FT_Bytes gsub,
FT_Bytes gpos,
+ FT_UInt glyph_count,
FT_Validator valid );
FT_LOCAL( void )
@@ -63,6 +64,11 @@ FT_BEGIN_HEADER
FT_UInt glyph_count,
FT_Validator valid );
+ FT_LOCAL( void )
+ otv_MATH_validate( FT_Bytes table,
+ FT_UInt glyph_count,
+ FT_Validator ftvalid );
+
FT_END_HEADER
diff --git a/src/freetype2/otvalid/otvbase.c b/src/freetype2/otvalid/otvbase.c
index 8ad2238..d742d2d 100644
--- a/src/freetype2/otvalid/otvbase.c
+++ b/src/freetype2/otvalid/otvbase.c
@@ -4,7 +4,7 @@
/* */
/* OpenType BASE table validation (body). */
/* */
-/* Copyright 2004 by */
+/* Copyright 2004, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -62,7 +62,7 @@
break;
default:
- FT_INVALID_DATA;
+ FT_INVALID_FORMAT;
}
OTV_EXIT;
@@ -297,7 +297,7 @@
OTV_LIMIT_CHECK( 6 );
if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */
- FT_INVALID_DATA;
+ FT_INVALID_FORMAT;
table_size = 6;
diff --git a/src/freetype2/otvalid/otvcommn.c b/src/freetype2/otvalid/otvcommn.c
index d94e4f3..a4f885b 100644
--- a/src/freetype2/otvalid/otvcommn.c
+++ b/src/freetype2/otvalid/otvcommn.c
@@ -4,7 +4,7 @@
/* */
/* OpenType common tables validation (body). */
/* */
-/* Copyright 2004, 2005, 2006 by */
+/* Copyright 2004, 2005, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -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;
}
}
@@ -291,7 +318,10 @@
EndSize = FT_NEXT_USHORT( p );
DeltaFormat = FT_NEXT_USHORT( p );
- if ( DeltaFormat < 1 || DeltaFormat > 3 || EndSize < StartSize )
+ if ( DeltaFormat < 1 || DeltaFormat > 3 )
+ FT_INVALID_FORMAT;
+
+ if ( EndSize < StartSize )
FT_INVALID_DATA;
count = EndSize - StartSize + 1;
@@ -330,7 +360,7 @@
OTV_TRACE(( " (type %d)\n", LookupType ));
- if ( LookupType == 0 || LookupType >= valid->type_count )
+ if ( LookupType == 0 || LookupType > valid->type_count )
FT_INVALID_DATA;
validate = valid->type_funcs[LookupType - 1];
@@ -657,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 );
@@ -729,6 +759,7 @@
FT_INVALID_DATA;
OTV_LIMIT_CHECK( ( Count1 - 1 ) * 2 + Count2 * 4 );
+ p += ( Count1 - 1 ) * 2;
for ( ; Count2 > 0; Count2-- )
{
@@ -824,7 +855,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 );
@@ -872,7 +903,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-- )
{
@@ -913,7 +944,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 );
@@ -963,7 +994,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 );
@@ -972,7 +1003,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 );
@@ -981,7 +1012,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 );
diff --git a/src/freetype2/otvalid/otvcommn.h b/src/freetype2/otvalid/otvcommn.h
index be6ac69..898887f 100644
--- a/src/freetype2/otvalid/otvcommn.h
+++ b/src/freetype2/otvalid/otvcommn.h
@@ -4,7 +4,7 @@
/* */
/* OpenType common tables validation (specification). */
/* */
-/* Copyright 2004, 2005 by */
+/* Copyright 2004, 2005, 2007, 2009 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -85,27 +85,27 @@ FT_BEGIN_HEADER
FT_INVALID_TOO_SHORT; \
FT_END_STMNT
-#define OTV_SIZE_CHECK( _size ) \
- FT_BEGIN_STMNT \
- if ( _size > 0 && _size < table_size ) \
- { \
- if ( valid->root->level == FT_VALIDATE_PARANOID ) \
- FT_INVALID_OFFSET; \
- else \
- { \
- /* strip off `const' */ \
- FT_Byte* pp = (FT_Byte*)_size ## _p; \
- \
- \
- FT_TRACE3(( "\n" \
- "Invalid offset to optional table `%s'!\n" \
- "Set to zero.\n" \
- "\n", #_size )); \
- \
- /* always assume 16bit entities */ \
- _size = pp[0] = pp[1] = 0; \
- } \
- } \
+#define OTV_SIZE_CHECK( _size ) \
+ FT_BEGIN_STMNT \
+ if ( _size > 0 && _size < table_size ) \
+ { \
+ if ( valid->root->level == FT_VALIDATE_PARANOID ) \
+ FT_INVALID_OFFSET; \
+ else \
+ { \
+ /* strip off `const' */ \
+ FT_Byte* pp = (FT_Byte*)_size ## _p; \
+ \
+ \
+ FT_TRACE3(( "\n" \
+ "Invalid offset to optional table `%s'" \
+ " set to zero.\n" \
+ "\n", #_size )); \
+ \
+ /* always assume 16bit entities */ \
+ _size = pp[0] = pp[1] = 0; \
+ } \
+ } \
FT_END_STMNT
@@ -192,12 +192,12 @@ FT_BEGIN_HEADER
valid->func[2] = OTV_FUNC( z ); \
FT_END_STMNT
-#define OTV_INIT do ; while ( 0 )
-#define OTV_ENTER do ; while ( 0 )
-#define OTV_NAME_ENTER( name ) do ; while ( 0 )
-#define OTV_EXIT do ; while ( 0 )
+#define OTV_INIT do { } while ( 0 )
+#define OTV_ENTER do { } while ( 0 )
+#define OTV_NAME_ENTER( name ) do { } while ( 0 )
+#define OTV_EXIT do { } while ( 0 )
-#define OTV_TRACE( s ) do ; while ( 0 )
+#define OTV_TRACE( s ) do { } while ( 0 )
#endif /* !FT_DEBUG_LEVEL_TRACE */
@@ -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 )
diff --git a/src/freetype2/otvalid/otvgdef.c b/src/freetype2/otvalid/otvgdef.c
index 7d24902..3633ad0 100644
--- a/src/freetype2/otvalid/otvgdef.c
+++ b/src/freetype2/otvalid/otvgdef.c
@@ -4,7 +4,7 @@
/* */
/* OpenType GDEF table validation (body). */
/* */
-/* 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, */
@@ -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;
@@ -126,7 +126,7 @@
break;
default:
- FT_INVALID_DATA;
+ FT_INVALID_FORMAT;
}
OTV_EXIT;
@@ -141,10 +141,13 @@
/*************************************************************************/
/*************************************************************************/
+ /* sets valid->glyph_count */
+
FT_LOCAL_DEF( void )
otv_GDEF_validate( FT_Bytes table,
FT_Bytes gsub,
FT_Bytes gpos,
+ FT_UInt glyph_count,
FT_Validator ftvalid )
{
OTV_ValidatorRec validrec;
@@ -183,6 +186,8 @@
else
table_size = 10; /* OpenType < 1.2 */
+ valid->glyph_count = glyph_count;
+
OTV_OPTIONAL_OFFSET( GlyphClassDef );
OTV_SIZE_CHECK( GlyphClassDef );
if ( GlyphClassDef )
diff --git a/src/freetype2/otvalid/otvgpos.c b/src/freetype2/otvalid/otvgpos.c
index ed34705..49b4618 100644
--- a/src/freetype2/otvalid/otvgpos.c
+++ b/src/freetype2/otvalid/otvgpos.c
@@ -4,7 +4,7 @@
/* */
/* OpenType GPOS table validation (body). */
/* */
-/* Copyright 2002, 2004, 2005, 2006 by */
+/* Copyright 2002, 2004, 2005, 2006, 2007, 2008 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -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 );
@@ -191,7 +191,7 @@
#endif
if ( format >= 0x100 )
- FT_INVALID_DATA;
+ FT_INVALID_FORMAT;
for ( count = 4; count > 0; count-- )
{
@@ -209,7 +209,7 @@
{
if ( format & 1 )
{
- FT_UInt table_size;
+ FT_PtrDist table_size;
OTV_OPTIONAL_TABLE( device );
@@ -294,7 +294,7 @@
break;
default:
- FT_INVALID_DATA;
+ FT_INVALID_FORMAT;
}
OTV_EXIT;
@@ -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 );
@@ -409,7 +409,7 @@
break;
default:
- FT_INVALID_DATA;
+ FT_INVALID_FORMAT;
}
OTV_EXIT;
@@ -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 );
@@ -558,7 +558,7 @@
break;
default:
- FT_INVALID_DATA;
+ FT_INVALID_FORMAT;
}
OTV_EXIT;
@@ -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 );
@@ -629,7 +629,7 @@
break;
default:
- FT_INVALID_DATA;
+ FT_INVALID_FORMAT;
}
OTV_EXIT;
@@ -644,7 +644,10 @@
/*************************************************************************/
/*************************************************************************/
- /* sets valid->extra2 (0) */
+ /* UNDOCUMENTED (in OpenType 1.5): */
+ /* BaseRecord tables can contain NULL pointers. */
+
+ /* sets valid->extra2 (1) */
static void
otv_MarkBasePos_validate( FT_Bytes table,
@@ -664,13 +667,13 @@
switch ( PosFormat )
{
case 1:
- valid->extra2 = 0;
+ valid->extra2 = 1;
OTV_NEST2( MarkBasePosFormat1, BaseArray );
OTV_RUN( table, valid );
break;
default:
- FT_INVALID_DATA;
+ FT_INVALID_FORMAT;
}
OTV_EXIT;
@@ -711,7 +714,7 @@
break;
default:
- FT_INVALID_DATA;
+ FT_INVALID_FORMAT;
}
OTV_EXIT;
@@ -752,7 +755,7 @@
break;
default:
- FT_INVALID_DATA;
+ FT_INVALID_FORMAT;
}
OTV_EXIT;
@@ -811,7 +814,7 @@
break;
default:
- FT_INVALID_DATA;
+ FT_INVALID_FORMAT;
}
OTV_EXIT;
@@ -872,7 +875,7 @@
break;
default:
- FT_INVALID_DATA;
+ FT_INVALID_FORMAT;
}
OTV_EXIT;
@@ -908,7 +911,8 @@
{
case 1: /* ExtensionPosFormat1 */
{
- FT_UInt ExtensionLookupType, ExtensionOffset;
+ FT_UInt ExtensionLookupType;
+ FT_ULong ExtensionOffset;
OTV_Validate_Func validate;
@@ -925,7 +929,7 @@
break;
default:
- FT_INVALID_DATA;
+ FT_INVALID_FORMAT;
}
OTV_EXIT;
@@ -989,7 +993,7 @@
OTV_LIMIT_CHECK( 10 );
if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */
- FT_INVALID_DATA;
+ FT_INVALID_FORMAT;
ScriptList = FT_NEXT_USHORT( p );
FeatureList = FT_NEXT_USHORT( p );
diff --git a/src/freetype2/otvalid/otvgsub.c b/src/freetype2/otvalid/otvgsub.c
index 91dae0b..ed499d1 100644
--- a/src/freetype2/otvalid/otvgsub.c
+++ b/src/freetype2/otvalid/otvgsub.c
@@ -4,7 +4,7 @@
/* */
/* OpenType GSUB table validation (body). */
/* */
-/* 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, */
@@ -68,7 +68,7 @@
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 )
@@ -91,19 +91,19 @@
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;
default:
- FT_INVALID_DATA;
+ FT_INVALID_FORMAT;
}
OTV_EXIT;
@@ -144,7 +144,7 @@
break;
default:
- FT_INVALID_DATA;
+ FT_INVALID_FORMAT;
}
OTV_EXIT;
@@ -185,7 +185,7 @@
break;
default:
- FT_INVALID_DATA;
+ FT_INVALID_FORMAT;
}
OTV_EXIT;
@@ -259,7 +259,7 @@
break;
default:
- FT_INVALID_DATA;
+ FT_INVALID_FORMAT;
}
OTV_EXIT;
@@ -318,7 +318,7 @@
break;
default:
- FT_INVALID_DATA;
+ FT_INVALID_FORMAT;
}
OTV_EXIT;
@@ -379,7 +379,7 @@
break;
default:
- FT_INVALID_DATA;
+ FT_INVALID_FORMAT;
}
OTV_EXIT;
@@ -415,7 +415,8 @@
{
case 1: /* ExtensionSubstFormat1 */
{
- FT_UInt ExtensionLookupType, ExtensionOffset;
+ FT_UInt ExtensionLookupType;
+ FT_ULong ExtensionOffset;
OTV_Validate_Func validate;
@@ -434,7 +435,7 @@
break;
default:
- FT_INVALID_DATA;
+ FT_INVALID_FORMAT;
}
OTV_EXIT;
@@ -476,12 +477,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 +491,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 );
@@ -509,7 +510,7 @@
break;
default:
- FT_INVALID_DATA;
+ FT_INVALID_FORMAT;
}
OTV_EXIT;
@@ -560,7 +561,7 @@
OTV_LIMIT_CHECK( 10 );
if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */
- FT_INVALID_DATA;
+ FT_INVALID_FORMAT;
ScriptList = FT_NEXT_USHORT( p );
FeatureList = FT_NEXT_USHORT( p );
diff --git a/src/freetype2/otvalid/otvjstf.c b/src/freetype2/otvalid/otvjstf.c
index 80b8dd6..a616a23 100644
--- a/src/freetype2/otvalid/otvjstf.c
+++ b/src/freetype2/otvalid/otvjstf.c
@@ -4,7 +4,7 @@
/* */
/* OpenType JSTF table validation (body). */
/* */
-/* Copyright 2004 by */
+/* Copyright 2004, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -222,7 +222,7 @@
OTV_LIMIT_CHECK( 6 );
if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */
- FT_INVALID_DATA;
+ FT_INVALID_FORMAT;
JstfScriptCount = FT_NEXT_USHORT( p );
diff --git a/src/freetype2/otvalid/otvmath.c b/src/freetype2/otvalid/otvmath.c
new file mode 100644
index 0000000..50ed10c
--- /dev/null
+++ b/src/freetype2/otvalid/otvmath.c
@@ -0,0 +1,452 @@
+/***************************************************************************/
+/* */
+/* otvmath.c */
+/* */
+/* OpenType MATH table validation (body). */
+/* */
+/* Copyright 2007, 2008 by */
+/* David Turner, Robert Wilhelm, and Werner Lemberg. */
+/* */
+/* Written by George Williams. */
+/* */
+/* This file is part of the FreeType project, and may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+
+#include "otvalid.h"
+#include "otvcommn.h"
+#include "otvgpos.h"
+
+
+ /*************************************************************************/
+ /* */
+ /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
+ /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
+ /* messages during execution. */
+ /* */
+#undef FT_COMPONENT
+#define FT_COMPONENT trace_otvmath
+
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+ /***** MATH TYPOGRAPHIC CONSTANTS *****/
+ /***** *****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ static void
+ otv_MathConstants_validate( FT_Bytes table,
+ OTV_Validator valid )
+ {
+ FT_Bytes p = table;
+ FT_UInt i;
+ FT_UInt table_size;
+
+ OTV_OPTIONAL_TABLE( DeviceTableOffset );
+
+
+ OTV_NAME_ENTER( "MathConstants" );
+
+ /* 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 < 51; ++i )
+ {
+ p += 2; /* skip the value */
+ OTV_OPTIONAL_OFFSET( DeviceTableOffset );
+ OTV_SIZE_CHECK( DeviceTableOffset );
+ if ( DeviceTableOffset )
+ otv_Device_validate( table + DeviceTableOffset, valid );
+ }
+
+ OTV_EXIT;
+ }
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+ /***** MATH ITALICS CORRECTION *****/
+ /***** MATH TOP ACCENT ATTACHMENT *****/
+ /***** *****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ static void
+ otv_MathItalicsCorrectionInfo_validate( FT_Bytes table,
+ OTV_Validator valid,
+ FT_Int isItalic )
+ {
+ FT_Bytes p = table;
+ FT_UInt i, cnt, table_size ;
+
+ OTV_OPTIONAL_TABLE( Coverage );
+ OTV_OPTIONAL_TABLE( DeviceTableOffset );
+
+ FT_UNUSED( isItalic ); /* only used if tracing is active */
+
+
+ OTV_NAME_ENTER( isItalic ? "MathItalicsCorrectionInfo"
+ : "MathTopAccentAttachment" );
+
+ OTV_LIMIT_CHECK( 4 );
+
+ OTV_OPTIONAL_OFFSET( Coverage );
+ cnt = FT_NEXT_USHORT( p );
+
+ OTV_LIMIT_CHECK( 4 * cnt );
+ table_size = 4 + 4 * cnt;
+
+ OTV_SIZE_CHECK( Coverage );
+ otv_Coverage_validate( table + Coverage, valid, cnt );
+
+ for ( i = 0; i < cnt; ++i )
+ {
+ p += 2; /* Skip the value */
+ OTV_OPTIONAL_OFFSET( DeviceTableOffset );
+ OTV_SIZE_CHECK( DeviceTableOffset );
+ if ( DeviceTableOffset )
+ otv_Device_validate( table + DeviceTableOffset, valid );
+ }
+
+ OTV_EXIT;
+ }
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+ /***** MATH KERNING *****/
+ /***** *****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ static void
+ otv_MathKern_validate( FT_Bytes table,
+ OTV_Validator valid )
+ {
+ FT_Bytes p = table;
+ FT_UInt i, cnt, table_size;
+
+ OTV_OPTIONAL_TABLE( DeviceTableOffset );
+
+
+ /* OTV_NAME_ENTER( "MathKern" );*/
+
+ OTV_LIMIT_CHECK( 2 );
+
+ cnt = FT_NEXT_USHORT( p );
+
+ OTV_LIMIT_CHECK( 4 * cnt + 2 );
+ table_size = 4 + 4 * cnt;
+
+ /* Heights */
+ for ( i = 0; i < cnt; ++i )
+ {
+ p += 2; /* Skip the value */
+ OTV_OPTIONAL_OFFSET( DeviceTableOffset );
+ OTV_SIZE_CHECK( DeviceTableOffset );
+ if ( DeviceTableOffset )
+ otv_Device_validate( table + DeviceTableOffset, valid );
+ }
+
+ /* One more Kerning value */
+ for ( i = 0; i < cnt + 1; ++i )
+ {
+ p += 2; /* Skip the value */
+ OTV_OPTIONAL_OFFSET( DeviceTableOffset );
+ OTV_SIZE_CHECK( DeviceTableOffset );
+ if ( DeviceTableOffset )
+ otv_Device_validate( table + DeviceTableOffset, valid );
+ }
+
+ OTV_EXIT;
+ }
+
+
+ static void
+ otv_MathKernInfo_validate( FT_Bytes table,
+ OTV_Validator valid )
+ {
+ FT_Bytes p = table;
+ FT_UInt i, j, cnt, table_size;
+
+ OTV_OPTIONAL_TABLE( Coverage );
+ OTV_OPTIONAL_TABLE( MKRecordOffset );
+
+
+ OTV_NAME_ENTER( "MathKernInfo" );
+
+ OTV_LIMIT_CHECK( 4 );
+
+ OTV_OPTIONAL_OFFSET( Coverage );
+ cnt = FT_NEXT_USHORT( p );
+
+ OTV_LIMIT_CHECK( 8 * cnt );
+ table_size = 4 + 8 * cnt;
+
+ OTV_SIZE_CHECK( Coverage );
+ otv_Coverage_validate( table + Coverage, valid, cnt );
+
+ for ( i = 0; i < cnt; ++i )
+ {
+ for ( j = 0; j < 4; ++j )
+ {
+ OTV_OPTIONAL_OFFSET( MKRecordOffset );
+ OTV_SIZE_CHECK( MKRecordOffset );
+ if ( MKRecordOffset )
+ otv_MathKern_validate( table + MKRecordOffset, valid );
+ }
+ }
+
+ OTV_EXIT;
+ }
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+ /***** MATH GLYPH INFO *****/
+ /***** *****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ static void
+ otv_MathGlyphInfo_validate( FT_Bytes table,
+ OTV_Validator valid )
+ {
+ FT_Bytes p = table;
+ FT_UInt MathItalicsCorrectionInfo, MathTopAccentAttachment;
+ FT_UInt ExtendedShapeCoverage, MathKernInfo;
+
+
+ OTV_NAME_ENTER( "MathGlyphInfo" );
+
+ OTV_LIMIT_CHECK( 8 );
+
+ MathItalicsCorrectionInfo = FT_NEXT_USHORT( p );
+ MathTopAccentAttachment = FT_NEXT_USHORT( p );
+ ExtendedShapeCoverage = FT_NEXT_USHORT( p );
+ MathKernInfo = FT_NEXT_USHORT( p );
+
+ if ( MathItalicsCorrectionInfo )
+ otv_MathItalicsCorrectionInfo_validate(
+ table + MathItalicsCorrectionInfo, valid, TRUE );
+
+ /* Italic correction and Top Accent Attachment have the same format */
+ if ( MathTopAccentAttachment )
+ otv_MathItalicsCorrectionInfo_validate(
+ table + MathTopAccentAttachment, valid, FALSE );
+
+ if ( ExtendedShapeCoverage ) {
+ OTV_NAME_ENTER( "ExtendedShapeCoverage" );
+ otv_Coverage_validate( table + ExtendedShapeCoverage, valid, -1 );
+ OTV_EXIT;
+ }
+
+ if ( MathKernInfo )
+ otv_MathKernInfo_validate( table + MathKernInfo, valid );
+
+ OTV_EXIT;
+ }
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+ /***** MATH GLYPH CONSTRUCTION *****/
+ /***** *****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ static void
+ otv_GlyphAssembly_validate( FT_Bytes table,
+ OTV_Validator valid )
+ {
+ FT_Bytes p = table;
+ FT_UInt pcnt, table_size;
+ FT_UInt i;
+
+ OTV_OPTIONAL_TABLE( DeviceTableOffset );
+
+
+ /* OTV_NAME_ENTER( "GlyphAssembly" ); */
+
+ OTV_LIMIT_CHECK( 6 );
+
+ p += 2; /* Skip the Italics Correction value */
+ OTV_OPTIONAL_OFFSET( DeviceTableOffset );
+ pcnt = FT_NEXT_USHORT( p );
+
+ OTV_LIMIT_CHECK( 8 * pcnt );
+ table_size = 6 + 8 * pcnt;
+
+ OTV_SIZE_CHECK( DeviceTableOffset );
+ 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; */
+ }
+
+
+ static void
+ otv_MathGlyphConstruction_validate( FT_Bytes table,
+ OTV_Validator valid )
+ {
+ FT_Bytes p = table;
+ FT_UInt vcnt, table_size;
+ FT_UInt i;
+
+ OTV_OPTIONAL_TABLE( GlyphAssembly );
+
+
+ /* OTV_NAME_ENTER( "MathGlyphConstruction" ); */
+
+ OTV_LIMIT_CHECK( 4 );
+
+ OTV_OPTIONAL_OFFSET( GlyphAssembly );
+ vcnt = FT_NEXT_USHORT( p );
+
+ 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 );
+
+ /* OTV_EXIT; */
+ }
+
+
+ static void
+ otv_MathVariants_validate( FT_Bytes table,
+ OTV_Validator valid )
+ {
+ FT_Bytes p = table;
+ FT_UInt vcnt, hcnt, i, table_size;
+
+ OTV_OPTIONAL_TABLE( VCoverage );
+ OTV_OPTIONAL_TABLE( HCoverage );
+ OTV_OPTIONAL_TABLE( Offset );
+
+
+ OTV_NAME_ENTER( "MathVariants" );
+
+ OTV_LIMIT_CHECK( 10 );
+
+ p += 2; /* Skip the MinConnectorOverlap constant */
+ OTV_OPTIONAL_OFFSET( VCoverage );
+ OTV_OPTIONAL_OFFSET( HCoverage );
+ vcnt = FT_NEXT_USHORT( p );
+ hcnt = FT_NEXT_USHORT( p );
+
+ OTV_LIMIT_CHECK( 2 * vcnt + 2 * hcnt );
+ table_size = 10 + 2 * vcnt + 2 * hcnt;
+
+ OTV_SIZE_CHECK( VCoverage );
+ if ( VCoverage )
+ otv_Coverage_validate( table + VCoverage, valid, vcnt );
+
+ OTV_SIZE_CHECK( HCoverage );
+ if ( HCoverage )
+ otv_Coverage_validate( table + HCoverage, valid, hcnt );
+
+ for ( i = 0; i < vcnt; ++i )
+ {
+ OTV_OPTIONAL_OFFSET( Offset );
+ OTV_SIZE_CHECK( Offset );
+ otv_MathGlyphConstruction_validate( table + Offset, valid );
+ }
+
+ for ( i = 0; i < hcnt; ++i )
+ {
+ OTV_OPTIONAL_OFFSET( Offset );
+ OTV_SIZE_CHECK( Offset );
+ otv_MathGlyphConstruction_validate( table + Offset, valid );
+ }
+
+ OTV_EXIT;
+ }
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+ /***** MATH TABLE *****/
+ /***** *****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ /* sets valid->glyph_count */
+
+ FT_LOCAL_DEF( void )
+ otv_MATH_validate( FT_Bytes table,
+ FT_UInt glyph_count,
+ FT_Validator ftvalid )
+ {
+ OTV_ValidatorRec validrec;
+ OTV_Validator valid = &validrec;
+ FT_Bytes p = table;
+ FT_UInt MathConstants, MathGlyphInfo, MathVariants;
+
+
+ valid->root = ftvalid;
+
+ FT_TRACE3(( "validating MATH table\n" ));
+ OTV_INIT;
+
+ OTV_LIMIT_CHECK( 10 );
+
+ if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */
+ FT_INVALID_FORMAT;
+
+ MathConstants = FT_NEXT_USHORT( p );
+ MathGlyphInfo = FT_NEXT_USHORT( p );
+ MathVariants = FT_NEXT_USHORT( p );
+
+ valid->glyph_count = glyph_count;
+
+ otv_MathConstants_validate( table + MathConstants,
+ valid );
+ otv_MathGlyphInfo_validate( table + MathGlyphInfo,
+ valid );
+ otv_MathVariants_validate ( table + MathVariants,
+ valid );
+
+ FT_TRACE4(( "\n" ));
+ }
+
+
+/* END */
diff --git a/src/freetype2/otvalid/otvmod.c b/src/freetype2/otvalid/otvmod.c
index 157272f..3248564 100644
--- a/src/freetype2/otvalid/otvmod.c
+++ b/src/freetype2/otvalid/otvmod.c
@@ -4,7 +4,7 @@
/* */
/* FreeType's OpenType validation module implementation (body). */
/* */
-/* Copyright 2004, 2005, 2006 by */
+/* Copyright 2004, 2005, 2006, 2007, 2008 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -79,12 +79,27 @@
FT_Byte* volatile gpos;
FT_Byte* volatile gsub;
FT_Byte* volatile jstf;
+ FT_Byte* volatile math;
FT_ULong len_base, len_gdef, len_gpos, len_gsub, len_jstf;
+ FT_ULong len_math;
+ FT_UInt num_glyphs = (FT_UInt)face->num_glyphs;
FT_ValidatorRec volatile valid;
- base = gdef = gpos = gsub = jstf = NULL;
- len_base = len_gdef = len_gpos = len_gsub = len_jstf = 0;
+ base = gdef = gpos = gsub = jstf = math = NULL;
+ len_base = len_gdef = len_gpos = len_gsub = len_jstf = len_math = 0;
+
+ /*
+ * XXX: OpenType tables cannot handle 32-bit glyph index,
+ * although broken TrueType can have 32-bit glyph index.
+ */
+ if ( face->num_glyphs > 0xFFFFL )
+ {
+ FT_TRACE1(( "otv_validate: Invalid glyphs index (0x0000FFFF - 0x%08x) ",
+ face->num_glyphs ));
+ FT_TRACE1(( "are not handled by OpenType tables\n" ));
+ num_glyphs = 0xFFFF;
+ }
/* load tables */
@@ -123,6 +138,13 @@
goto Exit;
}
+ if ( ot_flags & FT_VALIDATE_MATH )
+ {
+ error = otv_load_table( face, TTAG_MATH, &math, &len_math );
+ if ( error )
+ goto Exit;
+ }
+
/* validate tables */
if ( base )
@@ -139,7 +161,7 @@
{
ft_validator_init( &valid, gpos, gpos + len_gpos, FT_VALIDATE_DEFAULT );
if ( ft_setjmp( valid.jump_buffer ) == 0 )
- otv_GPOS_validate( gpos, face->num_glyphs, &valid );
+ otv_GPOS_validate( gpos, num_glyphs, &valid );
error = valid.error;
if ( error )
goto Exit;
@@ -149,7 +171,7 @@
{
ft_validator_init( &valid, gsub, gsub + len_gsub, FT_VALIDATE_DEFAULT );
if ( ft_setjmp( valid.jump_buffer ) == 0 )
- otv_GSUB_validate( gsub, face->num_glyphs, &valid );
+ otv_GSUB_validate( gsub, num_glyphs, &valid );
error = valid.error;
if ( error )
goto Exit;
@@ -159,7 +181,7 @@
{
ft_validator_init( &valid, gdef, gdef + len_gdef, FT_VALIDATE_DEFAULT );
if ( ft_setjmp( valid.jump_buffer ) == 0 )
- otv_GDEF_validate( gdef, gsub, gpos, &valid );
+ otv_GDEF_validate( gdef, gsub, gpos, num_glyphs, &valid );
error = valid.error;
if ( error )
goto Exit;
@@ -169,7 +191,17 @@
{
ft_validator_init( &valid, jstf, jstf + len_jstf, FT_VALIDATE_DEFAULT );
if ( ft_setjmp( valid.jump_buffer ) == 0 )
- otv_JSTF_validate( jstf, gsub, gpos, face->num_glyphs, &valid );
+ otv_JSTF_validate( jstf, gsub, gpos, num_glyphs, &valid );
+ error = valid.error;
+ if ( error )
+ goto Exit;
+ }
+
+ if ( math )
+ {
+ ft_validator_init( &valid, math, math + len_math, FT_VALIDATE_DEFAULT );
+ if ( ft_setjmp( valid.jump_buffer ) == 0 )
+ otv_MATH_validate( math, num_glyphs, &valid );
error = valid.error;
if ( error )
goto Exit;
@@ -192,6 +224,12 @@
FT_FREE( gsub );
FT_FREE( jstf );
}
+ {
+ FT_Memory memory = FT_FACE_MEMORY( face );
+
+
+ FT_FREE( math ); /* Can't return this as API is frozen */
+ }
return error;
}
diff --git a/src/freetype2/otvalid/otvmod.h b/src/freetype2/otvalid/otvmod.h
index 1bfc189..573b2a0 100644
--- a/src/freetype2/otvalid/otvmod.h
+++ b/src/freetype2/otvalid/otvmod.h
@@ -27,6 +27,10 @@
FT_BEGIN_HEADER
+#ifdef FT_CONFIG_OPTION_PIC
+#error "this module does not support PIC yet"
+#endif
+
FT_EXPORT_VAR( const FT_Module_Class ) otv_module_class;