bugThe FreeType Project - Bugs: bug #37831, ASCII hex encoded Type 1 fonts are...

 
 

bug #37831: ASCII hex encoded Type 1 fonts are no longer parseble

Submitted by:  None
Submitted on:  Thu 29 Nov 2012 06:30:56 PM UTC  
 
Severity: 3 - NormalItem Group: Incorrect behaviour
Status: FixedPrivacy: Public
Assigned to: Werner LEMBERG <wl>Open/Closed: Closed
Planned Release: 2.4.11

Add a New Comment(Rich Markup)
   

You are not logged in

Please log in, so followups can be emailed to you.

 

Thu 29 Nov 2012 08:11:02 PM UTC, comment #1:

Thanks a lot for your analysis and fix! I've just applied it to the git repository.

Regarding the double loop: IIRC, two loops are necessary, but if you can manage it with a single one, I would be glad to add your patch :-)

Werner LEMBERG <wl>
Project AdministratorIn charge of this item.
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.

Anonymous

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach File(s):
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -unavailable- added by wl (Posted a comment)
  •  

    Do you think this task is very important?
    If so, you can click here to add your encouragement to it.
    This task has 0 encouragements so far.

    Only logged-in users can vote.

     

    Please enter the title of George Orwell's famous dystopian book (it's a date):

     

     

    Follow 4 latest changes.

    Date Changed By Updated Field Previous Value => Replaced By
    Thu 29 Nov 2012 08:11:02 PM UTCwlStatusNone=>Fixed
      Assigned toNone=>wl
      Open/ClosedOpen=>Closed
      Planned ReleaseNone=>2.4.11

    Back to the top


    Powered by Savane 3.1-cleanup1