summaryrefslogtreecommitdiffstats
path: root/src/sfnt/sfobjs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sfnt/sfobjs.c')
-rw-r--r--src/sfnt/sfobjs.c148
1 files changed, 113 insertions, 35 deletions
diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c
index 40c27fa..de030ea 100644
--- a/src/sfnt/sfobjs.c
+++ b/src/sfnt/sfobjs.c
@@ -120,27 +120,9 @@
FT_Memory memory );
- /*************************************************************************/
- /* */
- /* <Function> */
- /* tt_face_get_name */
- /* */
- /* <Description> */
- /* Returns a given ENGLISH name record in ASCII. */
- /* */
- /* <Input> */
- /* face :: A handle to the source face object. */
- /* */
- /* nameid :: The name id of the name record to return. */
- /* */
- /* <InOut> */
- /* name :: The address of a string pointer. NULL if no name is */
- /* present. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. */
- /* */
- static FT_Error
+ /* documentation is in sfnt.h */
+
+ FT_LOCAL_DEF( FT_Error )
tt_face_get_name( TT_Face face,
FT_UShort nameid,
FT_String** name )
@@ -469,10 +451,14 @@
woff.metaOrigLength != 0 ) ) ||
( woff.metaLength != 0 && woff.metaOrigLength == 0 ) ||
( woff.privOffset == 0 && woff.privLength != 0 ) )
+ {
+ FT_ERROR(( "woff_font_open: invalid WOFF header\n" ));
return FT_THROW( Invalid_Table );
+ }
- if ( FT_ALLOC( sfnt, woff.totalSfntSize ) ||
- FT_NEW( sfnt_stream ) )
+ /* Don't trust `totalSfntSize' before thorough checks. */
+ if ( FT_ALLOC( sfnt, 12 + woff.num_tables * 16UL ) ||
+ FT_NEW( sfnt_stream ) )
goto Exit;
sfnt_header = sfnt;
@@ -539,6 +525,8 @@
if ( table->Tag <= old_tag )
{
FT_FRAME_EXIT();
+
+ FT_ERROR(( "woff_font_open: table tags are not sorted\n" ));
error = FT_THROW( Invalid_Table );
goto Exit;
}
@@ -573,6 +561,7 @@
sfnt_offset > woff.totalSfntSize - table->OrigLength ||
table->CompLength > table->OrigLength )
{
+ FT_ERROR(( "woff_font_open: invalid table offsets\n" ));
error = FT_THROW( Invalid_Table );
goto Exit;
}
@@ -598,6 +587,8 @@
if ( woff.metaOffset != woff_offset ||
woff.metaOffset + woff.metaLength > woff.length )
{
+ FT_ERROR(( "woff_font_open:"
+ " invalid `metadata' offset or length\n" ));
error = FT_THROW( Invalid_Table );
goto Exit;
}
@@ -614,6 +605,7 @@
if ( woff.privOffset != woff_offset ||
woff.privOffset + woff.privLength > woff.length )
{
+ FT_ERROR(( "woff_font_open: invalid `private' offset or length\n" ));
error = FT_THROW( Invalid_Table );
goto Exit;
}
@@ -625,10 +617,19 @@
if ( sfnt_offset != woff.totalSfntSize ||
woff_offset != woff.length )
{
+ FT_ERROR(( "woff_font_open: invalid `sfnt' table structure\n" ));
error = FT_THROW( Invalid_Table );
goto Exit;
}
+ /* Now use `totalSfntSize'. */
+ if ( FT_REALLOC( sfnt,
+ 12 + woff.num_tables * 16UL,
+ woff.totalSfntSize ) )
+ goto Exit;
+
+ sfnt_header = sfnt + 12;
+
/* Write the tables. */
for ( nn = 0; nn < woff.num_tables; nn++ )
@@ -669,6 +670,7 @@
goto Exit;
if ( output_len != table->OrigLength )
{
+ FT_ERROR(( "woff_font_open: compressed table length mismatch\n" ));
error = FT_THROW( Invalid_Table );
goto Exit;
}
@@ -839,13 +841,14 @@
FT_LOCAL_DEF( FT_Error )
sfnt_init_face( FT_Stream stream,
TT_Face face,
- FT_Int face_index,
+ FT_Int face_instance_index,
FT_Int num_params,
FT_Parameter* params )
{
- FT_Error error;
- FT_Library library = face->root.driver->root.library;
- SFNT_Service sfnt;
+ FT_Error error;
+ FT_Library library = face->root.driver->root.library;
+ SFNT_Service sfnt;
+ FT_Int face_index;
/* for now, parameters are unused */
@@ -878,22 +881,97 @@
/* Stream may have changed in sfnt_open_font. */
stream = face->root.stream;
- FT_TRACE2(( "sfnt_init_face: %08p, %ld\n", face, face_index ));
+ FT_TRACE2(( "sfnt_init_face: %08p, %ld\n", face, face_instance_index ));
- if ( face_index < 0 )
- face_index = 0;
+ face_index = FT_ABS( face_instance_index ) & 0xFFFF;
if ( face_index >= face->ttc_header.count )
- return FT_THROW( Invalid_Argument );
+ {
+ if ( face_instance_index >= 0 )
+ return FT_THROW( Invalid_Argument );
+ else
+ face_index = 0;
+ }
if ( FT_STREAM_SEEK( face->ttc_header.offsets[face_index] ) )
return error;
- /* check that we have a valid TrueType file */
+ /* check whether we have a valid TrueType file */
error = sfnt->load_font_dir( face, stream );
if ( error )
return error;
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+ {
+ FT_ULong fvar_len;
+
+ FT_ULong version;
+ FT_ULong offset;
+
+ FT_UShort num_axes;
+ FT_UShort axis_size;
+ FT_UShort num_instances;
+ FT_UShort instance_size;
+
+ FT_Int instance_index;
+
+
+ instance_index = FT_ABS( face_instance_index ) >> 16;
+
+ /* test whether current face is a GX font with named instances */
+ if ( face->goto_table( face, TTAG_fvar, stream, &fvar_len ) ||
+ fvar_len < 20 ||
+ FT_READ_ULONG( version ) ||
+ FT_READ_USHORT( offset ) ||
+ FT_STREAM_SKIP( 2 ) ||
+ FT_READ_USHORT( num_axes ) ||
+ FT_READ_USHORT( axis_size ) ||
+ FT_READ_USHORT( num_instances ) ||
+ FT_READ_USHORT( instance_size ) )
+ {
+ version = 0;
+ offset = 0;
+ num_axes = 0;
+ axis_size = 0;
+ num_instances = 0;
+ instance_size = 0;
+ }
+
+ /* check that the data is bound by the table length; */
+ /* based on similar code in function `TT_Get_MM_Var' */
+ if ( version != 0x00010000UL ||
+ axis_size != 20 ||
+ num_axes > 0x3FFE ||
+ instance_size != 4 + 4 * num_axes ||
+ num_instances > 0x7EFF ||
+ offset +
+ axis_size * num_axes +
+ instance_size * num_instances > fvar_len )
+ num_instances = 0;
+
+ /* we support at most 2^15 - 1 instances */
+ if ( num_instances >= ( 1U << 15 ) - 1 )
+ {
+ if ( face_instance_index >= 0 )
+ return FT_THROW( Invalid_Argument );
+ else
+ num_instances = 0;
+ }
+
+ /* instance indices in `face_instance_index' start with index 1, */
+ /* thus `>' and not `>=' */
+ if ( instance_index > num_instances )
+ {
+ if ( face_instance_index >= 0 )
+ return FT_THROW( Invalid_Argument );
+ else
+ num_instances = 0;
+ }
+
+ face->root.style_flags = (FT_Long)num_instances << 16;
+ }
+#endif
+
face->root.num_faces = face->ttc_header.count;
face->root.face_index = face_index;
@@ -946,7 +1024,7 @@
FT_LOCAL_DEF( FT_Error )
sfnt_load_face( FT_Stream stream,
TT_Face face,
- FT_Int face_index,
+ FT_Int face_instance_index,
FT_Int num_params,
FT_Parameter* params )
{
@@ -962,7 +1040,7 @@
SFNT_Service sfnt = (SFNT_Service)face->sfnt;
- FT_UNUSED( face_index );
+ FT_UNUSED( face_instance_index );
/* Check parameters */
@@ -1284,7 +1362,7 @@
flags |= FT_STYLE_FLAG_ITALIC;
}
- root->style_flags = flags;
+ root->style_flags |= flags;
/*********************************************************************/
/* */