(root)/
freetype-2.13.2/
src/
otvalid/
otvgdef.c
       1  /****************************************************************************
       2   *
       3   * otvgdef.c
       4   *
       5   *   OpenType GDEF table validation (body).
       6   *
       7   * Copyright (C) 2004-2023 by
       8   * David Turner, Robert Wilhelm, and Werner Lemberg.
       9   *
      10   * This file is part of the FreeType project, and may only be used,
      11   * modified, and distributed under the terms of the FreeType project
      12   * license, LICENSE.TXT.  By continuing to use, modify, or distribute
      13   * this file you indicate that you have read the license and
      14   * understand and accept it fully.
      15   *
      16   */
      17  
      18  
      19  #include "otvalid.h"
      20  #include "otvcommn.h"
      21  
      22  
      23    /**************************************************************************
      24     *
      25     * The macro FT_COMPONENT is used in trace mode.  It is an implicit
      26     * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
      27     * messages during execution.
      28     */
      29  #undef  FT_COMPONENT
      30  #define FT_COMPONENT  otvgdef
      31  
      32  
      33    /*************************************************************************/
      34    /*************************************************************************/
      35    /*****                                                               *****/
      36    /*****                      UTILITY FUNCTIONS                        *****/
      37    /*****                                                               *****/
      38    /*************************************************************************/
      39    /*************************************************************************/
      40  
      41  #define AttachListFunc    otv_O_x_Ox
      42  #define LigCaretListFunc  otv_O_x_Ox
      43  
      44    /* sets valid->extra1 (0)           */
      45  
      46    static void
      47    otv_O_x_Ox( FT_Bytes       table,
      48                OTV_Validator  otvalid )
      49    {
      50      FT_Bytes           p = table;
      51      FT_Bytes           Coverage;
      52      FT_UInt            GlyphCount;
      53      OTV_Validate_Func  func;
      54  
      55  
      56      OTV_ENTER;
      57  
      58      OTV_LIMIT_CHECK( 4 );
      59      Coverage   = table + FT_NEXT_USHORT( p );
      60      GlyphCount = FT_NEXT_USHORT( p );
      61  
      62      OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
      63  
      64      otv_Coverage_validate( Coverage, otvalid, (FT_Int)GlyphCount );
      65      if ( GlyphCount != otv_Coverage_get_count( Coverage ) )
      66        FT_INVALID_DATA;
      67  
      68      OTV_LIMIT_CHECK( GlyphCount * 2 );
      69  
      70      otvalid->nesting_level++;
      71      func            = otvalid->func[otvalid->nesting_level];
      72      otvalid->extra1 = 0;
      73  
      74      for ( ; GlyphCount > 0; GlyphCount-- )
      75        func( table + FT_NEXT_USHORT( p ), otvalid );
      76  
      77      otvalid->nesting_level--;
      78  
      79      OTV_EXIT;
      80    }
      81  
      82  
      83    /*************************************************************************/
      84    /*************************************************************************/
      85    /*****                                                               *****/
      86    /*****                       LIGATURE CARETS                         *****/
      87    /*****                                                               *****/
      88    /*************************************************************************/
      89    /*************************************************************************/
      90  
      91  #define CaretValueFunc  otv_CaretValue_validate
      92  
      93    static void
      94    otv_CaretValue_validate( FT_Bytes       table,
      95                             OTV_Validator  otvalid )
      96    {
      97      FT_Bytes  p = table;
      98      FT_UInt   CaretValueFormat;
      99  
     100  
     101      OTV_ENTER;
     102  
     103      OTV_LIMIT_CHECK( 4 );
     104  
     105      CaretValueFormat = FT_NEXT_USHORT( p );
     106  
     107      OTV_TRACE(( " (format = %d)\n", CaretValueFormat ));
     108  
     109      switch ( CaretValueFormat )
     110      {
     111      case 1:     /* CaretValueFormat1 */
     112        /* skip Coordinate, no test */
     113        break;
     114  
     115      case 2:     /* CaretValueFormat2 */
     116        /* skip CaretValuePoint, no test */
     117        break;
     118  
     119      case 3:     /* CaretValueFormat3 */
     120        p += 2;   /* skip Coordinate */
     121  
     122        OTV_LIMIT_CHECK( 2 );
     123  
     124        /* DeviceTable */
     125        otv_Device_validate( table + FT_NEXT_USHORT( p ), otvalid );
     126        break;
     127  
     128      default:
     129        FT_INVALID_FORMAT;
     130      }
     131  
     132      OTV_EXIT;
     133    }
     134  
     135  
     136    /*************************************************************************/
     137    /*************************************************************************/
     138    /*****                                                               *****/
     139    /*****                       MARK GLYPH SETS                         *****/
     140    /*****                                                               *****/
     141    /*************************************************************************/
     142    /*************************************************************************/
     143  
     144    static void
     145    otv_MarkGlyphSets_validate( FT_Bytes       table,
     146                                OTV_Validator  otvalid )
     147    {
     148      FT_Bytes  p = table;
     149      FT_UInt   MarkGlyphSetCount;
     150  
     151  
     152      OTV_NAME_ENTER( "MarkGlyphSets" );
     153  
     154      p += 2;     /* skip Format */
     155  
     156      OTV_LIMIT_CHECK( 2 );
     157      MarkGlyphSetCount = FT_NEXT_USHORT( p );
     158  
     159      OTV_TRACE(( " (MarkGlyphSetCount = %d)\n", MarkGlyphSetCount ));
     160  
     161      OTV_LIMIT_CHECK( MarkGlyphSetCount * 4 );      /* CoverageOffsets */
     162  
     163      for ( ; MarkGlyphSetCount > 0; MarkGlyphSetCount-- )
     164        otv_Coverage_validate( table + FT_NEXT_ULONG( p ), otvalid, -1 );
     165  
     166      OTV_EXIT;
     167    }
     168  
     169  
     170    /*************************************************************************/
     171    /*************************************************************************/
     172    /*****                                                               *****/
     173    /*****                         GDEF TABLE                            *****/
     174    /*****                                                               *****/
     175    /*************************************************************************/
     176    /*************************************************************************/
     177  
     178    /* sets otvalid->glyph_count */
     179  
     180    FT_LOCAL_DEF( void )
     181    otv_GDEF_validate( FT_Bytes      table,
     182                       FT_Bytes      gsub,
     183                       FT_Bytes      gpos,
     184                       FT_UInt       glyph_count,
     185                       FT_Validator  ftvalid )
     186    {
     187      OTV_ValidatorRec  otvalidrec;
     188      OTV_Validator     otvalid = &otvalidrec;
     189      FT_Bytes          p       = table;
     190      FT_UInt           table_size;
     191      FT_UShort         version;
     192      FT_Bool           need_MarkAttachClassDef = 1;
     193  
     194      OTV_OPTIONAL_TABLE( GlyphClassDef );
     195      OTV_OPTIONAL_TABLE( AttachListOffset );
     196      OTV_OPTIONAL_TABLE( LigCaretListOffset );
     197      OTV_OPTIONAL_TABLE( MarkAttachClassDef );
     198      OTV_OPTIONAL_TABLE( MarkGlyphSetsDef );
     199  
     200      OTV_OPTIONAL_TABLE32( itemVarStore );
     201  
     202  
     203      otvalid->root = ftvalid;
     204  
     205      FT_TRACE3(( "validating GDEF table\n" ));
     206      OTV_INIT;
     207  
     208      OTV_LIMIT_CHECK( 4 );
     209  
     210      if ( FT_NEXT_USHORT( p ) != 1 )  /* majorVersion */
     211        FT_INVALID_FORMAT;
     212  
     213      version = FT_NEXT_USHORT( p );   /* minorVersion */
     214  
     215      table_size = 10;
     216      switch ( version )
     217      {
     218      case 0:
     219        /* MarkAttachClassDef has been added to the OpenType */
     220        /* specification without increasing GDEF's version,  */
     221        /* so we use this ugly hack to find out whether the  */
     222        /* table is needed actually.                         */
     223  
     224        need_MarkAttachClassDef = FT_BOOL(
     225          otv_GSUBGPOS_have_MarkAttachmentType_flag( gsub ) ||
     226          otv_GSUBGPOS_have_MarkAttachmentType_flag( gpos ) );
     227  
     228        if ( need_MarkAttachClassDef )
     229        {
     230          OTV_LIMIT_CHECK( 8 );
     231          table_size += 2;
     232        }
     233        else
     234          OTV_LIMIT_CHECK( 6 );  /* OpenType < 1.2 */
     235  
     236        break;
     237  
     238      case 2:
     239        OTV_LIMIT_CHECK( 10 );
     240        table_size += 4;
     241        break;
     242  
     243      case 3:
     244        OTV_LIMIT_CHECK( 14 );
     245        table_size += 8;
     246        break;
     247  
     248      default:
     249        FT_INVALID_FORMAT;
     250      }
     251  
     252      otvalid->glyph_count = glyph_count;
     253  
     254      OTV_OPTIONAL_OFFSET( GlyphClassDef );
     255      OTV_SIZE_CHECK( GlyphClassDef );
     256      if ( GlyphClassDef )
     257        otv_ClassDef_validate( table + GlyphClassDef, otvalid );
     258  
     259      OTV_OPTIONAL_OFFSET( AttachListOffset );
     260      OTV_SIZE_CHECK( AttachListOffset );
     261      if ( AttachListOffset )
     262      {
     263        OTV_NEST2( AttachList, AttachPoint );
     264        OTV_RUN( table + AttachListOffset, otvalid );
     265      }
     266  
     267      OTV_OPTIONAL_OFFSET( LigCaretListOffset );
     268      OTV_SIZE_CHECK( LigCaretListOffset );
     269      if ( LigCaretListOffset )
     270      {
     271        OTV_NEST3( LigCaretList, LigGlyph, CaretValue );
     272        OTV_RUN( table + LigCaretListOffset, otvalid );
     273      }
     274  
     275      if ( need_MarkAttachClassDef )
     276      {
     277        OTV_OPTIONAL_OFFSET( MarkAttachClassDef );
     278        OTV_SIZE_CHECK( MarkAttachClassDef );
     279        if ( MarkAttachClassDef )
     280          otv_ClassDef_validate( table + MarkAttachClassDef, otvalid );
     281      }
     282  
     283      if ( version > 0 )
     284      {
     285        OTV_OPTIONAL_OFFSET( MarkGlyphSetsDef );
     286        OTV_SIZE_CHECK( MarkGlyphSetsDef );
     287        if ( MarkGlyphSetsDef )
     288          otv_MarkGlyphSets_validate( table + MarkGlyphSetsDef, otvalid );
     289      }
     290  
     291      if ( version > 2 )
     292      {
     293        OTV_OPTIONAL_OFFSET32( itemVarStore );
     294        OTV_SIZE_CHECK32( itemVarStore );
     295        if ( itemVarStore )
     296          OTV_TRACE(( "  [omitting itemVarStore validation]\n" )); /* XXX */
     297      }
     298  
     299      FT_TRACE4(( "\n" ));
     300    }
     301  
     302  
     303  /* END */