* src/cid/cidload.c (cid_face_open): Always allocate

face->cid_stream so that we can deallocate it safely.


Make the PS parser more tolerant w.r.t. non-standard font data.  In
general, an error is only reported in case of a syntax error; a
wrong type is now simply ignored (if possible).  To be independent
of the order of various MM-specific keywords, the parse_shared_dict
routine has been removed -- the PS parser is now capable to skip
this data.  It no longer fails on parsing e.g.

  dup /WeightVector exch def

Since the token following /WeightVector isn't `[' (starting an
array) it is simply ignored.

* include/freetype/fterrdef.h: Define `FT_Err_Ignore' (0xA2) as a
new internal error value.

* src/type1/t1load.c (parse_blend_axis_types,
parse_blend_design_positions, parse_blend_design_map): Return
T1_Err_Ignore if no proper array is following the keyword.
(parse_weight_vector): Use T1_ToTokenArray, initializing `blend'
structure, if necessary.
Return T1_Err_Ignore if no proper array is following the keyword.
(parse_shared_dict): Removed.
(parse_encoding): Set parser->root.error to return T1_Err_Ignore
if no result can be obtained.
Check for errors before accessing `elements' array.
(t1_keywords): Remove /shareddict.
(parse_dict): Reset error if t1_load_keyword returns T1_Err_Ignore.
Set keyword_flag only in case of success.
Check error code if skipping an unrecognized token.
(T1_Open_Face) [!T1_CONFIG_OPTION_NO_MM_SUPPORT]: Call T1_Done_Blend
if blend commands haven't set up a proper MM font.

* src/psaux/psobjs.c (ps_parser_load_field_table): Remove special
code for synthetic fonts.
Return PSaux_Err_Ignore if no proper value has been found.
This commit is contained in:
Werner Lemberg 2004-02-12 08:33:20 +00:00
parent 916838ca68
commit 95867077e8
5 changed files with 161 additions and 73 deletions

View File

@ -1,15 +1,58 @@
2003-02-09 Werner Lemberg <wl@gnu.org>
2004-02-11 Werner Lemberg <wl@gnu.org>
* src/cid/cidload.c (cid_face_open): Always allocate
face->cid_stream so that we can deallocate it safely.
2004-02-10 Werner Lemberg <wl@gnu.org>
Make the PS parser more tolerant w.r.t. non-standard font data. In
general, an error is only reported in case of a syntax error; a
wrong type is now simply ignored (if possible). To be independent
of the order of various MM-specific keywords, the parse_shared_dict
routine has been removed -- the PS parser is now capable to skip
this data. It no longer fails on parsing e.g.
dup /WeightVector exch def
Since the token following /WeightVector isn't `[' (starting an
array) it is simply ignored.
* include/freetype/fterrdef.h: Define `FT_Err_Ignore' (0xA2) as a
new internal error value.
* src/type1/t1load.c (parse_blend_axis_types,
parse_blend_design_positions, parse_blend_design_map): Return
T1_Err_Ignore if no proper array is following the keyword.
(parse_weight_vector): Use T1_ToTokenArray, initializing `blend'
structure, if necessary.
Return T1_Err_Ignore if no proper array is following the keyword.
(parse_shared_dict): Removed.
(parse_encoding): Set parser->root.error to return T1_Err_Ignore
if no result can be obtained.
Check for errors before accessing `elements' array.
(t1_keywords): Remove /shareddict.
(parse_dict): Reset error if t1_load_keyword returns T1_Err_Ignore.
Set keyword_flag only in case of success.
Check error code if skipping an unrecognized token.
(T1_Open_Face) [!T1_CONFIG_OPTION_NO_MM_SUPPORT]: Call T1_Done_Blend
if blend commands haven't set up a proper MM font.
* src/psaux/psobjs.c (ps_parser_load_field_table): Remove special
code for synthetic fonts.
Return PSaux_Err_Ignore if no proper value has been found.
2004-02-09 Werner Lemberg <wl@gnu.org>
* src/cff/cffgload.c (cff_decoder_parse_charstrings)
<cff_op_endchar>: Preserve glyph width before calling
cff_operator_seac.
2003-02-09 Martin Muskens <mmuskens@aurelon.com>
2004-02-09 Martin Muskens <mmuskens@aurelon.com>
* src/cff/cffgload.c (cff_decoder_parse_charstrings): Handle special
first argument for `hintmask' and `cntrmask' operators also.
2003-02-08 Werner Lemberg <wl@gnu.org>
2004-02-08 Werner Lemberg <wl@gnu.org>
* builds/unix/configure.in: Call AC_SUBST for `enable_shared',
`hardcode_libdir_flag_spec', and `wl'.
@ -22,7 +65,7 @@
* docs/CHANGES: Updated.
2003-02-07 Keith Packard <keithp@keithp.com>
2004-02-07 Keith Packard <keithp@keithp.com>
* src/bdf/bdfdrivr.c (BDF_Face_Init, BDF_Set_Pixel_Size): Fix
computation of various vertical and horizontal metric values.
@ -30,24 +73,24 @@
* src/pcfdrivr.c (PCF_Set_Pixel_Size), src/pcfread (pcf_load_font):
Ditto.
2003-02-07 Werner Lemberg <wl@gnu.org>
2004-02-07 Werner Lemberg <wl@gnu.org>
* builds/win32/visualc/index.html,
builds/win32/visualc/freetype.dsp,
builds/win32/visualc/freetype.dsw, docs/CHANGES: Updated.
2003-02-07 Vitaliy Pasternak <v_a_pasternak@mail.ru>
2004-02-07 Vitaliy Pasternak <v_a_pasternak@mail.ru>
* builds/win32/visualc/freetype.sln,
builds/win32/visualc/freetype.vcproj: New files for VS.NET 2003.
2003-02-03 Werner Lemberg <wl@gnu.org>
2004-02-03 Werner Lemberg <wl@gnu.org>
* include/freetype/cache/ftccache.h (FTC_CACHE_LOOKUP_CMP):
Initialize `node'.
* src/type1/t1load.c (parse_dict): Initialize `have_integer'.
2003-02-02 Werner Lemberg <wl@gnu.org>
2004-02-02 Werner Lemberg <wl@gnu.org>
* src/type1/t1load.c (parse_dict): Handle `RD' and `-|' commands
outside of /Subrs or /CharStrings. This can happen if there is

