ref: 4795b36cf9a4fa37d9c2aa0a2ac4d8ee9d2bc2b3
parent: 1c0b8e9d7286792f9839f4f68f33a22ae53a9585
author: Werner Lemberg <[email protected]>
date: Thu Oct 23 12:24:10 EDT 2003
* 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.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2003-10-22 Werner Lemberg <[email protected]>
+
+ * 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 <[email protected]>
* include/freetype/internal/t1types.h (T1_FontRec): `paint_type'
@@ -488,7 +500,7 @@
step towards a massive simplification of the engine's internals, in
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.
* include/freetype/config/ftconfig.h (FT_BEGIN_STMNT, FT_END_STMNT,
--- a/docs/CHANGES
+++ b/docs/CHANGES
@@ -9,6 +9,15 @@
- Type 1 font files in binary format (PFB) with an end-of-file
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
- The internal module API has been heavily changed in favor of
@@ -16,7 +25,11 @@
that authors of third-party modules must adapt their code to the
new scheme.
+ - The PostScript parser has been enhanced to handle comments and
+ strings correctly. Additionally, more syntax forms are
+ recognized.
+
=====================================================================
LATEST CHANGES BETWEEN 2.1.5 and 2.1.4
@@ -39,14 +52,14 @@
longer overwritten.
- The font matrix wasn't applied to the advance width for Type1,
- CID, and CFF fonts. This caused problem when loading certain
- synthetic Type 1 fonts like "Helvetica Narrow"
+ CID, and CFF fonts. This caused problems when loading certain
+ synthetic Type 1 fonts like `Helvetica Narrow'.
- The test for the charset registry in BDF and PCF fonts is now
case-insensitive.
- - FT_Vector_Rotate rotating sometimes returned strange values due
- to rounding errors.
+ - FT_Vector_Rotate sometimes returned strange values due to
+ rounding errors.
- The PCF driver now returns the correct number of glyphs
(including an artificial `notdef' glyph at index 0).
--- a/src/type1/t1load.c
+++ b/src/type1/t1load.c
@@ -884,19 +884,28 @@
return;
}
- /* if we have a number, then the encoding is an array, */
- /* and we must load it now */
- if ( ft_isdigit( *cur ) )
+ /* if we have a number or `[', the encoding is an array, */
+ /* and we must load it now */
+ if ( ft_isdigit( *cur ) || *cur == '[' )
{
- T1_Encoding encode = &face->type1.encoding;
+ T1_Encoding encode = &face->type1.encoding;
FT_Int count, n;
- PS_Table char_table = &loader->encoding_table;
- FT_Memory memory = parser->root.memory;
+ PS_Table char_table = &loader->encoding_table;
+ FT_Memory memory = parser->root.memory;
FT_Error error;
+ FT_Bool only_immediates = 0;
/* 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 );
if ( parser->root.cursor >= limit )
return;
@@ -921,16 +930,25 @@
T1_Add_Table( char_table, n, notdef, 8 );
}
- /* Now we need to read a record of the form */
- /* ... charcode /charname ... for each entry in our table */
+ /* Now we need to read records of the form */
/* */
+ /* ... charcode /charname ... */
+ /* */
+ /* for each entry in our table. */
+ /* */
/* We simply look for a number followed by an immediate */
/* 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 */
/* */
/* used to clean the encoding array before anything else. */
+ /* */
+ /* Alternatively, if the array is directly given as */
+ /* */
+ /* /Encoding [ ... ] */
+ /* */
+ /* we only read immediates. */
n = 0;
T1_Skip_Spaces( parser );
@@ -939,7 +957,7 @@
{
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[1] == 'e' &&
@@ -951,18 +969,30 @@
break;
}
}
+ if ( *cur == ']' )
+ {
+ FT_TRACE6(( "encoding end\n" ));
+ cur++;
+ break;
+ }
- /* otherwise, we must find a number before anything else */
- if ( ft_isdigit( *cur ) )
+ /* check whether we've found an entry */
+ if ( ft_isdigit( *cur ) || only_immediates )
{
FT_Int charcode;
- charcode = (FT_Int)T1_ToInt( parser );
- T1_Skip_Spaces( parser );
+ if ( only_immediates )
+ charcode = n;
+ else
+ {
+ charcode = (FT_Int)T1_ToInt( parser );
+ T1_Skip_Spaces( parser );
+ }
+
cur = parser->root.cursor;
- if ( *cur == '/' && cur + 2 < limit )
+ if ( *cur == '/' && cur + 2 < limit && n < count )
{
FT_PtrDist len;
@@ -979,6 +1009,8 @@
char_table->elements[charcode][len] = '\0';
if ( parser->root.error )
return;
+
+ n++;
}
}
else
--- a/src/type1/t1parse.c
+++ b/src/type1/t1parse.c
@@ -299,6 +299,7 @@
FT_Byte c;
+ Again:
for (;;)
{
c = cur[0];
@@ -305,18 +306,11 @@
if ( c == 'e' && cur + 9 < limit ) /* 9 = 5 letters for `eexec' + */
/* newline + 4 chars */
{
- if ( cur[1] == 'e' && cur[2] == 'x' &&
- cur[3] == 'e' && cur[4] == 'c' )
- {
- cur += 6; /* we skip the newline after the `eexec' */
-
- /* 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++;
-
+ if ( cur[1] == 'e' &&
+ cur[2] == 'x' &&
+ cur[3] == 'e' &&
+ cur[4] == 'c' )
break;
- }
}
cur++;
if ( cur >= limit )
@@ -328,9 +322,42 @@
}
}
+ /* 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 */
/* dictionary. We overwrite the base dictionary for disk-based */
/* 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 ) );
--- a/src/type42/t42parse.c
+++ b/src/type42/t42parse.c
@@ -288,7 +288,6 @@
T1_Skip_Spaces( parser );
cur = parser->root.cursor;
-
if ( cur >= limit )
{
FT_ERROR(( "t42_parse_encoding: out of bounds!\n" ));
@@ -363,10 +362,10 @@
/* we only read immediates. */
n = 0;
+ T1_Skip_Spaces( parser );
while ( parser->root.cursor < limit )
{
- T1_Skip_Spaces( parser );
cur = parser->root.cursor;
/* we stop when we encounter `def' or `]' */
@@ -427,6 +426,8 @@
}
else
T1_Skip_PS_Token( parser );
+
+ T1_Skip_Spaces( parser );
}
face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY;