freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[freetype2] master 907952100: [type1] Directly search for eexec in priva


From: Werner Lemberg
Subject: [freetype2] master 907952100: [type1] Directly search for eexec in private dict
Date: Thu, 16 Jun 2022 11:02:35 -0400 (EDT)

branch: master
commit 9079521002231862d5202ff7ec8d628e27972673
Author: Ben Wagner <bungeman@chromium.org>
Commit: Ben Wagner <bungeman@chromium.org>

    [type1] Directly search for eexec in private dict
    
    This code originally just searched for `eexec`. This was later modified
    to check that the `eexec` found is valid (not in a string or comment).
    This was done by searching for `eexec` as before and then, for each
    `eexec` found, searching from the beginning using the correct parsing to
    see if the `eexec` was still found. If the private dictionary is large
    and contains many copies of `eexec` which are not valid, the initial
    part of the private dictionary is scanned once for each, potentially
    leading to n^2 parsing time.
    
    Instead of finding an initial `eexec` and then re-parsing to discover if
    it is valid, drop the initial search for `eexec` and just parse to find
    a valid `eexec`. This is strictly faster since the validation must
    happen anyway and avoids restarting from the beginning each time an
    `eexec` is found in the data.
    
    * src/type1/t1parse.c (T1_Get_Private_Dict): avoid n^2 parsing
    
    Bug: https://bugs.chromium.org/p/chromium/issues/detail?id=1328883
---
 src/type1/t1parse.c | 55 +++++++++--------------------------------------------
 1 file changed, 9 insertions(+), 46 deletions(-)

diff --git a/src/type1/t1parse.c b/src/type1/t1parse.c
index 95dc97d79..af9df3222 100644
--- a/src/type1/t1parse.c
+++ b/src/type1/t1parse.c
@@ -330,50 +330,25 @@
       /* the private dict.  Otherwise, simply overwrite into the base  */
       /* dictionary block in the heap.                                 */
 
-      /* first of all, look at the `eexec' keyword */
+      /* First look for the `eexec' keyword. Ensure `eexec' is real -- */
+      /* it could be in a comment or string (as e.g. in u003043t.gsf   */
+      /* from ghostscript).                                            */
       FT_Byte*    cur   = parser->base_dict;
       FT_Byte*    limit = cur + parser->base_len;
       FT_Pointer  pos_lf;
       FT_Bool     test_cr;
 
 
-    Again:
-      for (;;)
-      {
-        if ( cur[0] == 'e'   &&
-             cur + 9 < limit )      /* 9 = 5 letters for `eexec' + */
-                                    /* whitespace + 4 chars        */
-        {
-          if ( cur[1] == 'e' &&
-               cur[2] == 'x' &&
-               cur[3] == 'e' &&
-               cur[4] == 'c' )
-            break;
-        }
-        cur++;
-        if ( cur >= limit )
-        {
-          FT_ERROR(( "T1_Get_Private_Dict:"
-                     " could not find `eexec' keyword\n" ));
-          error = FT_THROW( Invalid_File_Format );
-          goto Exit;
-        }
-      }
-
-      /* 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;
-      /* set limit to `eexec' + whitespace + 4 characters */
-      parser->root.limit  = cur + 10;
+      parser->root.limit  = parser->base_dict + parser->base_len;
 
       cur   = parser->root.cursor;
       limit = parser->root.limit;
 
       while ( cur < limit )
       {
-        if ( cur[0] == 'e'   &&
-             cur + 5 < limit )
+        /* 9 = 5 letters for `eexec' + whitespace + 4 chars */
+        if ( cur[0] == 'e' && cur + 9 < limit )
         {
           if ( cur[1] == 'e' &&
                cur[2] == 'x' &&
@@ -389,21 +364,9 @@
         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;
-
-      if ( cur >= limit )
-      {
-        FT_ERROR(( "T1_Get_Private_Dict:"
-                   " premature end in private dictionary\n" ));
-        error = FT_THROW( Invalid_File_Format );
-        goto Exit;
-      }
-
-      goto Again;
+      FT_ERROR(( "T1_Get_Private_Dict: could not find `eexec' keyword\n" ));
+      error = FT_THROW( Invalid_File_Format );
+      goto Exit;
 
       /* now determine where to write the _encrypted_ binary private  */
       /* dictionary.  We overwrite the base dictionary for disk-based */



reply via email to

[Prev in Thread] Current Thread [Next in Thread]