View File

@ -4,7 +4,7 @@
/* */
/* FreeType error codes (specification). */
/* */
/* Copyright 2002 by */
/* Copyright 2002, 2004 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -207,6 +207,8 @@
"opcode syntax error" )
FT_ERRORDEF_( Stack_Underflow, 0xA1, \
"argument stack underflow" )
FT_ERRORDEF_( Ignore, 0xA2, \
"ignore" )
/* BDF errors */

View File

@ -612,6 +612,9 @@
if ( face_index < 0 )
goto Exit;
if ( FT_NEW( face->cid_stream ) )
goto Exit;
if ( parser->binary_length )
{
/* we must convert the data section from hexadecimal to binary */
@ -620,16 +623,13 @@
parser->data_offset, face ) )
goto Exit;
if ( FT_NEW( face->cid_stream ) )
goto Exit;
FT_Stream_OpenMemory( face->cid_stream,
face->binary_data, parser->binary_length );
face->cid.data_offset = 0;
}
else
{
face->cid_stream = face->root.stream;
*face->cid_stream = *face->root.stream;
face->cid.data_offset = loader.parser.data_offset;
}

View File

@ -4,7 +4,7 @@
/* */
/* Auxiliary functions for PostScript fonts (body). */
/* */
/* Copyright 1996-2001, 2002, 2003 by */
/* Copyright 1996-2001, 2002, 2003, 2004 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -1280,10 +1280,6 @@
if ( cur >= limit )
break;
/* with synthetic fonts, it is possible to find a field twice */
if ( *(FT_String**)q )
break;
if ( field->type == T1_FIELD_TYPE_KEY )
{
/* don't include leading `/' */
@ -1359,7 +1355,7 @@
T1_TokenRec elements[T1_MAX_TABLE_ELEMENTS];
T1_Token token;
FT_Int num_elements;
FT_Error error = 0;
FT_Error error = PSaux_Err_Ok;
FT_Byte* old_cursor;
FT_Byte* old_limit;
T1_FieldRec fieldrec = *(T1_Field)field;
@ -1374,8 +1370,10 @@
ps_parser_to_token_array( parser, elements,
T1_MAX_TABLE_ELEMENTS, &num_elements );
if ( num_elements < 0 )
goto Fail;
{
error = PSaux_Err_Ignore;
goto Exit;
}
if ( num_elements > T1_MAX_TABLE_ELEMENTS )
num_elements = T1_MAX_TABLE_ELEMENTS;
@ -1408,10 +1406,6 @@
Exit:
return error;
Fail:
error = PSaux_Err_Invalid_File_Format;
goto Exit;
}

