tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

gxvtrak.c (9553B)


      1 /****************************************************************************
      2 *
      3 * gxvtrak.c
      4 *
      5 *   TrueTypeGX/AAT trak table validation (body).
      6 *
      7 * Copyright (C) 2004-2025 by
      8 * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
      9 * David Turner, Robert Wilhelm, and Werner Lemberg.
     10 *
     11 * This file is part of the FreeType project, and may only be used,
     12 * modified, and distributed under the terms of the FreeType project
     13 * license, LICENSE.TXT.  By continuing to use, modify, or distribute
     14 * this file you indicate that you have read the license and
     15 * understand and accept it fully.
     16 *
     17 */
     18 
     19 /****************************************************************************
     20 *
     21 * gxvalid is derived from both gxlayout module and otvalid module.
     22 * Development of gxlayout is supported by the Information-technology
     23 * Promotion Agency(IPA), Japan.
     24 *
     25 */
     26 
     27 
     28 #include "gxvalid.h"
     29 #include "gxvcommn.h"
     30 
     31 
     32  /**************************************************************************
     33   *
     34   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
     35   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
     36   * messages during execution.
     37   */
     38 #undef  FT_COMPONENT
     39 #define FT_COMPONENT  gxvtrak
     40 
     41 
     42  /*************************************************************************/
     43  /*************************************************************************/
     44  /*****                                                               *****/
     45  /*****                      Data and Types                           *****/
     46  /*****                                                               *****/
     47  /*************************************************************************/
     48  /*************************************************************************/
     49 
     50    /*
     51     * referred track table format specification:
     52     * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6trak.html
     53     * last update was 1996.
     54     * ----------------------------------------------
     55     * [MINIMUM HEADER]: GXV_TRAK_SIZE_MIN
     56     * version          (fixed:  32bit) = 0x00010000
     57     * format           (uint16: 16bit) = 0 is only defined (1996)
     58     * horizOffset      (uint16: 16bit)
     59     * vertOffset       (uint16: 16bit)
     60     * reserved         (uint16: 16bit) = 0
     61     * ----------------------------------------------
     62     * [VARIABLE BODY]:
     63     * horizData
     64     *   header         ( 2 + 2 + 4
     65     *   trackTable       + nTracks * ( 4 + 2 + 2 )
     66     *   sizeTable        + nSizes * 4 )
     67     * ----------------------------------------------
     68     * vertData
     69     *   header         ( 2 + 2 + 4
     70     *   trackTable       + nTracks * ( 4 + 2 + 2 )
     71     *   sizeTable        + nSizes * 4 )
     72     * ----------------------------------------------
     73     */
     74  typedef struct  GXV_trak_DataRec_
     75  {
     76    FT_UShort  trackValueOffset_min;
     77    FT_UShort  trackValueOffset_max;
     78 
     79  } GXV_trak_DataRec, *GXV_trak_Data;
     80 
     81 
     82 #define GXV_TRAK_DATA( FIELD )  GXV_TABLE_DATA( trak, FIELD )
     83 
     84 
     85  /*************************************************************************/
     86  /*************************************************************************/
     87  /*****                                                               *****/
     88  /*****                      UTILITY FUNCTIONS                        *****/
     89  /*****                                                               *****/
     90  /*************************************************************************/
     91  /*************************************************************************/
     92 
     93  static void
     94  gxv_trak_trackTable_validate( FT_Bytes       table,
     95                                FT_Bytes       limit,
     96                                FT_UShort      nTracks,
     97                                GXV_Validator  gxvalid )
     98  {
     99    FT_Bytes  p = table;
    100 
    101    FT_Fixed   track, t;
    102    FT_UShort  nameIndex;
    103    FT_UShort  offset;
    104    FT_UShort  i, j;
    105 
    106 
    107    GXV_NAME_ENTER( "trackTable" );
    108 
    109    GXV_TRAK_DATA( trackValueOffset_min ) = 0xFFFFU;
    110    GXV_TRAK_DATA( trackValueOffset_max ) = 0x0000;
    111 
    112    GXV_LIMIT_CHECK( nTracks * ( 4 + 2 + 2 ) );
    113 
    114    for ( i = 0; i < nTracks; i++ )
    115    {
    116      p = table + i * ( 4 + 2 + 2 );
    117      track     = FT_NEXT_LONG( p );
    118      nameIndex = FT_NEXT_USHORT( p );
    119      offset    = FT_NEXT_USHORT( p );
    120 
    121      if ( offset < GXV_TRAK_DATA( trackValueOffset_min ) )
    122        GXV_TRAK_DATA( trackValueOffset_min ) = offset;
    123      if ( offset > GXV_TRAK_DATA( trackValueOffset_max ) )
    124        GXV_TRAK_DATA( trackValueOffset_max ) = offset;
    125 
    126      gxv_sfntName_validate( nameIndex, 256, 32767, gxvalid );
    127 
    128      for ( j = i; j < nTracks; j++ )
    129      {
    130         p = table + j * ( 4 + 2 + 2 );
    131         t = FT_NEXT_LONG( p );
    132         if ( t == track )
    133           GXV_TRACE(( "duplicated entries found for track value 0x%lx\n",
    134                        track ));
    135      }
    136    }
    137 
    138    gxvalid->subtable_length = (FT_ULong)( p - table );
    139    GXV_EXIT;
    140  }
    141 
    142 
    143  static void
    144  gxv_trak_trackData_validate( FT_Bytes       table,
    145                               FT_Bytes       limit,
    146                               GXV_Validator  gxvalid )
    147  {
    148    FT_Bytes   p = table;
    149    FT_UShort  nTracks;
    150    FT_UShort  nSizes;
    151    FT_ULong   sizeTableOffset;
    152 
    153    GXV_ODTECT( 4, odtect );
    154 
    155 
    156    GXV_ODTECT_INIT( odtect );
    157    GXV_NAME_ENTER( "trackData" );
    158 
    159    /* read the header of trackData */
    160    GXV_LIMIT_CHECK( 2 + 2 + 4 );
    161    nTracks         = FT_NEXT_USHORT( p );
    162    nSizes          = FT_NEXT_USHORT( p );
    163    sizeTableOffset = FT_NEXT_ULONG( p );
    164 
    165    gxv_odtect_add_range( table, (FT_ULong)( p - table ),
    166                          "trackData header", odtect );
    167 
    168    /* validate trackTable */
    169    gxv_trak_trackTable_validate( p, limit, nTracks, gxvalid );
    170    gxv_odtect_add_range( p, gxvalid->subtable_length,
    171                          "trackTable", odtect );
    172 
    173    /* sizeTable is array of FT_Fixed, don't check contents */
    174    p = gxvalid->root->base + sizeTableOffset;
    175    GXV_LIMIT_CHECK( nSizes * 4 );
    176    gxv_odtect_add_range( p, nSizes * 4, "sizeTable", odtect );
    177 
    178    /* validate trackValueOffet */
    179    p = gxvalid->root->base + GXV_TRAK_DATA( trackValueOffset_min );
    180    if ( limit - p < nTracks * nSizes * 2 )
    181      GXV_TRACE(( "too short trackValue array\n" ));
    182 
    183    p = gxvalid->root->base + GXV_TRAK_DATA( trackValueOffset_max );
    184    GXV_LIMIT_CHECK( nSizes * 2 );
    185 
    186    gxv_odtect_add_range( gxvalid->root->base
    187                            + GXV_TRAK_DATA( trackValueOffset_min ),
    188                          GXV_TRAK_DATA( trackValueOffset_max )
    189                            - GXV_TRAK_DATA( trackValueOffset_min )
    190                            + nSizes * 2,
    191                          "trackValue array", odtect );
    192 
    193    gxv_odtect_validate( odtect, gxvalid );
    194 
    195    GXV_EXIT;
    196  }
    197 
    198 
    199  /*************************************************************************/
    200  /*************************************************************************/
    201  /*****                                                               *****/
    202  /*****                          trak TABLE                           *****/
    203  /*****                                                               *****/
    204  /*************************************************************************/
    205  /*************************************************************************/
    206 
    207  FT_LOCAL_DEF( void )
    208  gxv_trak_validate( FT_Bytes      table,
    209                     FT_Face       face,
    210                     FT_Validator  ftvalid )
    211  {
    212    FT_Bytes          p = table;
    213    FT_Bytes          limit = 0;
    214 
    215    GXV_ValidatorRec  gxvalidrec;
    216    GXV_Validator     gxvalid = &gxvalidrec;
    217    GXV_trak_DataRec  trakrec;
    218    GXV_trak_Data     trak = &trakrec;
    219 
    220    FT_ULong   version;
    221    FT_UShort  format;
    222    FT_UShort  horizOffset;
    223    FT_UShort  vertOffset;
    224    FT_UShort  reserved;
    225 
    226 
    227    GXV_ODTECT( 3, odtect );
    228 
    229    GXV_ODTECT_INIT( odtect );
    230    gxvalid->root       = ftvalid;
    231    gxvalid->table_data = trak;
    232    gxvalid->face       = face;
    233 
    234    limit = gxvalid->root->limit;
    235 
    236    FT_TRACE3(( "validating `trak' table\n" ));
    237    GXV_INIT;
    238 
    239    GXV_LIMIT_CHECK( 4 + 2 + 2 + 2 + 2 );
    240    version     = FT_NEXT_ULONG( p );
    241    format      = FT_NEXT_USHORT( p );
    242    horizOffset = FT_NEXT_USHORT( p );
    243    vertOffset  = FT_NEXT_USHORT( p );
    244    reserved    = FT_NEXT_USHORT( p );
    245 
    246    GXV_TRACE(( " (version = 0x%08lx)\n", version ));
    247    GXV_TRACE(( " (format = 0x%04x)\n", format ));
    248    GXV_TRACE(( " (horizOffset = 0x%04x)\n", horizOffset ));
    249    GXV_TRACE(( " (vertOffset = 0x%04x)\n", vertOffset ));
    250    GXV_TRACE(( " (reserved = 0x%04x)\n", reserved ));
    251 
    252    /* Version 1.0 (always:1996) */
    253    if ( version != 0x00010000UL )
    254      FT_INVALID_FORMAT;
    255 
    256    /* format 0 (always:1996) */
    257    if ( format != 0x0000 )
    258      FT_INVALID_FORMAT;
    259 
    260    GXV_32BIT_ALIGNMENT_VALIDATE( horizOffset );
    261    GXV_32BIT_ALIGNMENT_VALIDATE( vertOffset );
    262 
    263    /* Reserved Fixed Value (always) */
    264    if ( reserved != 0x0000 )
    265      FT_INVALID_DATA;
    266 
    267    /* validate trackData */
    268    if ( 0 < horizOffset )
    269    {
    270      gxv_trak_trackData_validate( table + horizOffset, limit, gxvalid );
    271      gxv_odtect_add_range( table + horizOffset, gxvalid->subtable_length,
    272                            "horizJustData", odtect );
    273    }
    274 
    275    if ( 0 < vertOffset )
    276    {
    277      gxv_trak_trackData_validate( table + vertOffset, limit, gxvalid );
    278      gxv_odtect_add_range( table + vertOffset, gxvalid->subtable_length,
    279                            "vertJustData", odtect );
    280    }
    281 
    282    gxv_odtect_validate( odtect, gxvalid );
    283 
    284    FT_TRACE4(( "\n" ));
    285  }
    286 
    287 
    288 /* END */