tor-browser

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

gxvmod.c (8348B)


      1 /****************************************************************************
      2 *
      3 * gxvmod.c
      4 *
      5 *   FreeType's TrueTypeGX/AAT validation module implementation (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 <freetype/tttables.h>
     29 #include <freetype/tttags.h>
     30 #include <freetype/ftgxval.h>
     31 #include <freetype/internal/ftobjs.h>
     32 #include <freetype/internal/services/svgxval.h>
     33 
     34 #include "gxvmod.h"
     35 #include "gxvalid.h"
     36 #include "gxvcommn.h"
     37 
     38 
     39  /**************************************************************************
     40   *
     41   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
     42   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
     43   * messages during execution.
     44   */
     45 #undef  FT_COMPONENT
     46 #define FT_COMPONENT  gxvmodule
     47 
     48 
     49  static FT_Error
     50  gxv_load_table( FT_Face             face,
     51                  FT_Tag              tag,
     52                  FT_Byte* volatile*  table,
     53                  FT_ULong*           table_len )
     54  {
     55    FT_Error   error;
     56    FT_Memory  memory = FT_FACE_MEMORY( face );
     57 
     58 
     59    error = FT_Load_Sfnt_Table( face, tag, 0, NULL, table_len );
     60    if ( FT_ERR_EQ( error, Table_Missing ) )
     61      return FT_Err_Ok;
     62    if ( error )
     63      goto Exit;
     64 
     65    if ( FT_QALLOC( *table, *table_len ) )
     66      goto Exit;
     67 
     68    error = FT_Load_Sfnt_Table( face, tag, 0, *table, table_len );
     69 
     70  Exit:
     71    return error;
     72  }
     73 
     74 
     75 #define GXV_TABLE_DECL( _sfnt )                     \
     76          FT_Byte* volatile  _sfnt          = NULL; \
     77          FT_ULong            len_ ## _sfnt = 0
     78 
     79 #define GXV_TABLE_LOAD( _sfnt )                                       \
     80          FT_BEGIN_STMNT                                              \
     81            if ( ( FT_VALIDATE_ ## _sfnt ## _INDEX < table_count ) && \
     82                 ( gx_flags & FT_VALIDATE_ ## _sfnt )            )    \
     83            {                                                         \
     84              error = gxv_load_table( face, TTAG_ ## _sfnt,           \
     85                                      &_sfnt, &len_ ## _sfnt );       \
     86              if ( error )                                            \
     87                goto Exit;                                            \
     88            }                                                         \
     89          FT_END_STMNT
     90 
     91 #define GXV_TABLE_VALIDATE( _sfnt )                                    \
     92          FT_BEGIN_STMNT                                               \
     93            if ( _sfnt )                                               \
     94            {                                                          \
     95              ft_validator_init( &valid, _sfnt, _sfnt + len_ ## _sfnt, \
     96                                 FT_VALIDATE_DEFAULT );                \
     97              if ( ft_setjmp( valid.jump_buffer ) == 0 )               \
     98                gxv_ ## _sfnt ## _validate( _sfnt, face, &valid );     \
     99              error = valid.error;                                     \
    100              if ( error )                                             \
    101                goto Exit;                                             \
    102            }                                                          \
    103          FT_END_STMNT
    104 
    105 #define GXV_TABLE_SET( _sfnt )                                        \
    106          if ( FT_VALIDATE_ ## _sfnt ## _INDEX < table_count )        \
    107            tables[FT_VALIDATE_ ## _sfnt ## _INDEX] = (FT_Bytes)_sfnt
    108 
    109 
    110  static FT_Error
    111  gxv_validate( FT_Face   face,
    112                FT_UInt   gx_flags,
    113                FT_Bytes  tables[FT_VALIDATE_GX_LENGTH],
    114                FT_UInt   table_count )
    115  {
    116    FT_Memory volatile        memory = FT_FACE_MEMORY( face );
    117 
    118    FT_Error                  error = FT_Err_Ok;
    119    FT_ValidatorRec volatile  valid;
    120 
    121    FT_UInt  i;
    122 
    123 
    124    GXV_TABLE_DECL( feat );
    125    GXV_TABLE_DECL( bsln );
    126    GXV_TABLE_DECL( trak );
    127    GXV_TABLE_DECL( just );
    128    GXV_TABLE_DECL( mort );
    129    GXV_TABLE_DECL( morx );
    130    GXV_TABLE_DECL( kern );
    131    GXV_TABLE_DECL( opbd );
    132    GXV_TABLE_DECL( prop );
    133    GXV_TABLE_DECL( lcar );
    134 
    135    for ( i = 0; i < table_count; i++ )
    136      tables[i] = 0;
    137 
    138    /* load tables */
    139    GXV_TABLE_LOAD( feat );
    140    GXV_TABLE_LOAD( bsln );
    141    GXV_TABLE_LOAD( trak );
    142    GXV_TABLE_LOAD( just );
    143    GXV_TABLE_LOAD( mort );
    144    GXV_TABLE_LOAD( morx );
    145    GXV_TABLE_LOAD( kern );
    146    GXV_TABLE_LOAD( opbd );
    147    GXV_TABLE_LOAD( prop );
    148    GXV_TABLE_LOAD( lcar );
    149 
    150    /* validate tables */
    151    GXV_TABLE_VALIDATE( feat );
    152    GXV_TABLE_VALIDATE( bsln );
    153    GXV_TABLE_VALIDATE( trak );
    154    GXV_TABLE_VALIDATE( just );
    155    GXV_TABLE_VALIDATE( mort );
    156    GXV_TABLE_VALIDATE( morx );
    157    GXV_TABLE_VALIDATE( kern );
    158    GXV_TABLE_VALIDATE( opbd );
    159    GXV_TABLE_VALIDATE( prop );
    160    GXV_TABLE_VALIDATE( lcar );
    161 
    162    /* Set results */
    163    GXV_TABLE_SET( feat );
    164    GXV_TABLE_SET( mort );
    165    GXV_TABLE_SET( morx );
    166    GXV_TABLE_SET( bsln );
    167    GXV_TABLE_SET( just );
    168    GXV_TABLE_SET( kern );
    169    GXV_TABLE_SET( opbd );
    170    GXV_TABLE_SET( trak );
    171    GXV_TABLE_SET( prop );
    172    GXV_TABLE_SET( lcar );
    173 
    174  Exit:
    175    if ( error )
    176    {
    177      FT_FREE( feat );
    178      FT_FREE( bsln );
    179      FT_FREE( trak );
    180      FT_FREE( just );
    181      FT_FREE( mort );
    182      FT_FREE( morx );
    183      FT_FREE( kern );
    184      FT_FREE( opbd );
    185      FT_FREE( prop );
    186      FT_FREE( lcar );
    187    }
    188 
    189    return error;
    190  }
    191 
    192 
    193  static FT_Error
    194  classic_kern_validate( FT_Face    face,
    195                         FT_UInt    ckern_flags,
    196                         FT_Bytes*  ckern_table )
    197  {
    198    FT_Memory volatile        memory = FT_FACE_MEMORY( face );
    199 
    200    FT_Byte* volatile         ckern     = NULL;
    201    FT_ULong                  len_ckern = 0;
    202 
    203    /* without volatile on `error' GCC 4.1.1. emits:                         */
    204    /*  warning: variable 'error' might be clobbered by 'longjmp' or 'vfork' */
    205    /* this warning seems spurious but ---                                   */
    206    FT_Error volatile         error;
    207    FT_ValidatorRec volatile  valid;
    208 
    209 
    210    *ckern_table = NULL;
    211 
    212    error = gxv_load_table( face, TTAG_kern, &ckern, &len_ckern );
    213    if ( error )
    214      goto Exit;
    215 
    216    if ( ckern )
    217    {
    218      ft_validator_init( &valid, ckern, ckern + len_ckern,
    219                         FT_VALIDATE_DEFAULT );
    220      if ( ft_setjmp( valid.jump_buffer ) == 0 )
    221        gxv_kern_validate_classic( ckern, face,
    222                                   ckern_flags & FT_VALIDATE_CKERN, &valid );
    223      error = valid.error;
    224      if ( error )
    225        goto Exit;
    226    }
    227 
    228    *ckern_table = ckern;
    229 
    230  Exit:
    231    if ( error )
    232      FT_FREE( ckern );
    233 
    234    return error;
    235  }
    236 
    237 
    238  static
    239  const FT_Service_GXvalidateRec  gxvalid_interface =
    240  {
    241    gxv_validate              /* validate */
    242  };
    243 
    244 
    245  static
    246  const FT_Service_CKERNvalidateRec  ckernvalid_interface =
    247  {
    248    classic_kern_validate     /* validate */
    249  };
    250 
    251 
    252  static
    253  const FT_ServiceDescRec  gxvalid_services[] =
    254  {
    255    { FT_SERVICE_ID_GX_VALIDATE,          &gxvalid_interface },
    256    { FT_SERVICE_ID_CLASSICKERN_VALIDATE, &ckernvalid_interface },
    257    { NULL, NULL }
    258  };
    259 
    260 
    261  static FT_Pointer
    262  gxvalid_get_service( FT_Module    module,
    263                       const char*  service_id )
    264  {
    265    FT_UNUSED( module );
    266 
    267    return ft_service_list_lookup( gxvalid_services, service_id );
    268  }
    269 
    270 
    271  FT_CALLBACK_TABLE_DEF
    272  const FT_Module_Class  gxv_module_class =
    273  {
    274    0,
    275    sizeof ( FT_ModuleRec ),
    276    "gxvalid",
    277    0x10000L,
    278    0x20000L,
    279 
    280    NULL,              /* module-specific interface */
    281 
    282    (FT_Module_Constructor)NULL,                /* module_init   */
    283    (FT_Module_Destructor) NULL,                /* module_done   */
    284    (FT_Module_Requester)  gxvalid_get_service  /* get_interface */
    285  };
    286 
    287 
    288 /* END */