freetype-commit
[Top][All Lists]
Advanced

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

[Git][freetype/freetype][master] [sfnt] Streamline POST format 2.0 handi


From: Alexei Podtelezhnikov (@apodtele)
Subject: [Git][freetype/freetype][master] [sfnt] Streamline POST format 2.0 handing.
Date: Tue, 04 May 2021 02:41:26 +0000

Alexei Podtelezhnikov pushed to branch master at FreeType / FreeType

Commits:

2 changed files:

Changes:

  • ChangeLog
    1
    -2021-04-25  Alexei Podtelezhnikov  <apodtele@gmail.com>
    
    1
    +2021-05-03  Alexei Podtelezhnikov  <apodtele@gmail.com>
    
    2
    +
    
    3
    +	[sfnt] Streamline POST format 2.0 handing.
    
    4
    +
    
    5
    +	To reduce memory allocations, we read an entire Pascal-string buffer
    
    6
    +	and convert it to a C-string buffer.  We also reject tables with
    
    7
    +	Postscript glyph names exceeding 63 bytes.
    
    8
    +
    
    9
    +	* src/sfnt/ttpost.c (load_format20): Implement it.
    
    10
    +	(load_post_names): Check the minimal POST table size.
    
    11
    +	(load_format25, tt_face_free_ps_names): Updated accordingly.
    
    12
    +
    
    13
    +2021-05-02  Alexei Podtelezhnikov  <apodtele@gmail.com>
    
    2 14
     
    
    3 15
     	[bdf,pcf] Avoid memory zeroing (contd.).
    
    4 16
     
    

  • src/sfnt/ttpost.c
    ... ... @@ -158,7 +158,7 @@
    158 158
       static FT_Error
    
    159 159
       load_format_20( TT_Face    face,
    
    160 160
                       FT_Stream  stream,
    
    161
    -                  FT_ULong   post_limit )
    
    161
    +                  FT_ULong   post_len )
    
    162 162
       {
    
    163 163
         FT_Memory   memory = stream->memory;
    
    164 164
         FT_Error    error;
    
    ... ... @@ -168,6 +168,7 @@
    168 168
     
    
    169 169
         FT_UShort*  glyph_indices = NULL;
    
    170 170
         FT_Char**   name_strings  = NULL;
    
    171
    +    FT_Byte*    strings       = NULL;
    
    171 172
     
    
    172 173
     
    
    173 174
         if ( FT_READ_USHORT( num_glyphs ) )
    
    ... ... @@ -179,7 +180,8 @@
    179 180
         /* There already exist fonts which have more than 32768 glyph names */
    
    180 181
         /* in this table, so the test for this threshold has been dropped.  */
    
    181 182
     
    
    182
    -    if ( num_glyphs > face->max_profile.numGlyphs )
    
    183
    +    if ( num_glyphs > face->max_profile.numGlyphs ||
    
    184
    +         num_glyphs * 2UL > post_len - 2          )
    
    183 185
         {
    
    184 186
           error = FT_THROW( Invalid_File_Format );
    
    185 187
           goto Exit;
    
    ... ... @@ -190,8 +192,8 @@
    190 192
           FT_Int  n;
    
    191 193
     
    
    192 194
     
    
    193
    -      if ( FT_QNEW_ARRAY ( glyph_indices, num_glyphs ) ||
    
    194
    -           FT_FRAME_ENTER( num_glyphs * 2L )           )
    
    195
    +      if ( FT_QNEW_ARRAY( glyph_indices, num_glyphs ) ||
    
    196
    +           FT_FRAME_ENTER( num_glyphs * 2L )          )
    
    195 197
             goto Fail;
    
    196 198
     
    
    197 199
           for ( n = 0; n < num_glyphs; n++ )
    
    ... ... @@ -223,60 +225,56 @@
    223 225
         }
    
    224 226
     
    
    225 227
         /* now load the name strings */
    
    228
    +    if ( num_names )
    
    226 229
         {
    
    227 230
           FT_UShort  n;
    
    231
    +      FT_ULong   p;
    
    232
    +
    
    228 233
     
    
    234
    +      post_len -= num_glyphs * 2UL + 2;
    
    229 235
     
    
    230
    -      if ( FT_QNEW_ARRAY( name_strings, num_names ) )
    
    236
    +      if ( FT_QALLOC( strings, post_len + 1 )       ||
    
    237
    +           FT_STREAM_READ( strings, post_len )      ||
    
    238
    +           FT_QNEW_ARRAY( name_strings, num_names ) )
    
    231 239
             goto Fail;
    
    232 240
     
    
    233
    -      for ( n = 0; n < num_names; n++ )
    
    241
    +      /* convert from Pascal- to C-strings and set pointers */
    
    242
    +      for ( p = 0, n = 0; p < post_len && n < num_names; n++ )
    
    234 243
           {
    
    235
    -        FT_UInt  len;
    
    244
    +        FT_UInt  len = strings[p];
    
    236 245
     
    
    237 246
     
    
    238
    -        if ( FT_STREAM_POS() >= post_limit )
    
    239
    -          break;
    
    240
    -        else
    
    241
    -        {
    
    242
    -          FT_TRACE6(( "load_format_20: %ld byte left in post table\n",
    
    243
    -                      post_limit - FT_STREAM_POS() ));
    
    244
    -
    
    245
    -          if ( FT_READ_BYTE( len ) )
    
    246
    -            goto Fail1;
    
    247
    -        }
    
    248
    -
    
    249
    -        if ( len > post_limit                   ||
    
    250
    -             FT_STREAM_POS() > post_limit - len )
    
    247
    +        if ( len > 63U )
    
    251 248
             {
    
    252
    -          FT_Int  d = (FT_Int)post_limit - (FT_Int)FT_STREAM_POS();
    
    253
    -
    
    254
    -
    
    255
    -          FT_ERROR(( "load_format_20:"
    
    256
    -                     " exceeding string length (%d),"
    
    257
    -                     " truncating at end of post table (%d byte left)\n",
    
    258
    -                     len, d ));
    
    259
    -          len = (FT_UInt)FT_MAX( 0, d );
    
    249
    +          error = FT_THROW( Invalid_File_Format );
    
    250
    +          goto Fail;
    
    260 251
             }
    
    261 252
     
    
    262
    -        if ( FT_QNEW_ARRAY( name_strings[n], len + 1 ) ||
    
    263
    -             FT_STREAM_READ( name_strings[n], len    ) )
    
    264
    -          goto Fail1;
    
    265
    -
    
    266
    -        name_strings[n][len] = '\0';
    
    253
    +        strings[p]      = 0;
    
    254
    +        name_strings[n] = (FT_Char*)strings + p + 1;
    
    255
    +        p              += len + 1;
    
    267 256
           }
    
    257
    +      strings[post_len] = 0;
    
    268 258
     
    
    259
    +      /* deal with missing or insufficient string data */
    
    269 260
           if ( n < num_names )
    
    270 261
           {
    
    262
    +        if ( post_len == 0 )
    
    263
    +        {
    
    264
    +          /* fake empty string */
    
    265
    +          if ( FT_QREALLOC( strings, 1, 2 ) )
    
    266
    +            goto Fail;
    
    267
    +
    
    268
    +          post_len = 1;
    
    269
    +          strings[post_len] = 0;
    
    270
    +        }
    
    271
    +
    
    271 272
             FT_ERROR(( "load_format_20:"
    
    272 273
                        " all entries in post table are already parsed,"
    
    273 274
                        " using NULL names for gid %d - %d\n",
    
    274 275
                         n, num_names - 1 ));
    
    275 276
             for ( ; n < num_names; n++ )
    
    276
    -          if ( FT_QNEW_ARRAY( name_strings[n], 1 ) )
    
    277
    -            goto Fail1;
    
    278
    -          else
    
    279
    -            name_strings[n][0] = '\0';
    
    277
    +          name_strings[n] = (FT_Char*)strings + post_len;
    
    280 278
           }
    
    281 279
         }
    
    282 280
     
    
    ... ... @@ -292,17 +290,9 @@
    292 290
         }
    
    293 291
         return FT_Err_Ok;
    
    294 292
     
    
    295
    -  Fail1:
    
    296
    -    {
    
    297
    -      FT_UShort  n;
    
    298
    -
    
    299
    -
    
    300
    -      for ( n = 0; n < num_names; n++ )
    
    301
    -        FT_FREE( name_strings[n] );
    
    302
    -    }
    
    303
    -
    
    304 293
       Fail:
    
    305 294
         FT_FREE( name_strings );
    
    295
    +    FT_FREE( strings );
    
    306 296
         FT_FREE( glyph_indices );
    
    307 297
     
    
    308 298
       Exit:
    
    ... ... @@ -313,7 +303,7 @@
    313 303
       static FT_Error
    
    314 304
       load_format_25( TT_Face    face,
    
    315 305
                       FT_Stream  stream,
    
    316
    -                  FT_ULong   post_limit )
    
    306
    +                  FT_ULong   post_len )
    
    317 307
       {
    
    318 308
         FT_Memory  memory = stream->memory;
    
    319 309
         FT_Error   error;
    
    ... ... @@ -321,7 +311,7 @@
    321 311
         FT_Int     num_glyphs;
    
    322 312
         FT_Char*   offset_table = NULL;
    
    323 313
     
    
    324
    -    FT_UNUSED( post_limit );
    
    314
    +    FT_UNUSED( post_len );
    
    325 315
     
    
    326 316
     
    
    327 317
         if ( FT_READ_USHORT( num_glyphs ) )
    
    ... ... @@ -384,7 +374,6 @@
    384 374
         FT_Error   error;
    
    385 375
         FT_Fixed   format;
    
    386 376
         FT_ULong   post_len;
    
    387
    -    FT_ULong   post_limit;
    
    388 377
     
    
    389 378
     
    
    390 379
         /* get a stream for the face's resource */
    
    ... ... @@ -395,8 +384,6 @@
    395 384
         if ( error )
    
    396 385
           goto Exit;
    
    397 386
     
    
    398
    -    post_limit = FT_STREAM_POS() + post_len;
    
    399
    -
    
    400 387
         format = face->postscript.FormatType;
    
    401 388
     
    
    402 389
         /* go to beginning of subtable */
    
    ... ... @@ -404,10 +391,10 @@
    404 391
           goto Exit;
    
    405 392
     
    
    406 393
         /* now read postscript table */
    
    407
    -    if ( format == 0x00020000L )
    
    408
    -      error = load_format_20( face, stream, post_limit );
    
    409
    -    else if ( format == 0x00025000L )
    
    410
    -      error = load_format_25( face, stream, post_limit );
    
    394
    +    if ( format == 0x00020000L && post_len >= 34 )
    
    395
    +      error = load_format_20( face, stream, post_len - 32 );
    
    396
    +    else if ( format == 0x00025000L && post_len >= 34 )
    
    397
    +      error = load_format_25( face, stream, post_len - 32 );
    
    411 398
         else
    
    412 399
           error = FT_THROW( Invalid_File_Format );
    
    413 400
     
    
    ... ... @@ -433,17 +420,19 @@
    433 420
           if ( format == 0x00020000L )
    
    434 421
           {
    
    435 422
             TT_Post_20  table = &names->names.format_20;
    
    436
    -        FT_UShort   n;
    
    437 423
     
    
    438 424
     
    
    439 425
             FT_FREE( table->glyph_indices );
    
    440 426
             table->num_glyphs = 0;
    
    441 427
     
    
    442
    -        for ( n = 0; n < table->num_names; n++ )
    
    443
    -          FT_FREE( table->glyph_names[n] );
    
    428
    +        if ( table->num_names )
    
    429
    +        {
    
    430
    +          table->glyph_names[0]--;
    
    431
    +          FT_FREE( table->glyph_names[0] );
    
    444 432
     
    
    445
    -        FT_FREE( table->glyph_names );
    
    446
    -        table->num_names = 0;
    
    433
    +          FT_FREE( table->glyph_names );
    
    434
    +          table->num_names = 0;
    
    435
    +        }
    
    447 436
           }
    
    448 437
           else if ( format == 0x00025000L )
    
    449 438
           {
    


  • reply via email to

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