Thu 29 Nov 2012 06:30:56 PM UTC, original submission:
I believe commit ebda8b32573726cd6da483b4018913dc2d3f2bb4 has introduced a regression : no longer being able to parse ASCII hex encoded Type 1 fonts.
In T1_Get_Private_Dict() @ src/type1/t1parse.c it wrongly assumes binary encoded Type 1 for ASCII hex encoded Type 1 fonts because the following test fails:
--8<--
if ( cur + 3 < limit &&
ft_isxdigit( cur[0] ) && ft_isxdigit( cur[1] ) &&
ft_isxdigit( cur[2] ) && ft_isxdigit( cur[3] ) )
--8<--
At that point limit is exactly 3 bytes ahead of cur so we don't even try to check if we have 4 hex digits at cur.
The reason is as follows:
--8<--
/* 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;
--8<--
At this point we have a wrong 'limit' value. cur is pointing to the beginning of "eexec" string and the limit is 9 bytes ahead. The limit is an exclusive limit, i.e. "eexec" + 1 newline + 4 characters is beyond that limit).
--8<--
while ( cur < limit )
{
if ( cur == 'e' && ft_strncmp( (char)cur, "eexec", 5 ) == 0 )
goto Found;
T1_Skip_PS_Token( parser );
if ( parser->root.error )
break;
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;
--8<--
Aside, I'm not sure why we have the first eexec search loop when we need this 2nd search loop. Can't we just only have the latter ?
--8<--
/* we need to access the next 4 bytes (after the final \r following */
/* the `eexec' keyword); if they all are hexadecimal digits, then */
/* we have a case of ASCII storage */
if ( cur + 3 < limit &&
ft_isxdigit( cur[0] ) && ft_isxdigit( cur[1] ) &&
ft_isxdigit( cur[2] ) && ft_isxdigit( cur[3] ) )
{
/* ASCII hexadecimal encoding */
--8<--
As for ASCII hex encoded fonts, limit is exactly 3 bytes ahead of cur (cur has been increased with sizeof("eexec")-1 + 1 newline), this test always fails. My suggestion is to change:
parser->root.limit = cur + 9;
to
parser->root.limit = cur + 10;
John.
|