Edit

kc3-lang/freetype/src/otvalid/otvbase.c

Branch :

  • Show log

    Commit

  • Author : Werner Lemberg
    Date : 2025-09-06 06:14:03
    Hash : 32cb5390
    Message : Update all copyright notices.

  • src/otvalid/otvbase.c
  • /****************************************************************************
     *
     * otvbase.c
     *
     *   OpenType BASE table validation (body).
     *
     * Copyright (C) 2004-2025 by
     * 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.
     *
     */
    
    
    #include "otvalid.h"
    #include "otvcommn.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  otvbase
    
    
      static void
      otv_BaseCoord_validate( FT_Bytes       table,
                              OTV_Validator  otvalid )
      {
        FT_Bytes  p = table;
        FT_UInt   BaseCoordFormat;
    
    
        OTV_NAME_ENTER( "BaseCoord" );
    
        OTV_LIMIT_CHECK( 4 );
        BaseCoordFormat = FT_NEXT_USHORT( p );
        p += 2;     /* skip Coordinate */
    
        OTV_TRACE(( " (format %u)\n", BaseCoordFormat ));
    
        switch ( BaseCoordFormat )
        {
        case 1:     /* BaseCoordFormat1 */
          break;
    
        case 2:     /* BaseCoordFormat2 */
          OTV_LIMIT_CHECK( 4 );   /* ReferenceGlyph, BaseCoordPoint */
          break;
    
        case 3:     /* BaseCoordFormat3 */
          OTV_LIMIT_CHECK( 2 );
          /* DeviceTable */
          otv_Device_validate( table + FT_NEXT_USHORT( p ), otvalid );
          break;
    
        default:
          FT_INVALID_FORMAT;
        }
    
        OTV_EXIT;
      }
    
    
      static void
      otv_BaseTagList_validate( FT_Bytes       table,
                                OTV_Validator  otvalid )
      {
        FT_Bytes  p = table;
        FT_UInt   BaseTagCount;
    
    
        OTV_NAME_ENTER( "BaseTagList" );
    
        OTV_LIMIT_CHECK( 2 );
    
        BaseTagCount = FT_NEXT_USHORT( p );
    
        OTV_TRACE(( " (BaseTagCount = %u)\n", BaseTagCount ));
    
        OTV_LIMIT_CHECK( BaseTagCount * 4 );          /* BaselineTag */
    
        OTV_EXIT;
      }
    
    
      static void
      otv_BaseValues_validate( FT_Bytes       table,
                               OTV_Validator  otvalid )
      {
        FT_Bytes  p = table;
        FT_UInt   BaseCoordCount;
    
    
        OTV_NAME_ENTER( "BaseValues" );
    
        OTV_LIMIT_CHECK( 4 );
    
        p             += 2;                     /* skip DefaultIndex */
        BaseCoordCount = FT_NEXT_USHORT( p );
    
        OTV_TRACE(( " (BaseCoordCount = %u)\n", BaseCoordCount ));
    
        OTV_LIMIT_CHECK( BaseCoordCount * 2 );
    
        /* BaseCoord */
        for ( ; BaseCoordCount > 0; BaseCoordCount-- )
          otv_BaseCoord_validate( table + FT_NEXT_USHORT( p ), otvalid );
    
        OTV_EXIT;
      }
    
    
      static void
      otv_MinMax_validate( FT_Bytes       table,
                           OTV_Validator  otvalid )
      {
        FT_Bytes  p = table;
        FT_UInt   table_size;
        FT_UInt   FeatMinMaxCount;
    
        OTV_OPTIONAL_TABLE( MinCoord );
        OTV_OPTIONAL_TABLE( MaxCoord );
    
    
        OTV_NAME_ENTER( "MinMax" );
    
        OTV_LIMIT_CHECK( 6 );
    
        OTV_OPTIONAL_OFFSET( MinCoord );
        OTV_OPTIONAL_OFFSET( MaxCoord );
        FeatMinMaxCount = FT_NEXT_USHORT( p );
    
        OTV_TRACE(( " (FeatMinMaxCount = %u)\n", FeatMinMaxCount ));
    
        table_size = FeatMinMaxCount * 8 + 6;
    
        OTV_SIZE_CHECK( MinCoord );
        if ( MinCoord )
          otv_BaseCoord_validate( table + MinCoord, otvalid );
    
        OTV_SIZE_CHECK( MaxCoord );
        if ( MaxCoord )
          otv_BaseCoord_validate( table + MaxCoord, otvalid );
    
        OTV_LIMIT_CHECK( FeatMinMaxCount * 8 );
    
        /* FeatMinMaxRecord */
        for ( ; FeatMinMaxCount > 0; FeatMinMaxCount-- )
        {
          p += 4;                           /* skip FeatureTableTag */
    
          OTV_OPTIONAL_OFFSET( MinCoord );
          OTV_OPTIONAL_OFFSET( MaxCoord );
    
          OTV_SIZE_CHECK( MinCoord );
          if ( MinCoord )
            otv_BaseCoord_validate( table + MinCoord, otvalid );
    
          OTV_SIZE_CHECK( MaxCoord );
          if ( MaxCoord )
            otv_BaseCoord_validate( table + MaxCoord, otvalid );
        }
    
        OTV_EXIT;
      }
    
    
      static void
      otv_BaseScript_validate( FT_Bytes       table,
                               OTV_Validator  otvalid )
      {
        FT_Bytes  p = table;
        FT_UInt   table_size;
        FT_UInt   BaseLangSysCount;
    
        OTV_OPTIONAL_TABLE( BaseValues    );
        OTV_OPTIONAL_TABLE( DefaultMinMax );
    
    
        OTV_NAME_ENTER( "BaseScript" );
    
        OTV_LIMIT_CHECK( 6 );
        OTV_OPTIONAL_OFFSET( BaseValues    );
        OTV_OPTIONAL_OFFSET( DefaultMinMax );
        BaseLangSysCount = FT_NEXT_USHORT( p );
    
        OTV_TRACE(( " (BaseLangSysCount = %u)\n", BaseLangSysCount ));
    
        table_size = BaseLangSysCount * 6 + 6;
    
        OTV_SIZE_CHECK( BaseValues );
        if ( BaseValues )
          otv_BaseValues_validate( table + BaseValues, otvalid );
    
        OTV_SIZE_CHECK( DefaultMinMax );
        if ( DefaultMinMax )
          otv_MinMax_validate( table + DefaultMinMax, otvalid );
    
        OTV_LIMIT_CHECK( BaseLangSysCount * 6 );
    
        /* BaseLangSysRecord */
        for ( ; BaseLangSysCount > 0; BaseLangSysCount-- )
        {
          p += 4;       /* skip BaseLangSysTag */
    
          otv_MinMax_validate( table + FT_NEXT_USHORT( p ), otvalid );
        }
    
        OTV_EXIT;
      }
    
    
      static void
      otv_BaseScriptList_validate( FT_Bytes       table,
                                   OTV_Validator  otvalid )
      {
        FT_Bytes  p = table;
        FT_UInt   BaseScriptCount;
    
    
        OTV_NAME_ENTER( "BaseScriptList" );
    
        OTV_LIMIT_CHECK( 2 );
        BaseScriptCount = FT_NEXT_USHORT( p );
    
        OTV_TRACE(( " (BaseScriptCount = %u)\n", BaseScriptCount ));
    
        OTV_LIMIT_CHECK( BaseScriptCount * 6 );
    
        /* BaseScriptRecord */
        for ( ; BaseScriptCount > 0; BaseScriptCount-- )
        {
          p += 4;       /* skip BaseScriptTag */
    
          /* BaseScript */
          otv_BaseScript_validate( table + FT_NEXT_USHORT( p ), otvalid );
        }
    
        OTV_EXIT;
      }
    
    
      static void
      otv_Axis_validate( FT_Bytes       table,
                         OTV_Validator  otvalid )
      {
        FT_Bytes  p = table;
        FT_UInt   table_size;
    
        OTV_OPTIONAL_TABLE( BaseTagList );
    
    
        OTV_NAME_ENTER( "Axis" );
    
        OTV_LIMIT_CHECK( 4 );
        OTV_OPTIONAL_OFFSET( BaseTagList );
    
        table_size = 4;
    
        OTV_SIZE_CHECK( BaseTagList );
        if ( BaseTagList )
          otv_BaseTagList_validate( table + BaseTagList, otvalid );
    
        /* BaseScriptList */
        otv_BaseScriptList_validate( table + FT_NEXT_USHORT( p ), otvalid );
    
        OTV_EXIT;
      }
    
    
      FT_LOCAL_DEF( void )
      otv_BASE_validate( FT_Bytes      table,
                         FT_Validator  ftvalid )
      {
        OTV_ValidatorRec  otvalidrec;
        OTV_Validator     otvalid = &otvalidrec;
        FT_Bytes          p       = table;
        FT_UInt           table_size;
        FT_UShort         version;
    
        OTV_OPTIONAL_TABLE( HorizAxis );
        OTV_OPTIONAL_TABLE( VertAxis  );
    
        OTV_OPTIONAL_TABLE32( itemVarStore );
    
    
        otvalid->root = ftvalid;
    
        FT_TRACE3(( "validating BASE table\n" ));
        OTV_INIT;
    
        OTV_LIMIT_CHECK( 4 );
    
        if ( FT_NEXT_USHORT( p ) != 1 )  /* majorVersion */
          FT_INVALID_FORMAT;
    
        version = FT_NEXT_USHORT( p );   /* minorVersion */
    
        table_size = 8;
        switch ( version )
        {
        case 0:
          OTV_LIMIT_CHECK( 4 );
          break;
    
        case 1:
          OTV_LIMIT_CHECK( 8 );
          table_size += 4;
          break;
    
        default:
          FT_INVALID_FORMAT;
        }
    
        OTV_OPTIONAL_OFFSET( HorizAxis );
        OTV_SIZE_CHECK( HorizAxis );
        if ( HorizAxis )
          otv_Axis_validate( table + HorizAxis, otvalid );
    
        OTV_OPTIONAL_OFFSET( VertAxis );
        OTV_SIZE_CHECK( VertAxis );
        if ( VertAxis )
          otv_Axis_validate( table + VertAxis, otvalid );
    
        if ( version > 0 )
        {
          OTV_OPTIONAL_OFFSET32( itemVarStore );
          OTV_SIZE_CHECK32( itemVarStore );
          if ( itemVarStore )
            OTV_TRACE(( "  [omitting itemVarStore validation]\n" )); /* XXX */
        }
    
        FT_TRACE4(( "\n" ));
      }
    
    
    /* END */