freetype-commit
[Top][All Lists]
Advanced

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

[Git][freetype/freetype][master] [truetype] Prevent glyph program state


From: Werner Lemberg
Subject: [Git][freetype/freetype][master] [truetype] Prevent glyph program state from persisting.
Date: Fri, 02 Apr 2021 08:42:16 +0000

Werner Lemberg pushed to branch master at FreeType / FreeType

Commits:

4 changed files:

Changes:

  • ChangeLog
    1
    +2021-04-02  Ben Wagner  <bungeman@chromium.org>
    
    2
    +
    
    3
    +	[truetype] Prevent glyph program state from persisting.
    
    4
    +
    
    5
    +	`FDEF` instructions are specified as allowed only in 'prep' or
    
    6
    +	'fpgm'.  FreeType has attempted to prevent their use in the glyph
    
    7
    +	program, but they were still allowed in glyph programs if defined in
    
    8
    +	a function defined in 'prep' or 'fpgm' and called from the glyph
    
    9
    +	program.
    
    10
    +
    
    11
    +	Similarly, `IDEF` instructions are specified not to be able to
    
    12
    +	modify any existing instruction.  FreeType has attempted to prevent
    
    13
    +	their use in the glyph program, but they can still be used like
    
    14
    +	`FDEF`.
    
    15
    +
    
    16
    +	This change stores the initial bytecode range type and disallows the
    
    17
    +	use of `FDEF` and `IDEF` while running the glyph program.
    
    18
    +
    
    19
    +	Most other state is copied from the `TT_Size` into the execution
    
    20
    +	context.  However, it is possible for a glyph program to use `WS` to
    
    21
    +	write to the storage area or `WCVTP`, `WCVTF`, and `DELTAC[123]` to
    
    22
    +	write to the control value table.
    
    23
    +
    
    24
    +	Allowing any change to the global state from the glyph program is
    
    25
    +	problematic as the outlines of any given glyph may change based on
    
    26
    +	the order the glyphs are loaded or even how many times they are
    
    27
    +	loaded.  There exist fonts that write to the storage area or the
    
    28
    +	control value table in the glyph program, so their use should not be
    
    29
    +	an error.
    
    30
    +
    
    31
    +	Possible solutions to using these in the glyph program are
    
    32
    +
    
    33
    +	  * ignore the writes;
    
    34
    +	  * value-level copy on write, discard modified values when finished;
    
    35
    +	  * array-level copy on write, discard the copy when finished;
    
    36
    +	  * array-level copy up-front.
    
    37
    +
    
    38
    +	Ignoring the writes may break otherwise good uses.  A full copy
    
    39
    +	up-front was implemented, but was quite heavy as even well behaved
    
    40
    +	fonts required a full copy and the memory management that goes along
    
    41
    +	with it.  Value-level copy on write could use less memory but
    
    42
    +	requires a great deal more record keeping and complexity.  This
    
    43
    +	change implements array-level copy on write.  If any attempt is made
    
    44
    +	to write to the control value table or the storage area when the
    
    45
    +	initial bytecode range was in a glyph program, the relevant array
    
    46
    +	will be copied to a designated storage area and the copy used for
    
    47
    +	the rest of the glyph program's execution.
    
    48
    +
    
    49
    +	* src/truetype/ttinterp.h (TT_ExecContextRec): New fields
    
    50
    +	`iniRange`, `glyfCvtSize`, `glyfCvt`, `origCvt`, `glyfStoreSize`,
    
    51
    +	`glyfStorage`, and `origStorage`.
    
    52
    +
    
    53
    +	* src/truetype/ttinterp.c (Modify_CVT_Check): New function to handle
    
    54
    +	`exc->glyfCvt`.
    
    55
    +	(Write_CVT, Write_CVT_Stretched, Move_CVT, Move_CVT_Stretched): Use
    
    56
    +	it.
    
    57
    +	(Ins_WS): Handle `exc->glyfStorage`.
    
    58
    +	(Ins_FDEF, Ins_IDEF): Updated.
    
    59
    +	(TT_RunIns): Updated.
    
    60
    +	(TT_Done_Context): Free 'glyf' CVT working and storage area.
    
    61
    +	(TT_Load_Context): Fix/add casts.
    
    62
    +
    
    63
    +	* src/truetype/ttgload.c (TT_Load_Simple_Glyph): Fix cast.
    
    64
    +
    
    1 65
     2021-03-30  Dominik Röttsches  <drott@chromium.org>
    
    2 66
     
    
    3 67
     	[sfnt] Check validity of pointer location of `read_color_line`.
    
    ... ... @@ -277,7 +341,7 @@
    277 341
     
    
    278 342
     	[sfnt] Provide optional root transform for 'COLR' v1 glyph graph.
    
    279 343
     
    
    280
    -        * include/freetype/freetype.h (FT_Get_Color_Glyph_Paint):
    
    344
    +	* include/freetype/freetype.h (FT_Get_Color_Glyph_Paint):
    
    281 345
     	Additional function argument `root_transform` to control whether
    
    282 346
     	root transform should be returned.
    
    283 347
     	(FT_OpaquePaint): Additional tracking field to denote whether
    

  • src/truetype/ttgload.c
    ... ... @@ -458,7 +458,7 @@
    458 458
                               (void*)&load->exec->glyphIns,
    
    459 459
                               n_ins );
    
    460 460
     
    
    461
    -      load->exec->glyphSize = (FT_UShort)tmp;
    
    461
    +      load->exec->glyphSize = (FT_UInt)tmp;
    
    462 462
           if ( error )
    
    463 463
             return error;
    
    464 464
     
    

  • src/truetype/ttinterp.c
    ... ... @@ -251,6 +251,14 @@
    251 251
         FT_FREE( exec->stack );
    
    252 252
         exec->stackSize = 0;
    
    253 253
     
    
    254
    +    /* free glyf cvt working area */
    
    255
    +    FT_FREE( exec->glyfCvt );
    
    256
    +    exec->glyfCvtSize = 0;
    
    257
    +
    
    258
    +    /* free glyf storage working area */
    
    259
    +    FT_FREE( exec->glyfStorage );
    
    260
    +    exec->glyfStoreSize = 0;
    
    261
    +
    
    254 262
         /* free call stack */
    
    255 263
         FT_FREE( exec->callStack );
    
    256 264
         exec->callSize = 0;
    
    ... ... @@ -464,13 +472,13 @@
    464 472
         if ( error )
    
    465 473
           return error;
    
    466 474
     
    
    467
    -    tmp = exec->glyphSize;
    
    475
    +    tmp = (FT_ULong)exec->glyphSize;
    
    468 476
         error = Update_Max( exec->memory,
    
    469 477
                             &tmp,
    
    470 478
                             sizeof ( FT_Byte ),
    
    471 479
                             (void*)&exec->glyphIns,
    
    472 480
                             maxp->maxSizeOfInstructions );
    
    473
    -    exec->glyphSize = (FT_UShort)tmp;
    
    481
    +    exec->glyphSize = (FT_UInt)tmp;
    
    474 482
         if ( error )
    
    475 483
           return error;
    
    476 484
     
    
    ... ... @@ -1572,11 +1580,36 @@
    1572 1580
       }
    
    1573 1581
     
    
    1574 1582
     
    
    1583
    +  static void
    
    1584
    +  Modify_CVT_Check( TT_ExecContext  exc )
    
    1585
    +  {
    
    1586
    +    /* TT_RunIns sets origCvt and restores cvt to origCvt when done. */
    
    1587
    +    if ( exc->iniRange == tt_coderange_glyph &&
    
    1588
    +         exc->cvt == exc->origCvt            )
    
    1589
    +    {
    
    1590
    +      exc->error = Update_Max( exc->memory,
    
    1591
    +                               &exc->glyfCvtSize,
    
    1592
    +                               sizeof ( FT_Long ),
    
    1593
    +                               (void*)&exc->glyfCvt,
    
    1594
    +                               exc->cvtSize );
    
    1595
    +      if ( exc->error )
    
    1596
    +        return;
    
    1597
    +
    
    1598
    +      FT_ARRAY_COPY( exc->glyfCvt, exc->cvt, exc->glyfCvtSize );
    
    1599
    +      exc->cvt = exc->glyfCvt;
    
    1600
    +    }
    
    1601
    +  }
    
    1602
    +
    
    1603
    +
    
    1575 1604
       FT_CALLBACK_DEF( void )
    
    1576 1605
       Write_CVT( TT_ExecContext  exc,
    
    1577 1606
                  FT_ULong        idx,
    
    1578 1607
                  FT_F26Dot6      value )
    
    1579 1608
       {
    
    1609
    +    Modify_CVT_Check( exc );
    
    1610
    +    if ( exc->error )
    
    1611
    +      return;
    
    1612
    +
    
    1580 1613
         exc->cvt[idx] = value;
    
    1581 1614
       }
    
    1582 1615
     
    
    ... ... @@ -1586,6 +1619,10 @@
    1586 1619
                            FT_ULong        idx,
    
    1587 1620
                            FT_F26Dot6      value )
    
    1588 1621
       {
    
    1622
    +    Modify_CVT_Check( exc );
    
    1623
    +    if ( exc->error )
    
    1624
    +      return;
    
    1625
    +
    
    1589 1626
         exc->cvt[idx] = FT_DivFix( value, Current_Ratio( exc ) );
    
    1590 1627
       }
    
    1591 1628
     
    
    ... ... @@ -1595,6 +1632,10 @@
    1595 1632
                 FT_ULong        idx,
    
    1596 1633
                 FT_F26Dot6      value )
    
    1597 1634
       {
    
    1635
    +    Modify_CVT_Check( exc );
    
    1636
    +    if ( exc->error )
    
    1637
    +      return;
    
    1638
    +
    
    1598 1639
         exc->cvt[idx] = ADD_LONG( exc->cvt[idx], value );
    
    1599 1640
       }
    
    1600 1641
     
    
    ... ... @@ -1604,6 +1645,10 @@
    1604 1645
                           FT_ULong        idx,
    
    1605 1646
                           FT_F26Dot6      value )
    
    1606 1647
       {
    
    1648
    +    Modify_CVT_Check( exc );
    
    1649
    +    if ( exc->error )
    
    1650
    +      return;
    
    1651
    +
    
    1607 1652
         exc->cvt[idx] = ADD_LONG( exc->cvt[idx],
    
    1608 1653
                                   FT_DivFix( value, Current_Ratio( exc ) ) );
    
    1609 1654
       }
    
    ... ... @@ -3125,7 +3170,30 @@
    3125 3170
             ARRAY_BOUND_ERROR;
    
    3126 3171
         }
    
    3127 3172
         else
    
    3173
    +    {
    
    3174
    +      /* TT_RunIns sets origStorage and restores storage to origStorage */
    
    3175
    +      /* when done.                                                     */
    
    3176
    +      if ( exc->iniRange == tt_coderange_glyph &&
    
    3177
    +           exc->storage == exc->origStorage    )
    
    3178
    +      {
    
    3179
    +        FT_ULong  tmp = (FT_ULong)exc->glyfStoreSize;
    
    3180
    +
    
    3181
    +
    
    3182
    +        exc->error = Update_Max( exc->memory,
    
    3183
    +                                 &tmp,
    
    3184
    +                                 sizeof ( FT_Long ),
    
    3185
    +                                 (void*)&exc->glyfStorage,
    
    3186
    +                                 exc->storeSize );
    
    3187
    +        exc->glyfStoreSize = (FT_UShort)tmp;
    
    3188
    +        if ( exc->error )
    
    3189
    +          return;
    
    3190
    +
    
    3191
    +        FT_ARRAY_COPY( exc->glyfStorage, exc->storage, exc->glyfStoreSize );
    
    3192
    +        exc->storage = exc->glyfStorage;
    
    3193
    +      }
    
    3194
    +
    
    3128 3195
           exc->storage[I] = args[1];
    
    3196
    +    }
    
    3129 3197
       }
    
    3130 3198
     
    
    3131 3199
     
    
    ... ... @@ -3697,7 +3765,7 @@
    3697 3765
     
    
    3698 3766
     
    
    3699 3767
         /* FDEF is only allowed in `prep' or `fpgm' */
    
    3700
    -    if ( exc->curRange == tt_coderange_glyph )
    
    3768
    +    if ( exc->iniRange == tt_coderange_glyph )
    
    3701 3769
         {
    
    3702 3770
           exc->error = FT_THROW( DEF_In_Glyf_Bytecode );
    
    3703 3771
           return;
    
    ... ... @@ -4133,7 +4201,7 @@
    4133 4201
     
    
    4134 4202
     
    
    4135 4203
         /* we enable IDEF only in `prep' or `fpgm' */
    
    4136
    -    if ( exc->curRange == tt_coderange_glyph )
    
    4204
    +    if ( exc->iniRange == tt_coderange_glyph )
    
    4137 4205
         {
    
    4138 4206
           exc->error = FT_THROW( DEF_In_Glyf_Bytecode );
    
    4139 4207
           return;
    
    ... ... @@ -7842,6 +7910,10 @@
    7842 7910
           exc->func_move_cvt  = Move_CVT;
    
    7843 7911
         }
    
    7844 7912
     
    
    7913
    +    exc->origCvt     = exc->cvt;
    
    7914
    +    exc->origStorage = exc->storage;
    
    7915
    +    exc->iniRange    = exc->curRange;
    
    7916
    +
    
    7845 7917
         Compute_Funcs( exc );
    
    7846 7918
         Compute_Round( exc, (FT_Byte)exc->GS.round_state );
    
    7847 7919
     
    
    ... ... @@ -8566,8 +8638,10 @@
    8566 8638
     
    
    8567 8639
           /* increment instruction counter and check if we didn't */
    
    8568 8640
           /* run this program for too long (e.g. infinite loops). */
    
    8569
    -      if ( ++ins_counter > TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES )
    
    8570
    -        return FT_THROW( Execution_Too_Long );
    
    8641
    +      if ( ++ins_counter > TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES ) {
    
    8642
    +        exc->error = FT_THROW( Execution_Too_Long );
    
    8643
    +        goto LErrorLabel_;
    
    8644
    +      }
    
    8571 8645
     
    
    8572 8646
         LSuiteLabel_:
    
    8573 8647
           if ( exc->IP >= exc->codeSize )
    
    ... ... @@ -8586,6 +8660,10 @@
    8586 8660
         FT_TRACE4(( "  %ld instruction%s executed\n",
    
    8587 8661
                     ins_counter,
    
    8588 8662
                     ins_counter == 1 ? "" : "s" ));
    
    8663
    +
    
    8664
    +    exc->cvt     = exc->origCvt;
    
    8665
    +    exc->storage = exc->origStorage;
    
    8666
    +
    
    8589 8667
         return FT_Err_Ok;
    
    8590 8668
     
    
    8591 8669
       LErrorCodeOverflow_:
    
    ... ... @@ -8595,6 +8673,9 @@
    8595 8673
         if ( exc->error && !exc->instruction_trap )
    
    8596 8674
           FT_TRACE1(( "  The interpreter returned error 0x%x\n", exc->error ));
    
    8597 8675
     
    
    8676
    +    exc->cvt     = exc->origCvt;
    
    8677
    +    exc->storage = exc->origStorage;
    
    8678
    +
    
    8598 8679
         return exc->error;
    
    8599 8680
       }
    
    8600 8681
     
    

  • src/truetype/ttinterp.h
    ... ... @@ -175,6 +175,7 @@ FT_BEGIN_HEADER
    175 175
     
    
    176 176
         TT_GraphicsState   GS;         /* current graphics state */
    
    177 177
     
    
    178
    +    FT_Int             iniRange;  /* initial code range number   */
    
    178 179
         FT_Int             curRange;  /* current code range number   */
    
    179 180
         FT_Byte*           code;      /* current code range          */
    
    180 181
         FT_Long            IP;        /* current instruction pointer */
    
    ... ... @@ -187,6 +188,9 @@ FT_BEGIN_HEADER
    187 188
                                       /* increment IP after ins. exec */
    
    188 189
         FT_ULong           cvtSize;
    
    189 190
         FT_Long*           cvt;
    
    191
    +    FT_ULong           glyfCvtSize;
    
    192
    +    FT_Long*           glyfCvt;   /* cvt working copy for glyph */
    
    193
    +    FT_Long*           origCvt;
    
    190 194
     
    
    191 195
         FT_UInt            glyphSize; /* glyph instructions buffer size */
    
    192 196
         FT_Byte*           glyphIns;  /* glyph instructions buffer */
    
    ... ... @@ -213,8 +217,11 @@ FT_BEGIN_HEADER
    213 217
         TT_CodeRangeTable  codeRangeTable;  /* table of valid code ranges */
    
    214 218
                                             /* useful for the debugger   */
    
    215 219
     
    
    216
    -    FT_UShort          storeSize;  /* size of current storage */
    
    217
    -    FT_Long*           storage;    /* storage area            */
    
    220
    +    FT_UShort          storeSize;    /* size of current storage */
    
    221
    +    FT_Long*           storage;      /* storage area            */
    
    222
    +    FT_UShort          glyfStoreSize;
    
    223
    +    FT_Long*           glyfStorage;  /* storage working copy for glyph */
    
    224
    +    FT_Long*           origStorage;
    
    218 225
     
    
    219 226
         FT_F26Dot6         period;     /* values used for the */
    
    220 227
         FT_F26Dot6         phase;      /* `SuperRounding'     */
    


  • reply via email to

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