View File

@ -397,7 +397,12 @@
/* take an array of objects */
T1_ToTokenArray( &loader->parser, axis_tokens,
T1_MAX_MM_AXIS, &num_axis );
if ( num_axis <= 0 || num_axis > T1_MAX_MM_AXIS )
if ( num_axis < 0 )
{
error = T1_Err_Ignore;
goto Exit;
}
if ( num_axis == 0 || num_axis > T1_MAX_MM_AXIS )
{
FT_ERROR(( "parse_blend_axis_types: incorrect number of axes: %d\n",
num_axis ));
@ -459,8 +464,14 @@
/* get the array of design tokens -- compute number of designs */
T1_ToTokenArray( parser, design_tokens, T1_MAX_MM_DESIGNS, &num_designs );
if ( num_designs <= 0 || num_designs > T1_MAX_MM_DESIGNS )
T1_ToTokenArray( parser, design_tokens,
T1_MAX_MM_DESIGNS, &num_designs );
if ( num_designs < 0 )
{
error = T1_Err_Ignore;
goto Exit;
}
if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS )
{
FT_ERROR(( "parse_blend_design_positions:" ));
FT_ERROR(( " incorrect number of designs: %d\n",
@ -472,13 +483,13 @@
{
FT_Byte* old_cursor = parser->root.cursor;
FT_Byte* old_limit = parser->root.limit;
FT_UInt n;
FT_Int n;
blend = face->blend;
num_axis = 0; /* make compiler happy */
for ( n = 0; n < (FT_UInt)num_designs; n++ )
for ( n = 0; n < num_designs; n++ )
{
T1_TokenRec axis_tokens[T1_MAX_MM_DESIGNS];
T1_Token token;
@ -541,8 +552,14 @@
FT_Memory memory = face->root.memory;
T1_ToTokenArray( parser, axis_tokens, T1_MAX_MM_AXIS, &num_axis );
if ( num_axis <= 0 || num_axis > T1_MAX_MM_AXIS )
T1_ToTokenArray( parser, axis_tokens,
T1_MAX_MM_AXIS, &num_axis );
if ( num_axis < 0 )
{
error = T1_Err_Ignore;
goto Exit;
}
if ( num_axis == 0 || num_axis > T1_MAX_MM_AXIS )
{
FT_ERROR(( "parse_blend_design_map: incorrect number of axes: %d\n",
num_axis ));
@ -615,26 +632,46 @@
parse_weight_vector( T1_Face face,
T1_Loader loader )
{
T1_TokenRec design_tokens[T1_MAX_MM_DESIGNS];
FT_Int num_designs;
FT_Error error = T1_Err_Ok;
T1_Parser parser = &loader->parser;
PS_Blend blend = face->blend;
T1_TokenRec master;
FT_UInt n;
T1_Token token;
FT_Int n;
FT_Byte* old_cursor;
FT_Byte* old_limit;
if ( !blend || blend->num_designs == 0 )
T1_ToTokenArray( parser, design_tokens,
T1_MAX_MM_DESIGNS, &num_designs );
if ( num_designs < 0 )
{
FT_ERROR(( "parse_weight_vector: too early!\n" ));
error = T1_Err_Ignore;
goto Exit;
}
if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS )
{
FT_ERROR(( "parse_weight_vector:" ));
FT_ERROR(( " incorrect number of designs: %d\n",
num_designs ));
error = T1_Err_Invalid_File_Format;
goto Exit;
}
T1_ToToken( parser, &master );
if ( master.type != T1_TOKEN_TYPE_ARRAY )
if ( !blend || !blend->num_designs )
{
FT_ERROR(( "parse_weight_vector: incorrect format!\n" ));
error = t1_allocate_blend( face, num_designs, 0 );
if ( error )
goto Exit;
blend = face->blend;
}
else if ( blend->num_designs != (FT_UInt)num_designs )
{
FT_ERROR(( "parse_weight_vector:"
" /BlendDesignPosition and /WeightVector have\n" ));
FT_ERROR(( " "
" different number of elements!\n" ));
error = T1_Err_Invalid_File_Format;
goto Exit;
}
@ -642,12 +679,12 @@
old_cursor = parser->root.cursor;
old_limit = parser->root.limit;
/* don't include the delimiting brackets */
parser->root.cursor = master.start + 1;
parser->root.limit = master.limit - 1;
for ( n = 0; n < blend->num_designs; n++ )
for ( n = 0; n < num_designs; n++ )
{
token = design_tokens + n;
parser->root.cursor = token->start;
parser->root.limit = token->limit;
blend->default_weight_vector[n] =
blend->weight_vector[n] = T1_ToFixed( parser, 0 );
}
@ -660,23 +697,6 @@
}
/* the keyword `/shareddict' appears in some multiple master fonts */
/* with a lot of Postscript garbage behind it (that's completely out */
/* of spec!); we detect it and terminate the parsing */
/* */
static void
parse_shared_dict( T1_Face face,
T1_Loader loader )
{
T1_Parser parser = &loader->parser;
FT_UNUSED( face );
parser->root.cursor = parser->root.limit;
parser->root.error = 0;
}
#endif /* T1_CONFIG_OPTION_NO_MM_SUPPORT */
@ -1007,9 +1027,9 @@
parser->root.error = T1_Add_Table( char_table, charcode,
cur, len + 1 );
char_table->elements[charcode][len] = '\0';
if ( parser->root.error )
return;
char_table->elements[charcode][len] = '\0';
n++;
}
@ -1041,10 +1061,7 @@
face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1;
else
{
FT_ERROR(( "parse_encoding: invalid token!\n" ));
parser->root.error = T1_Err_Invalid_File_Format;
}
parser->root.error = T1_Err_Ignore;
}
}
@ -1230,8 +1247,8 @@
FT_Byte* base;
/* the format is simple: */
/* `/glyphname' + binary data */
/* the format is simple: */
/* `/glyphname' + binary data */
T1_Skip_Spaces( parser );
@ -1395,7 +1412,7 @@
/* We take index 0 and add it to the end of the table(s) */
/* and add our own /.notdef glyph to index 0. */
/* 0 333 hsbw endchar */
/* 0 333 hsbw endchar */
FT_Byte notdef_glyph[] = {0x8B, 0xF7, 0xE1, 0x0D, 0x0E};
char* notdef_name = (char *)".notdef";
@ -1469,7 +1486,6 @@
T1_FIELD_CALLBACK( "BlendDesignMap", parse_blend_design_map )
T1_FIELD_CALLBACK( "BlendAxisTypes", parse_blend_axis_types )
T1_FIELD_CALLBACK( "WeightVector", parse_weight_vector )
T1_FIELD_CALLBACK( "shareddict", parse_shared_dict )
#endif
{ 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0 }
@ -1640,10 +1656,16 @@
parser->root.error = t1_load_keyword( face,
loader,
keyword );
if ( parser->root.error )
return parser->root.error;
if ( parser->root.error == T1_Err_Ok )
keyword_flag[0] = 1;
else
{
if ( parser->root.error == T1_Err_Ignore )
parser->root.error = T1_Err_Ok;
else
return parser->root.error;
}
}
keyword_flag[0] = 1;
break;
}
@ -1657,12 +1679,15 @@
else
{
T1_Skip_PS_Token( parser );
if ( parser->root.error )
goto Exit;
have_integer = 0;
}
T1_Skip_Spaces( parser );
}
Exit:
return parser->root.error;
}
@ -1756,6 +1781,30 @@
if ( error )
goto Exit;
#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
/* the following can happen for MM instances; we then treat the */
/* font as a normal PS font */
if ( face->blend &&
( !face->blend->num_designs || !face->blend->num_axis ) )
T1_Done_Blend( face );
/* another safety check */
if ( face->blend )
{
FT_UInt i;
for ( i = 0; i < face->blend->num_axis; i++ )
if ( !face->blend->design_map[i].num_points )
{
T1_Done_Blend( face );
break;
}
}
#endif /* T1_CONFIG_OPTION_NO_MM_SUPPORT */
/* now, propagate the subrs, charstrings, and glyphnames tables */
/* to the Type1 data */
type1->num_glyphs = loader.num_glyphs;