freetype-commit
[Top][All Lists]
Advanced

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

[Git][freetype/freetype][master] [type1] Directly search for eexec in pr


From: Ben Wagner (@bungeman)
Subject: [Git][freetype/freetype][master] [type1] Directly search for eexec in private dict
Date: Thu, 16 Jun 2022 15:02:28 +0000

Ben Wagner pushed to branch master at FreeType / FreeType

Commits:

  • 90795210
    by Ben Wagner at 2022-06-16T14:51:57+00:00
    [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
    

1 changed file:

Changes:

  • src/type1/t1parse.c
    ... ... @@ -330,50 +330,25 @@
    330 330
           /* the private dict.  Otherwise, simply overwrite into the base  */
    
    331 331
           /* dictionary block in the heap.                                 */
    
    332 332
     
    
    333
    -      /* first of all, look at the `eexec' keyword */
    
    333
    +      /* First look for the `eexec' keyword. Ensure `eexec' is real -- */
    
    334
    +      /* it could be in a comment or string (as e.g. in u003043t.gsf   */
    
    335
    +      /* from ghostscript).                                            */
    
    334 336
           FT_Byte*    cur   = parser->base_dict;
    
    335 337
           FT_Byte*    limit = cur + parser->base_len;
    
    336 338
           FT_Pointer  pos_lf;
    
    337 339
           FT_Bool     test_cr;
    
    338 340
     
    
    339 341
     
    
    340
    -    Again:
    
    341
    -      for (;;)
    
    342
    -      {
    
    343
    -        if ( cur[0] == 'e'   &&
    
    344
    -             cur + 9 < limit )      /* 9 = 5 letters for `eexec' + */
    
    345
    -                                    /* whitespace + 4 chars        */
    
    346
    -        {
    
    347
    -          if ( cur[1] == 'e' &&
    
    348
    -               cur[2] == 'x' &&
    
    349
    -               cur[3] == 'e' &&
    
    350
    -               cur[4] == 'c' )
    
    351
    -            break;
    
    352
    -        }
    
    353
    -        cur++;
    
    354
    -        if ( cur >= limit )
    
    355
    -        {
    
    356
    -          FT_ERROR(( "T1_Get_Private_Dict:"
    
    357
    -                     " could not find `eexec' keyword\n" ));
    
    358
    -          error = FT_THROW( Invalid_File_Format );
    
    359
    -          goto Exit;
    
    360
    -        }
    
    361
    -      }
    
    362
    -
    
    363
    -      /* check whether `eexec' was real -- it could be in a comment */
    
    364
    -      /* or string (as e.g. in u003043t.gsf from ghostscript)       */
    
    365
    -
    
    366 342
           parser->root.cursor = parser->base_dict;
    
    367
    -      /* set limit to `eexec' + whitespace + 4 characters */
    
    368
    -      parser->root.limit  = cur + 10;
    
    343
    +      parser->root.limit  = parser->base_dict + parser->base_len;
    
    369 344
     
    
    370 345
           cur   = parser->root.cursor;
    
    371 346
           limit = parser->root.limit;
    
    372 347
     
    
    373 348
           while ( cur < limit )
    
    374 349
           {
    
    375
    -        if ( cur[0] == 'e'   &&
    
    376
    -             cur + 5 < limit )
    
    350
    +        /* 9 = 5 letters for `eexec' + whitespace + 4 chars */
    
    351
    +        if ( cur[0] == 'e' && cur + 9 < limit )
    
    377 352
             {
    
    378 353
               if ( cur[1] == 'e' &&
    
    379 354
                    cur[2] == 'x' &&
    
    ... ... @@ -389,21 +364,9 @@
    389 364
             cur = parser->root.cursor;
    
    390 365
           }
    
    391 366
     
    
    392
    -      /* we haven't found the correct `eexec'; go back and continue */
    
    393
    -      /* searching                                                  */
    
    394
    -
    
    395
    -      cur   = limit;
    
    396
    -      limit = parser->base_dict + parser->base_len;
    
    397
    -
    
    398
    -      if ( cur >= limit )
    
    399
    -      {
    
    400
    -        FT_ERROR(( "T1_Get_Private_Dict:"
    
    401
    -                   " premature end in private dictionary\n" ));
    
    402
    -        error = FT_THROW( Invalid_File_Format );
    
    403
    -        goto Exit;
    
    404
    -      }
    
    405
    -
    
    406
    -      goto Again;
    
    367
    +      FT_ERROR(( "T1_Get_Private_Dict: could not find `eexec' keyword\n" ));
    
    368
    +      error = FT_THROW( Invalid_File_Format );
    
    369
    +      goto Exit;
    
    407 370
     
    
    408 371
           /* now determine where to write the _encrypted_ binary private  */
    
    409 372
           /* dictionary.  We overwrite the base dictionary for disk-based */
    


  • reply via email to

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