freetype-commit
[Top][All Lists]
Advanced

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

[Git][freetype/freetype][cff-limit-check] [cff] Rework the stream limit


From: Alexei Podtelezhnikov (@apodtele)
Subject: [Git][freetype/freetype][cff-limit-check] [cff] Rework the stream limit checks.
Date: Sun, 19 Mar 2023 14:16:22 +0000

Alexei Podtelezhnikov pushed to branch cff-limit-check at FreeType / FreeType

Commits:

  • 4f0a55d1
    by Alexei Podtelezhnikov at 2023-03-19T10:13:52-04:00
    [cff] Rework the stream limit checks.
    
    The old stream limit checks, before 6986ddac1ece, were good but
    pointless for the crafted t2_strings.  Checking limits there is
    not necessary as they are created to hold all data.  By using two
    conditions, we can detect the actual crossing of the stream boundary
    as appropriate for the stream pointer only.  The t2_strings parsing
    will not be triggering these checks.
    
    * src/cff/cffparse.c (cff_parser_within_limits): Removed.
    (cff_parse_real, cff_parse_integer): Redesign the stream limit check.
    (cff_parse_num, do fixed, cff_parse_fixed_dynamic): Update callers.
    

1 changed file:

Changes:

  • src/cff/cffparse.c
    ... ... @@ -110,55 +110,14 @@
    110 110
       }
    
    111 111
     
    
    112 112
     
    
    113
    -  /* Assuming `first >= last'. */
    
    114
    -
    
    115
    -  static FT_Error
    
    116
    -  cff_parser_within_limits( CFF_Parser  parser,
    
    117
    -                            FT_Byte*    first,
    
    118
    -                            FT_Byte*    last )
    
    119
    -  {
    
    120
    -#ifndef CFF_CONFIG_OPTION_OLD_ENGINE
    
    121
    -
    
    122
    -    /* Fast path for regular FreeType builds with the "new" engine; */
    
    123
    -    /*   `first >= parser->start' can be assumed.                   */
    
    124
    -
    
    125
    -    FT_UNUSED( first );
    
    126
    -
    
    127
    -    return last < parser->limit ? FT_Err_Ok : FT_THROW( Invalid_Argument );
    
    128
    -
    
    129
    -#else /* CFF_CONFIG_OPTION_OLD_ENGINE */
    
    130
    -
    
    131
    -    FT_ListNode  node;
    
    132
    -
    
    133
    -
    
    134
    -    if ( first >= parser->start &&
    
    135
    -         last  <  parser->limit )
    
    136
    -      return FT_Err_Ok;
    
    137
    -
    
    138
    -    node = parser->t2_strings.head;
    
    139
    -
    
    140
    -    while ( node )
    
    141
    -    {
    
    142
    -      CFF_T2_String  t2 = (CFF_T2_String)node->data;
    
    143
    -
    
    144
    -
    
    145
    -      if ( first >= t2->start &&
    
    146
    -           last  <  t2->limit )
    
    147
    -        return FT_Err_Ok;
    
    148
    -
    
    149
    -      node = node->next;
    
    150
    -    }
    
    151
    -
    
    152
    -    return FT_THROW( Invalid_Argument );
    
    153
    -
    
    154
    -#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
    
    155
    -  }
    
    156
    -
    
    113
    +  /* The parser limit checks in the next two functions are supposed */
    
    114
    +  /* to detect the immediate crossing of the stream boundary.  They */
    
    115
    +  /* shall not be triggered from the distant t2_strings buffers.    */
    
    157 116
     
    
    158 117
       /* read an integer */
    
    159 118
       static FT_Long
    
    160
    -  cff_parse_integer( CFF_Parser  parser,
    
    161
    -                     FT_Byte*    start )
    
    119
    +  cff_parse_integer( FT_Byte*  start,
    
    120
    +                     FT_Byte*  limit )
    
    162 121
       {
    
    163 122
         FT_Byte*  p   = start;
    
    164 123
         FT_Int    v   = *p++;
    
    ... ... @@ -167,14 +126,14 @@
    167 126
     
    
    168 127
         if ( v == 28 )
    
    169 128
         {
    
    170
    -      if ( cff_parser_within_limits( parser, p, p + 1 ) )
    
    129
    +      if ( p + 2 > limit && limit >= p )
    
    171 130
             goto Bad;
    
    172 131
     
    
    173 132
           val = (FT_Short)( ( (FT_UShort)p[0] << 8 ) | p[1] );
    
    174 133
         }
    
    175 134
         else if ( v == 29 )
    
    176 135
         {
    
    177
    -      if ( cff_parser_within_limits( parser, p, p + 3 ) )
    
    136
    +      if ( p + 4 > limit && limit >= p )
    
    178 137
             goto Bad;
    
    179 138
     
    
    180 139
           val = (FT_Long)( ( (FT_ULong)p[0] << 24 ) |
    
    ... ... @@ -188,14 +147,14 @@
    188 147
         }
    
    189 148
         else if ( v < 251 )
    
    190 149
         {
    
    191
    -      if ( cff_parser_within_limits( parser, p, p ) )
    
    150
    +      if ( p + 1 > limit && limit >= p )
    
    192 151
             goto Bad;
    
    193 152
     
    
    194 153
           val = ( v - 247 ) * 256 + p[0] + 108;
    
    195 154
         }
    
    196 155
         else
    
    197 156
         {
    
    198
    -      if ( cff_parser_within_limits( parser, p, p ) )
    
    157
    +      if ( p + 1 > limit && limit >= p )
    
    199 158
             goto Bad;
    
    200 159
     
    
    201 160
           val = -( v - 251 ) * 256 - p[0] - 108;
    
    ... ... @@ -244,10 +203,10 @@
    244 203
     
    
    245 204
       /* read a real */
    
    246 205
       static FT_Fixed
    
    247
    -  cff_parse_real( CFF_Parser  parser,
    
    248
    -                  FT_Byte*    start,
    
    249
    -                  FT_Long     power_ten,
    
    250
    -                  FT_Long*    scaling )
    
    206
    +  cff_parse_real( FT_Byte*  start,
    
    207
    +                  FT_Byte*  limit,
    
    208
    +                  FT_Long   power_ten,
    
    209
    +                  FT_Long*  scaling )
    
    251 210
       {
    
    252 211
         FT_Byte*  p = start;
    
    253 212
         FT_Int    nib;
    
    ... ... @@ -282,7 +241,7 @@
    282 241
             p++;
    
    283 242
     
    
    284 243
             /* Make sure we don't read past the end. */
    
    285
    -        if ( cff_parser_within_limits( parser, p, p ) )
    
    244
    +        if ( p + 1 > limit && limit >= p )
    
    286 245
               goto Bad;
    
    287 246
           }
    
    288 247
     
    
    ... ... @@ -319,7 +278,7 @@
    319 278
               p++;
    
    320 279
     
    
    321 280
               /* Make sure we don't read past the end. */
    
    322
    -          if ( cff_parser_within_limits( parser, p, p ) )
    
    281
    +          if ( p + 1 > limit && limit >= p )
    
    323 282
                 goto Bad;
    
    324 283
             }
    
    325 284
     
    
    ... ... @@ -358,7 +317,7 @@
    358 317
               p++;
    
    359 318
     
    
    360 319
               /* Make sure we don't read past the end. */
    
    361
    -          if ( cff_parser_within_limits( parser, p, p ) )
    
    320
    +          if ( p + 1 > limit && limit >= p )
    
    362 321
                 goto Bad;
    
    363 322
             }
    
    364 323
     
    
    ... ... @@ -525,7 +484,7 @@
    525 484
         if ( **d == 30 )
    
    526 485
         {
    
    527 486
           /* binary-coded decimal is truncated to integer */
    
    528
    -      return cff_parse_real( parser, *d, 0, NULL ) >> 16;
    
    487
    +      return cff_parse_real( *d, parser->limit, 0, NULL ) >> 16;
    
    529 488
         }
    
    530 489
     
    
    531 490
         else if ( **d == 255 )
    
    ... ... @@ -551,7 +510,7 @@
    551 510
         }
    
    552 511
     
    
    553 512
         else
    
    554
    -      return cff_parse_integer( parser, *d );
    
    513
    +      return cff_parse_integer( *d, parser->limit );
    
    555 514
       }
    
    556 515
     
    
    557 516
     
    
    ... ... @@ -562,10 +521,10 @@
    562 521
                 FT_Long     scaling )
    
    563 522
       {
    
    564 523
         if ( **d == 30 )
    
    565
    -      return cff_parse_real( parser, *d, scaling, NULL );
    
    524
    +      return cff_parse_real( *d, parser->limit, scaling, NULL );
    
    566 525
         else
    
    567 526
         {
    
    568
    -      FT_Long  val = cff_parse_integer( parser, *d );
    
    527
    +      FT_Long  val = cff_parse_integer( *d, parser->limit );
    
    569 528
     
    
    570 529
     
    
    571 530
           if ( scaling )
    
    ... ... @@ -630,14 +589,14 @@
    630 589
         FT_ASSERT( scaling );
    
    631 590
     
    
    632 591
         if ( **d == 30 )
    
    633
    -      return cff_parse_real( parser, *d, 0, scaling );
    
    592
    +      return cff_parse_real( *d, parser->limit, 0, scaling );
    
    634 593
         else
    
    635 594
         {
    
    636 595
           FT_Long  number;
    
    637 596
           FT_Int   integer_length;
    
    638 597
     
    
    639 598
     
    
    640
    -      number = cff_parse_integer( parser, d[0] );
    
    599
    +      number = cff_parse_integer( *d, parser->limit );
    
    641 600
     
    
    642 601
           if ( number > 0x7FFFL )
    
    643 602
           {
    


  • reply via email to

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