Edit

kc3-lang/freetype/src/gxvalid/gxvtrak.c

Branch :

  • Show log

    Commit

  • Author : Werner Lemberg
    Date : 2020-01-19 17:05:19
    Hash : e5038be7
    Message : Update all copyright notices.

  • src/gxvalid/gxvtrak.c
  • /****************************************************************************
     *
     * gxvtrak.c
     *
     *   TrueTypeGX/AAT trak table validation (body).
     *
     * Copyright (C) 2004-2020 by
     * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
     * David Turner, Robert Wilhelm, and Werner Lemberg.
     *
     * This file is part of the FreeType project, and may only be used,
     * modified, and distributed under the terms of the FreeType project
     * license, LICENSE.TXT.  By continuing to use, modify, or distribute
     * this file you indicate that you have read the license and
     * understand and accept it fully.
     *
     */
    
    /****************************************************************************
     *
     * gxvalid is derived from both gxlayout module and otvalid module.
     * Development of gxlayout is supported by the Information-technology
     * Promotion Agency(IPA), Japan.
     *
     */
    
    
    #include "gxvalid.h"
    #include "gxvcommn.h"
    
    
      /**************************************************************************
       *
       * The macro FT_COMPONENT is used in trace mode.  It is an implicit
       * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
       * messages during execution.
       */
    #undef  FT_COMPONENT
    #define FT_COMPONENT  gxvtrak
    
    
      /*************************************************************************/
      /*************************************************************************/
      /*****                                                               *****/
      /*****                      Data and Types                           *****/
      /*****                                                               *****/
      /*************************************************************************/
      /*************************************************************************/
    
        /*
         * referred track table format specification:
         * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6trak.html
         * last update was 1996.
         * ----------------------------------------------
         * [MINIMUM HEADER]: GXV_TRAK_SIZE_MIN
         * version          (fixed:  32bit) = 0x00010000
         * format           (uint16: 16bit) = 0 is only defined (1996)
         * horizOffset      (uint16: 16bit)
         * vertOffset       (uint16: 16bit)
         * reserved         (uint16: 16bit) = 0
         * ----------------------------------------------
         * [VARIABLE BODY]:
         * horizData
         *   header         ( 2 + 2 + 4
         *   trackTable       + nTracks * ( 4 + 2 + 2 )
         *   sizeTable        + nSizes * 4 )
         * ----------------------------------------------
         * vertData
         *   header         ( 2 + 2 + 4
         *   trackTable       + nTracks * ( 4 + 2 + 2 )
         *   sizeTable        + nSizes * 4 )
         * ----------------------------------------------
         */
      typedef struct  GXV_trak_DataRec_
      {
        FT_UShort  trackValueOffset_min;
        FT_UShort  trackValueOffset_max;
    
      } GXV_trak_DataRec, *GXV_trak_Data;
    
    
    #define GXV_TRAK_DATA( FIELD )  GXV_TABLE_DATA( trak, FIELD )
    
    
      /*************************************************************************/
      /*************************************************************************/
      /*****                                                               *****/
      /*****                      UTILITY FUNCTIONS                        *****/
      /*****                                                               *****/
      /*************************************************************************/
      /*************************************************************************/
    
      static void
      gxv_trak_trackTable_validate( FT_Bytes       table,
                                    FT_Bytes       limit,
                                    FT_UShort      nTracks,
                                    GXV_Validator  gxvalid )
      {
        FT_Bytes  p = table;
    
        FT_Fixed   track, t;
        FT_UShort  nameIndex;
        FT_UShort  offset;
        FT_UShort  i, j;
    
    
        GXV_NAME_ENTER( "trackTable" );
    
        GXV_TRAK_DATA( trackValueOffset_min ) = 0xFFFFU;
        GXV_TRAK_DATA( trackValueOffset_max ) = 0x0000;
    
        GXV_LIMIT_CHECK( nTracks * ( 4 + 2 + 2 ) );
    
        for ( i = 0; i < nTracks; i++ )
        {
          p = table + i * ( 4 + 2 + 2 );
          track     = FT_NEXT_LONG( p );
          nameIndex = FT_NEXT_USHORT( p );
          offset    = FT_NEXT_USHORT( p );
    
          if ( offset < GXV_TRAK_DATA( trackValueOffset_min ) )
            GXV_TRAK_DATA( trackValueOffset_min ) = offset;
          if ( offset > GXV_TRAK_DATA( trackValueOffset_max ) )
            GXV_TRAK_DATA( trackValueOffset_max ) = offset;
    
          gxv_sfntName_validate( nameIndex, 256, 32767, gxvalid );
    
          for ( j = i; j < nTracks; j++ )
          {
             p = table + j * ( 4 + 2 + 2 );
             t = FT_NEXT_LONG( p );
             if ( t == track )
               GXV_TRACE(( "duplicated entries found for track value 0x%x\n",
                            track ));
          }
        }
    
        gxvalid->subtable_length = (FT_ULong)( p - table );
        GXV_EXIT;
      }
    
    
      static void
      gxv_trak_trackData_validate( FT_Bytes       table,
                                   FT_Bytes       limit,
                                   GXV_Validator  gxvalid )
      {
        FT_Bytes   p = table;
        FT_UShort  nTracks;
        FT_UShort  nSizes;
        FT_ULong   sizeTableOffset;
    
        GXV_ODTECT( 4, odtect );
    
    
        GXV_ODTECT_INIT( odtect );
        GXV_NAME_ENTER( "trackData" );
    
        /* read the header of trackData */
        GXV_LIMIT_CHECK( 2 + 2 + 4 );
        nTracks         = FT_NEXT_USHORT( p );
        nSizes          = FT_NEXT_USHORT( p );
        sizeTableOffset = FT_NEXT_ULONG( p );
    
        gxv_odtect_add_range( table, (FT_ULong)( p - table ),
                              "trackData header", odtect );
    
        /* validate trackTable */
        gxv_trak_trackTable_validate( p, limit, nTracks, gxvalid );
        gxv_odtect_add_range( p, gxvalid->subtable_length,
                              "trackTable", odtect );
    
        /* sizeTable is array of FT_Fixed, don't check contents */
        p = gxvalid->root->base + sizeTableOffset;
        GXV_LIMIT_CHECK( nSizes * 4 );
        gxv_odtect_add_range( p, nSizes * 4, "sizeTable", odtect );
    
        /* validate trackValueOffet */
        p = gxvalid->root->base + GXV_TRAK_DATA( trackValueOffset_min );
        if ( limit - p < nTracks * nSizes * 2 )
          GXV_TRACE(( "too short trackValue array\n" ));
    
        p = gxvalid->root->base + GXV_TRAK_DATA( trackValueOffset_max );
        GXV_LIMIT_CHECK( nSizes * 2 );
    
        gxv_odtect_add_range( gxvalid->root->base
                                + GXV_TRAK_DATA( trackValueOffset_min ),
                              GXV_TRAK_DATA( trackValueOffset_max )
                                - GXV_TRAK_DATA( trackValueOffset_min )
                                + nSizes * 2,
                              "trackValue array", odtect );
    
        gxv_odtect_validate( odtect, gxvalid );
    
        GXV_EXIT;
      }
    
    
      /*************************************************************************/
      /*************************************************************************/
      /*****                                                               *****/
      /*****                          trak TABLE                           *****/
      /*****                                                               *****/
      /*************************************************************************/
      /*************************************************************************/
    
      FT_LOCAL_DEF( void )
      gxv_trak_validate( FT_Bytes      table,
                         FT_Face       face,
                         FT_Validator  ftvalid )
      {
        FT_Bytes          p = table;
        FT_Bytes          limit = 0;
    
        GXV_ValidatorRec  gxvalidrec;
        GXV_Validator     gxvalid = &gxvalidrec;
        GXV_trak_DataRec  trakrec;
        GXV_trak_Data     trak = &trakrec;
    
        FT_ULong   version;
        FT_UShort  format;
        FT_UShort  horizOffset;
        FT_UShort  vertOffset;
        FT_UShort  reserved;
    
    
        GXV_ODTECT( 3, odtect );
    
        GXV_ODTECT_INIT( odtect );
        gxvalid->root       = ftvalid;
        gxvalid->table_data = trak;
        gxvalid->face       = face;
    
        limit      = gxvalid->root->limit;
    
        FT_TRACE3(( "validating `trak' table\n" ));
        GXV_INIT;
    
        GXV_LIMIT_CHECK( 4 + 2 + 2 + 2 + 2 );
        version     = FT_NEXT_ULONG( p );
        format      = FT_NEXT_USHORT( p );
        horizOffset = FT_NEXT_USHORT( p );
        vertOffset  = FT_NEXT_USHORT( p );
        reserved    = FT_NEXT_USHORT( p );
    
        GXV_TRACE(( " (version = 0x%08x)\n", version ));
        GXV_TRACE(( " (format = 0x%04x)\n", format ));
        GXV_TRACE(( " (horizOffset = 0x%04x)\n", horizOffset ));
        GXV_TRACE(( " (vertOffset = 0x%04x)\n", vertOffset ));
        GXV_TRACE(( " (reserved = 0x%04x)\n", reserved ));
    
        /* Version 1.0 (always:1996) */
        if ( version != 0x00010000UL )
          FT_INVALID_FORMAT;
    
        /* format 0 (always:1996) */
        if ( format != 0x0000 )
          FT_INVALID_FORMAT;
    
        GXV_32BIT_ALIGNMENT_VALIDATE( horizOffset );
        GXV_32BIT_ALIGNMENT_VALIDATE( vertOffset );
    
        /* Reserved Fixed Value (always) */
        if ( reserved != 0x0000 )
          FT_INVALID_DATA;
    
        /* validate trackData */
        if ( 0 < horizOffset )
        {
          gxv_trak_trackData_validate( table + horizOffset, limit, gxvalid );
          gxv_odtect_add_range( table + horizOffset, gxvalid->subtable_length,
                                "horizJustData", odtect );
        }
    
        if ( 0 < vertOffset )
        {
          gxv_trak_trackData_validate( table + vertOffset, limit, gxvalid );
          gxv_odtect_add_range( table + vertOffset, gxvalid->subtable_length,
                                "vertJustData", odtect );
        }
    
        gxv_odtect_validate( odtect, gxvalid );
    
        FT_TRACE4(( "\n" ));
      }
    
    
    /* END */