tor-browser

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

otvmath.c (13656B)


      1 /****************************************************************************
      2 *
      3 * otvmath.c
      4 *
      5 *   OpenType MATH table validation (body).
      6 *
      7 * Copyright (C) 2007-2025 by
      8 * David Turner, Robert Wilhelm, and Werner Lemberg.
      9 *
     10 * Written by George Williams.
     11 *
     12 * This file is part of the FreeType project, and may only be used,
     13 * modified, and distributed under the terms of the FreeType project
     14 * license, LICENSE.TXT.  By continuing to use, modify, or distribute
     15 * this file you indicate that you have read the license and
     16 * understand and accept it fully.
     17 *
     18 */
     19 
     20 
     21 #include "otvalid.h"
     22 #include "otvcommn.h"
     23 #include "otvgpos.h"
     24 
     25 
     26  /**************************************************************************
     27   *
     28   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
     29   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
     30   * messages during execution.
     31   */
     32 #undef  FT_COMPONENT
     33 #define FT_COMPONENT  otvmath
     34 
     35 
     36 
     37  /*************************************************************************/
     38  /*************************************************************************/
     39  /*****                                                               *****/
     40  /*****                  MATH TYPOGRAPHIC CONSTANTS                   *****/
     41  /*****                                                               *****/
     42  /*************************************************************************/
     43  /*************************************************************************/
     44 
     45  static void
     46  otv_MathConstants_validate( FT_Bytes       table,
     47                              OTV_Validator  otvalid )
     48  {
     49    FT_Bytes  p = table;
     50    FT_UInt   i;
     51    FT_UInt   table_size;
     52 
     53    OTV_OPTIONAL_TABLE( DeviceTableOffset );
     54 
     55 
     56    OTV_NAME_ENTER( "MathConstants" );
     57 
     58    /* 56 constants, 51 have device tables */
     59    OTV_LIMIT_CHECK( 2 * ( 56 + 51 ) );
     60    table_size = 2 * ( 56 + 51 );
     61 
     62    p += 4 * 2;                 /* First 4 constants have no device tables */
     63    for ( i = 0; i < 51; i++ )
     64    {
     65      p += 2;                                            /* skip the value */
     66      OTV_OPTIONAL_OFFSET( DeviceTableOffset );
     67      OTV_SIZE_CHECK( DeviceTableOffset );
     68      if ( DeviceTableOffset )
     69        otv_Device_validate( table + DeviceTableOffset, otvalid );
     70    }
     71 
     72    OTV_EXIT;
     73  }
     74 
     75 
     76  /*************************************************************************/
     77  /*************************************************************************/
     78  /*****                                                               *****/
     79  /*****                   MATH ITALICS CORRECTION                     *****/
     80  /*****                 MATH TOP ACCENT ATTACHMENT                    *****/
     81  /*****                                                               *****/
     82  /*************************************************************************/
     83  /*************************************************************************/
     84 
     85  static void
     86  otv_MathItalicsCorrectionInfo_validate( FT_Bytes       table,
     87                                          OTV_Validator  otvalid,
     88                                          FT_Int         isItalic )
     89  {
     90    FT_Bytes  p = table;
     91    FT_UInt   i, cnt, table_size;
     92 
     93    OTV_OPTIONAL_TABLE( Coverage );
     94    OTV_OPTIONAL_TABLE( DeviceTableOffset );
     95 
     96    FT_UNUSED( isItalic );  /* only used if tracing is active */
     97 
     98 
     99    OTV_NAME_ENTER( isItalic ? "MathItalicsCorrectionInfo"
    100                             : "MathTopAccentAttachment" );
    101 
    102    OTV_LIMIT_CHECK( 4 );
    103 
    104    OTV_OPTIONAL_OFFSET( Coverage );
    105    cnt = FT_NEXT_USHORT( p );
    106 
    107    OTV_LIMIT_CHECK( 4 * cnt );
    108    table_size = 4 + 4 * cnt;
    109 
    110    OTV_SIZE_CHECK( Coverage );
    111    otv_Coverage_validate( table + Coverage, otvalid, (FT_Int)cnt );
    112 
    113    for ( i = 0; i < cnt; i++ )
    114    {
    115      p += 2;                                            /* Skip the value */
    116      OTV_OPTIONAL_OFFSET( DeviceTableOffset );
    117      OTV_SIZE_CHECK( DeviceTableOffset );
    118      if ( DeviceTableOffset )
    119        otv_Device_validate( table + DeviceTableOffset, otvalid );
    120    }
    121 
    122    OTV_EXIT;
    123  }
    124 
    125 
    126  /*************************************************************************/
    127  /*************************************************************************/
    128  /*****                                                               *****/
    129  /*****                           MATH KERNING                        *****/
    130  /*****                                                               *****/
    131  /*************************************************************************/
    132  /*************************************************************************/
    133 
    134  static void
    135  otv_MathKern_validate( FT_Bytes       table,
    136                         OTV_Validator  otvalid )
    137  {
    138    FT_Bytes  p = table;
    139    FT_UInt   i, cnt, table_size;
    140 
    141    OTV_OPTIONAL_TABLE( DeviceTableOffset );
    142 
    143 
    144    /* OTV_NAME_ENTER( "MathKern" ); */
    145 
    146    OTV_LIMIT_CHECK( 2 );
    147 
    148    cnt = FT_NEXT_USHORT( p );
    149 
    150    OTV_LIMIT_CHECK( 4 * cnt + 2 );
    151    table_size = 4 + 4 * cnt;
    152 
    153    /* Heights */
    154    for ( i = 0; i < cnt; i++ )
    155    {
    156      p += 2;                                            /* Skip the value */
    157      OTV_OPTIONAL_OFFSET( DeviceTableOffset );
    158      OTV_SIZE_CHECK( DeviceTableOffset );
    159      if ( DeviceTableOffset )
    160        otv_Device_validate( table + DeviceTableOffset, otvalid );
    161    }
    162 
    163    /* One more Kerning value */
    164    for ( i = 0; i < cnt + 1; i++ )
    165    {
    166      p += 2;                                            /* Skip the value */
    167      OTV_OPTIONAL_OFFSET( DeviceTableOffset );
    168      OTV_SIZE_CHECK( DeviceTableOffset );
    169      if ( DeviceTableOffset )
    170        otv_Device_validate( table + DeviceTableOffset, otvalid );
    171    }
    172 
    173    OTV_EXIT;
    174  }
    175 
    176 
    177  static void
    178  otv_MathKernInfo_validate( FT_Bytes       table,
    179                             OTV_Validator  otvalid )
    180  {
    181    FT_Bytes  p = table;
    182    FT_UInt   i, j, cnt, table_size;
    183 
    184    OTV_OPTIONAL_TABLE( Coverage );
    185    OTV_OPTIONAL_TABLE( MKRecordOffset );
    186 
    187 
    188    OTV_NAME_ENTER( "MathKernInfo" );
    189 
    190    OTV_LIMIT_CHECK( 4 );
    191 
    192    OTV_OPTIONAL_OFFSET( Coverage );
    193    cnt = FT_NEXT_USHORT( p );
    194 
    195    OTV_LIMIT_CHECK( 8 * cnt );
    196    table_size = 4 + 8 * cnt;
    197 
    198    OTV_SIZE_CHECK( Coverage );
    199    otv_Coverage_validate( table + Coverage, otvalid, (FT_Int)cnt );
    200 
    201    for ( i = 0; i < cnt; i++ )
    202    {
    203      for ( j = 0; j < 4; j++ )
    204      {
    205        OTV_OPTIONAL_OFFSET( MKRecordOffset );
    206        OTV_SIZE_CHECK( MKRecordOffset );
    207        if ( MKRecordOffset )
    208          otv_MathKern_validate( table + MKRecordOffset, otvalid );
    209      }
    210    }
    211 
    212    OTV_EXIT;
    213  }
    214 
    215 
    216  /*************************************************************************/
    217  /*************************************************************************/
    218  /*****                                                               *****/
    219  /*****                         MATH GLYPH INFO                       *****/
    220  /*****                                                               *****/
    221  /*************************************************************************/
    222  /*************************************************************************/
    223 
    224  static void
    225  otv_MathGlyphInfo_validate( FT_Bytes       table,
    226                              OTV_Validator  otvalid )
    227  {
    228    FT_Bytes  p = table;
    229    FT_UInt   MathItalicsCorrectionInfo, MathTopAccentAttachment;
    230    FT_UInt   ExtendedShapeCoverage, MathKernInfo;
    231 
    232 
    233    OTV_NAME_ENTER( "MathGlyphInfo" );
    234 
    235    OTV_LIMIT_CHECK( 8 );
    236 
    237    MathItalicsCorrectionInfo = FT_NEXT_USHORT( p );
    238    MathTopAccentAttachment   = FT_NEXT_USHORT( p );
    239    ExtendedShapeCoverage     = FT_NEXT_USHORT( p );
    240    MathKernInfo              = FT_NEXT_USHORT( p );
    241 
    242    if ( MathItalicsCorrectionInfo )
    243      otv_MathItalicsCorrectionInfo_validate(
    244        table + MathItalicsCorrectionInfo, otvalid, TRUE );
    245 
    246    /* Italic correction and Top Accent Attachment have the same format */
    247    if ( MathTopAccentAttachment )
    248      otv_MathItalicsCorrectionInfo_validate(
    249        table + MathTopAccentAttachment, otvalid, FALSE );
    250 
    251    if ( ExtendedShapeCoverage )
    252    {
    253      OTV_NAME_ENTER( "ExtendedShapeCoverage" );
    254      otv_Coverage_validate( table + ExtendedShapeCoverage, otvalid, -1 );
    255      OTV_EXIT;
    256    }
    257 
    258    if ( MathKernInfo )
    259      otv_MathKernInfo_validate( table + MathKernInfo, otvalid );
    260 
    261    OTV_EXIT;
    262  }
    263 
    264 
    265  /*************************************************************************/
    266  /*************************************************************************/
    267  /*****                                                               *****/
    268  /*****                    MATH GLYPH CONSTRUCTION                    *****/
    269  /*****                                                               *****/
    270  /*************************************************************************/
    271  /*************************************************************************/
    272 
    273  static void
    274  otv_GlyphAssembly_validate( FT_Bytes       table,
    275                              OTV_Validator  otvalid )
    276  {
    277    FT_Bytes  p = table;
    278    FT_UInt   pcnt, table_size;
    279    FT_UInt   i;
    280 
    281    OTV_OPTIONAL_TABLE( DeviceTableOffset );
    282 
    283 
    284    /* OTV_NAME_ENTER( "GlyphAssembly" ); */
    285 
    286    OTV_LIMIT_CHECK( 6 );
    287 
    288    p += 2;                           /* Skip the Italics Correction value */
    289    OTV_OPTIONAL_OFFSET( DeviceTableOffset );
    290    pcnt = FT_NEXT_USHORT( p );
    291 
    292    OTV_LIMIT_CHECK( 8 * pcnt );
    293    table_size = 6 + 8 * pcnt;
    294 
    295    OTV_SIZE_CHECK( DeviceTableOffset );
    296    if ( DeviceTableOffset )
    297      otv_Device_validate( table + DeviceTableOffset, otvalid );
    298 
    299    for ( i = 0; i < pcnt; i++ )
    300    {
    301      FT_UInt  gid;
    302 
    303 
    304      gid = FT_NEXT_USHORT( p );
    305      if ( gid >= otvalid->glyph_count )
    306        FT_INVALID_GLYPH_ID;
    307      p += 2*4;             /* skip the Start, End, Full, and Flags fields */
    308    }
    309 
    310    /* OTV_EXIT; */
    311  }
    312 
    313 
    314  static void
    315  otv_MathGlyphConstruction_validate( FT_Bytes       table,
    316                                      OTV_Validator  otvalid )
    317  {
    318    FT_Bytes  p = table;
    319    FT_UInt   vcnt, table_size;
    320    FT_UInt   i;
    321 
    322    OTV_OPTIONAL_TABLE( GlyphAssembly );
    323 
    324 
    325    /* OTV_NAME_ENTER( "MathGlyphConstruction" ); */
    326 
    327    OTV_LIMIT_CHECK( 4 );
    328 
    329    OTV_OPTIONAL_OFFSET( GlyphAssembly );
    330    vcnt = FT_NEXT_USHORT( p );
    331 
    332    OTV_LIMIT_CHECK( 4 * vcnt );
    333    table_size = 4 + 4 * vcnt;
    334 
    335    for ( i = 0; i < vcnt; i++ )
    336    {
    337      FT_UInt  gid;
    338 
    339 
    340      gid = FT_NEXT_USHORT( p );
    341      if ( gid >= otvalid->glyph_count )
    342        FT_INVALID_GLYPH_ID;
    343      p += 2;                          /* skip the size */
    344    }
    345 
    346    OTV_SIZE_CHECK( GlyphAssembly );
    347    if ( GlyphAssembly )
    348      otv_GlyphAssembly_validate( table+GlyphAssembly, otvalid );
    349 
    350    /* OTV_EXIT; */
    351  }
    352 
    353 
    354  static void
    355  otv_MathVariants_validate( FT_Bytes       table,
    356                             OTV_Validator  otvalid )
    357  {
    358    FT_Bytes  p = table;
    359    FT_UInt   vcnt, hcnt, i, table_size;
    360 
    361    OTV_OPTIONAL_TABLE( VCoverage );
    362    OTV_OPTIONAL_TABLE( HCoverage );
    363    OTV_OPTIONAL_TABLE( Offset );
    364 
    365 
    366    OTV_NAME_ENTER( "MathVariants" );
    367 
    368    OTV_LIMIT_CHECK( 10 );
    369 
    370    p += 2;                       /* Skip the MinConnectorOverlap constant */
    371    OTV_OPTIONAL_OFFSET( VCoverage );
    372    OTV_OPTIONAL_OFFSET( HCoverage );
    373    vcnt = FT_NEXT_USHORT( p );
    374    hcnt = FT_NEXT_USHORT( p );
    375 
    376    OTV_LIMIT_CHECK( 2 * vcnt + 2 * hcnt );
    377    table_size = 10 + 2 * vcnt + 2 * hcnt;
    378 
    379    OTV_SIZE_CHECK( VCoverage );
    380    if ( VCoverage )
    381      otv_Coverage_validate( table + VCoverage, otvalid, (FT_Int)vcnt );
    382 
    383    OTV_SIZE_CHECK( HCoverage );
    384    if ( HCoverage )
    385      otv_Coverage_validate( table + HCoverage, otvalid, (FT_Int)hcnt );
    386 
    387    for ( i = 0; i < vcnt; i++ )
    388    {
    389      OTV_OPTIONAL_OFFSET( Offset );
    390      OTV_SIZE_CHECK( Offset );
    391      otv_MathGlyphConstruction_validate( table + Offset, otvalid );
    392    }
    393 
    394    for ( i = 0; i < hcnt; i++ )
    395    {
    396      OTV_OPTIONAL_OFFSET( Offset );
    397      OTV_SIZE_CHECK( Offset );
    398      otv_MathGlyphConstruction_validate( table + Offset, otvalid );
    399    }
    400 
    401    OTV_EXIT;
    402  }
    403 
    404 
    405  /*************************************************************************/
    406  /*************************************************************************/
    407  /*****                                                               *****/
    408  /*****                          MATH TABLE                           *****/
    409  /*****                                                               *****/
    410  /*************************************************************************/
    411  /*************************************************************************/
    412 
    413  /* sets otvalid->glyph_count */
    414 
    415  FT_LOCAL_DEF( void )
    416  otv_MATH_validate( FT_Bytes      table,
    417                     FT_UInt       glyph_count,
    418                     FT_Validator  ftvalid )
    419  {
    420    OTV_ValidatorRec  otvalidrec;
    421    OTV_Validator     otvalid = &otvalidrec;
    422    FT_Bytes          p       = table;
    423    FT_UInt           MathConstants, MathGlyphInfo, MathVariants;
    424 
    425 
    426    otvalid->root = ftvalid;
    427 
    428    FT_TRACE3(( "validating MATH table\n" ));
    429    OTV_INIT;
    430 
    431    OTV_LIMIT_CHECK( 10 );
    432 
    433    if ( FT_NEXT_ULONG( p ) != 0x10000UL )      /* Version */
    434      FT_INVALID_FORMAT;
    435 
    436    MathConstants = FT_NEXT_USHORT( p );
    437    MathGlyphInfo = FT_NEXT_USHORT( p );
    438    MathVariants  = FT_NEXT_USHORT( p );
    439 
    440    otvalid->glyph_count = glyph_count;
    441 
    442    otv_MathConstants_validate( table + MathConstants,
    443                                otvalid );
    444    otv_MathGlyphInfo_validate( table + MathGlyphInfo,
    445                                otvalid );
    446    otv_MathVariants_validate ( table + MathVariants,
    447                                otvalid );
    448 
    449    FT_TRACE4(( "\n" ));
    450  }
    451 
    452 
    453 /* END */