* src/type1/t1load.c (parse_encoding): Handle `/Encoding [ ... ]'.

* src/type1/t1parse.c (T1_Get_Private_Dict): Test whether `eexec'
is real.

* src/type42/t42parse.c (t42_parse_encoding): Improve boundary
checking while parsing.

* docs/CHANGES: Updated.
This commit is contained in:
Werner Lemberg 2003-10-23 16:24:10 +00:00
parent 1c0b8e9d72
commit 4795b36cf9
5 changed files with 119 additions and 34 deletions

View File

@ -1,3 +1,15 @@
2003-10-22 Werner Lemberg <wl@gnu.org>
* src/type1/t1load.c (parse_encoding): Handle `/Encoding [ ... ]'.
* src/type1/t1parse.c (T1_Get_Private_Dict): Test whether `eexec'
is real.
* src/type42/t42parse.c (t42_parse_encoding): Improve boundary
checking while parsing.
* docs/CHANGES: Updated.
2003-10-21 Josselin Mouette <joss@debian.org> 2003-10-21 Josselin Mouette <joss@debian.org>
* include/freetype/internal/t1types.h (T1_FontRec): `paint_type' * include/freetype/internal/t1types.h (T1_FontRec): `paint_type'
@ -488,7 +500,7 @@
step towards a massive simplification of the engine's internals, in step towards a massive simplification of the engine's internals, in
order to get rid of various numbers of hacks. order to get rid of various numbers of hacks.
Note that this changes will break source & binary compatibility for Note that these changes will break source & binary compatibility for
authors of external font drivers. authors of external font drivers.
* include/freetype/config/ftconfig.h (FT_BEGIN_STMNT, FT_END_STMNT, * include/freetype/config/ftconfig.h (FT_BEGIN_STMNT, FT_END_STMNT,

View File

@ -9,6 +9,15 @@ LATEST CHANGES BETWEEN 2.1.6 and 2.1.5
- Type 1 font files in binary format (PFB) with an end-of-file - Type 1 font files in binary format (PFB) with an end-of-file
indicator weren't accepted by the FreeType engine. indicator weren't accepted by the FreeType engine.
- Fonts which contain /PaintType and /StrokeWidth no longer cause
a segfault. This bug has been introduced in version 2.1.5.
- Fonts loaded with FT_LOAD_RENDER no longer cause strange
results. This bug has been introduced in version 2.1.5.
- Some Windows (bitmap) FNT/FON files couldn't be handled
correctly.
II. IMPORTANT CHANGES II. IMPORTANT CHANGES
- The internal module API has been heavily changed in favor of - The internal module API has been heavily changed in favor of
@ -16,6 +25,10 @@ LATEST CHANGES BETWEEN 2.1.6 and 2.1.5
that authors of third-party modules must adapt their code to the that authors of third-party modules must adapt their code to the
new scheme. new scheme.
- The PostScript parser has been enhanced to handle comments and
strings correctly. Additionally, more syntax forms are
recognized.
===================================================================== =====================================================================
@ -39,14 +52,14 @@ LATEST CHANGES BETWEEN 2.1.5 and 2.1.4
longer overwritten. longer overwritten.
- The font matrix wasn't applied to the advance width for Type1, - The font matrix wasn't applied to the advance width for Type1,
CID, and CFF fonts. This caused problem when loading certain CID, and CFF fonts. This caused problems when loading certain
synthetic Type 1 fonts like "Helvetica Narrow" synthetic Type 1 fonts like `Helvetica Narrow'.
- The test for the charset registry in BDF and PCF fonts is now - The test for the charset registry in BDF and PCF fonts is now
case-insensitive. case-insensitive.
- FT_Vector_Rotate rotating sometimes returned strange values due - FT_Vector_Rotate sometimes returned strange values due to
to rounding errors. rounding errors.
- The PCF driver now returns the correct number of glyphs - The PCF driver now returns the correct number of glyphs
(including an artificial `notdef' glyph at index 0). (including an artificial `notdef' glyph at index 0).

View File

@ -884,19 +884,28 @@
return; return;
} }
/* if we have a number, then the encoding is an array, */ /* if we have a number or `[', the encoding is an array, */
/* and we must load it now */ /* and we must load it now */
if ( ft_isdigit( *cur ) ) if ( ft_isdigit( *cur ) || *cur == '[' )
{ {
T1_Encoding encode = &face->type1.encoding; T1_Encoding encode = &face->type1.encoding;
FT_Int count, n; FT_Int count, n;
PS_Table char_table = &loader->encoding_table; PS_Table char_table = &loader->encoding_table;
FT_Memory memory = parser->root.memory; FT_Memory memory = parser->root.memory;
FT_Error error; FT_Error error;
FT_Bool only_immediates = 0;
/* read the number of entries in the encoding; should be 256 */ /* read the number of entries in the encoding; should be 256 */
count = (FT_Int)T1_ToInt( parser ); if ( *cur == '[' )
{
count = 256;
only_immediates = 1;
parser->root.cursor++;
}
else
count = (FT_Int)T1_ToInt( parser );
T1_Skip_Spaces( parser ); T1_Skip_Spaces( parser );
if ( parser->root.cursor >= limit ) if ( parser->root.cursor >= limit )
return; return;
@ -921,16 +930,25 @@
T1_Add_Table( char_table, n, notdef, 8 ); T1_Add_Table( char_table, n, notdef, 8 );
} }
/* Now we need to read a record of the form */ /* Now we need to read records of the form */
/* ... charcode /charname ... for each entry in our table */ /* */
/* ... charcode /charname ... */
/* */
/* for each entry in our table. */
/* */ /* */
/* We simply look for a number followed by an immediate */ /* We simply look for a number followed by an immediate */
/* name. Note that this ignores correctly the sequence */ /* name. Note that this ignores correctly the sequence */
/* that is often seen in Type 1 fonts: */ /* that is often seen in type1 fonts: */
/* */ /* */
/* 0 1 255 { 1 index exch /.notdef put } for dup */ /* 0 1 255 { 1 index exch /.notdef put } for dup */
/* */ /* */
/* used to clean the encoding array before anything else. */ /* used to clean the encoding array before anything else. */
/* */
/* Alternatively, if the array is directly given as */
/* */
/* /Encoding [ ... ] */
/* */
/* we only read immediates. */
n = 0; n = 0;
T1_Skip_Spaces( parser ); T1_Skip_Spaces( parser );
@ -939,7 +957,7 @@
{ {
cur = parser->root.cursor; cur = parser->root.cursor;
/* we stop when we encounter a `def' */ /* we stop when we encounter a `def' or `]' */
if ( *cur == 'd' && cur + 3 < limit ) if ( *cur == 'd' && cur + 3 < limit )
{ {
if ( cur[1] == 'e' && if ( cur[1] == 'e' &&
@ -951,18 +969,30 @@
break; break;
} }
} }
if ( *cur == ']' )
{
FT_TRACE6(( "encoding end\n" ));
cur++;
break;
}
/* otherwise, we must find a number before anything else */ /* check whether we've found an entry */
if ( ft_isdigit( *cur ) ) if ( ft_isdigit( *cur ) || only_immediates )
{ {
FT_Int charcode; FT_Int charcode;
charcode = (FT_Int)T1_ToInt( parser ); if ( only_immediates )
T1_Skip_Spaces( parser ); charcode = n;
else
{
charcode = (FT_Int)T1_ToInt( parser );
T1_Skip_Spaces( parser );
}
cur = parser->root.cursor; cur = parser->root.cursor;
if ( *cur == '/' && cur + 2 < limit ) if ( *cur == '/' && cur + 2 < limit && n < count )
{ {
FT_PtrDist len; FT_PtrDist len;
@ -979,6 +1009,8 @@
char_table->elements[charcode][len] = '\0'; char_table->elements[charcode][len] = '\0';
if ( parser->root.error ) if ( parser->root.error )
return; return;
n++;
} }
} }
else else

View File

@ -299,24 +299,18 @@
FT_Byte c; FT_Byte c;
Again:
for (;;) for (;;)
{ {
c = cur[0]; c = cur[0];
if ( c == 'e' && cur + 9 < limit ) /* 9 = 5 letters for `eexec' + */ if ( c == 'e' && cur + 9 < limit ) /* 9 = 5 letters for `eexec' + */
/* newline + 4 chars */ /* newline + 4 chars */
{ {
if ( cur[1] == 'e' && cur[2] == 'x' && if ( cur[1] == 'e' &&
cur[3] == 'e' && cur[4] == 'c' ) cur[2] == 'x' &&
{ cur[3] == 'e' &&
cur += 6; /* we skip the newline after the `eexec' */ cur[4] == 'c' )
/* XXX: Some fonts use DOS-linefeeds, i.e. \r\n; we need to */
/* skip the extra \n if we find it */
if ( cur[0] == '\n' )
cur++;
break; break;
}
} }
cur++; cur++;
if ( cur >= limit ) if ( cur >= limit )
@ -328,10 +322,43 @@
} }
} }
/* check whether `eexec' was real -- it could be in a comment */
/* or string (as e.g. in u003043t.gsf from ghostscript) */
parser->root.cursor = parser->base_dict;
parser->root.limit = cur + 9;
cur = parser->root.cursor;
limit = parser->root.limit;
while ( cur < limit )
{
if ( *cur == 'e' && ft_strncmp( (char*)cur, "eexec", 5 ) == 0 )
goto Found;
T1_Skip_PS_Token( parser );
T1_Skip_Spaces ( parser );
cur = parser->root.cursor;
}
/* we haven't found the correct `eexec'; go back and continue */
/* searching */
cur = limit;
limit = parser->base_dict + parser->base_len;
goto Again;
/* now determine where to write the _encrypted_ binary private */ /* now determine where to write the _encrypted_ binary private */
/* dictionary. We overwrite the base dictionary for disk-based */ /* dictionary. We overwrite the base dictionary for disk-based */
/* resources and allocate a new block otherwise */ /* resources and allocate a new block otherwise */
Found:
parser->root.limit = parser->base_dict + parser->base_len;
T1_Skip_PS_Token( parser );
T1_Skip_Spaces ( parser );
cur = parser->root.cursor;
size = (FT_Long)( parser->base_len - ( cur - parser->base_dict ) ); size = (FT_Long)( parser->base_len - ( cur - parser->base_dict ) );
if ( parser->in_memory ) if ( parser->in_memory )

View File

@ -288,7 +288,6 @@
T1_Skip_Spaces( parser ); T1_Skip_Spaces( parser );
cur = parser->root.cursor; cur = parser->root.cursor;
if ( cur >= limit ) if ( cur >= limit )
{ {
FT_ERROR(( "t42_parse_encoding: out of bounds!\n" )); FT_ERROR(( "t42_parse_encoding: out of bounds!\n" ));
@ -363,10 +362,10 @@
/* we only read immediates. */ /* we only read immediates. */
n = 0; n = 0;
T1_Skip_Spaces( parser );
while ( parser->root.cursor < limit ) while ( parser->root.cursor < limit )
{ {
T1_Skip_Spaces( parser );
cur = parser->root.cursor; cur = parser->root.cursor;
/* we stop when we encounter `def' or `]' */ /* we stop when we encounter `def' or `]' */
@ -427,6 +426,8 @@
} }
else else
T1_Skip_PS_Token( parser ); T1_Skip_PS_Token( parser );
T1_Skip_Spaces( parser );
} }
face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY; face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY;