tor-browser

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

otvmod.c (7207B)


      1 /****************************************************************************
      2 *
      3 * otvmod.c
      4 *
      5 *   FreeType's OpenType validation module implementation (body).
      6 *
      7 * Copyright (C) 2004-2025 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 <freetype/tttables.h>
     20 #include <freetype/tttags.h>
     21 #include <freetype/ftotval.h>
     22 #include <freetype/internal/ftobjs.h>
     23 #include <freetype/internal/services/svotval.h>
     24 
     25 #include "otvmod.h"
     26 #include "otvalid.h"
     27 #include "otvcommn.h"
     28 
     29 
     30  /**************************************************************************
     31   *
     32   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
     33   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
     34   * messages during execution.
     35   */
     36 #undef  FT_COMPONENT
     37 #define FT_COMPONENT  otvmodule
     38 
     39 
     40  static FT_Error
     41  otv_load_table( FT_Face             face,
     42                  FT_Tag              tag,
     43                  FT_Byte* volatile*  table,
     44                  FT_ULong*           table_len )
     45  {
     46    FT_Error   error;
     47    FT_Memory  memory = FT_FACE_MEMORY( face );
     48 
     49 
     50    error = FT_Load_Sfnt_Table( face, tag, 0, NULL, table_len );
     51    if ( FT_ERR_EQ( error, Table_Missing ) )
     52      return FT_Err_Ok;
     53    if ( error )
     54      goto Exit;
     55 
     56    if ( FT_QALLOC( *table, *table_len ) )
     57      goto Exit;
     58 
     59    error = FT_Load_Sfnt_Table( face, tag, 0, *table, table_len );
     60 
     61  Exit:
     62    return error;
     63  }
     64 
     65 
     66  static FT_Error
     67  otv_validate( FT_Face volatile   face,
     68                FT_UInt            ot_flags,
     69                FT_Bytes          *ot_base,
     70                FT_Bytes          *ot_gdef,
     71                FT_Bytes          *ot_gpos,
     72                FT_Bytes          *ot_gsub,
     73                FT_Bytes          *ot_jstf )
     74  {
     75    FT_Error                  error = FT_Err_Ok;
     76    FT_Byte* volatile         base;
     77    FT_Byte* volatile         gdef;
     78    FT_Byte* volatile         gpos;
     79    FT_Byte* volatile         gsub;
     80    FT_Byte* volatile         jstf;
     81    FT_Byte* volatile         math;
     82    FT_ULong                  len_base, len_gdef, len_gpos, len_gsub, len_jstf;
     83    FT_ULong                  len_math;
     84    FT_UInt                   num_glyphs = (FT_UInt)face->num_glyphs;
     85    FT_ValidatorRec volatile  valid;
     86 
     87 
     88    base     = gdef     = gpos     = gsub     = jstf     = math     = NULL;
     89    len_base = len_gdef = len_gpos = len_gsub = len_jstf = len_math = 0;
     90 
     91    /*
     92     * XXX: OpenType tables cannot handle 32-bit glyph index,
     93     *      although broken TrueType can have 32-bit glyph index.
     94     */
     95    if ( face->num_glyphs > 0xFFFFL )
     96    {
     97      FT_TRACE1(( "otv_validate: Invalid glyphs index (0x0000FFFF - 0x%08lx) ",
     98                  face->num_glyphs ));
     99      FT_TRACE1(( "are not handled by OpenType tables\n" ));
    100      num_glyphs = 0xFFFF;
    101    }
    102 
    103    /* load tables */
    104 
    105    if ( ot_flags & FT_VALIDATE_BASE )
    106    {
    107      error = otv_load_table( face, TTAG_BASE, &base, &len_base );
    108      if ( error )
    109        goto Exit;
    110    }
    111 
    112    if ( ot_flags & FT_VALIDATE_GDEF )
    113    {
    114      error = otv_load_table( face, TTAG_GDEF, &gdef, &len_gdef );
    115      if ( error )
    116        goto Exit;
    117    }
    118 
    119    if ( ot_flags & FT_VALIDATE_GPOS )
    120    {
    121      error = otv_load_table( face, TTAG_GPOS, &gpos, &len_gpos );
    122      if ( error )
    123        goto Exit;
    124    }
    125 
    126    if ( ot_flags & FT_VALIDATE_GSUB )
    127    {
    128      error = otv_load_table( face, TTAG_GSUB, &gsub, &len_gsub );
    129      if ( error )
    130        goto Exit;
    131    }
    132 
    133    if ( ot_flags & FT_VALIDATE_JSTF )
    134    {
    135      error = otv_load_table( face, TTAG_JSTF, &jstf, &len_jstf );
    136      if ( error )
    137        goto Exit;
    138    }
    139 
    140    if ( ot_flags & FT_VALIDATE_MATH )
    141    {
    142      error = otv_load_table( face, TTAG_MATH, &math, &len_math );
    143      if ( error )
    144        goto Exit;
    145    }
    146 
    147    /* validate tables */
    148 
    149    if ( base )
    150    {
    151      ft_validator_init( &valid, base, base + len_base, FT_VALIDATE_DEFAULT );
    152      if ( ft_setjmp( valid.jump_buffer ) == 0 )
    153        otv_BASE_validate( base, &valid );
    154      error = valid.error;
    155      if ( error )
    156        goto Exit;
    157    }
    158 
    159    if ( gpos )
    160    {
    161      ft_validator_init( &valid, gpos, gpos + len_gpos, FT_VALIDATE_DEFAULT );
    162      if ( ft_setjmp( valid.jump_buffer ) == 0 )
    163        otv_GPOS_validate( gpos, num_glyphs, &valid );
    164      error = valid.error;
    165      if ( error )
    166        goto Exit;
    167    }
    168 
    169    if ( gsub )
    170    {
    171      ft_validator_init( &valid, gsub, gsub + len_gsub, FT_VALIDATE_DEFAULT );
    172      if ( ft_setjmp( valid.jump_buffer ) == 0 )
    173        otv_GSUB_validate( gsub, num_glyphs, &valid );
    174      error = valid.error;
    175      if ( error )
    176        goto Exit;
    177    }
    178 
    179    if ( gdef )
    180    {
    181      ft_validator_init( &valid, gdef, gdef + len_gdef, FT_VALIDATE_DEFAULT );
    182      if ( ft_setjmp( valid.jump_buffer ) == 0 )
    183        otv_GDEF_validate( gdef, gsub, gpos, num_glyphs, &valid );
    184      error = valid.error;
    185      if ( error )
    186        goto Exit;
    187    }
    188 
    189    if ( jstf )
    190    {
    191      ft_validator_init( &valid, jstf, jstf + len_jstf, FT_VALIDATE_DEFAULT );
    192      if ( ft_setjmp( valid.jump_buffer ) == 0 )
    193        otv_JSTF_validate( jstf, gsub, gpos, num_glyphs, &valid );
    194      error = valid.error;
    195      if ( error )
    196        goto Exit;
    197    }
    198 
    199    if ( math )
    200    {
    201      ft_validator_init( &valid, math, math + len_math, FT_VALIDATE_DEFAULT );
    202      if ( ft_setjmp( valid.jump_buffer ) == 0 )
    203        otv_MATH_validate( math, num_glyphs, &valid );
    204      error = valid.error;
    205      if ( error )
    206        goto Exit;
    207    }
    208 
    209    *ot_base = (FT_Bytes)base;
    210    *ot_gdef = (FT_Bytes)gdef;
    211    *ot_gpos = (FT_Bytes)gpos;
    212    *ot_gsub = (FT_Bytes)gsub;
    213    *ot_jstf = (FT_Bytes)jstf;
    214 
    215  Exit:
    216    if ( error )
    217    {
    218      FT_Memory  memory = FT_FACE_MEMORY( face );
    219 
    220 
    221      FT_FREE( base );
    222      FT_FREE( gdef );
    223      FT_FREE( gpos );
    224      FT_FREE( gsub );
    225      FT_FREE( jstf );
    226    }
    227 
    228    {
    229      FT_Memory  memory = FT_FACE_MEMORY( face );
    230 
    231 
    232      FT_FREE( math );                 /* Can't return this as API is frozen */
    233    }
    234 
    235    return error;
    236  }
    237 
    238 
    239  static
    240  const FT_Service_OTvalidateRec  otvalid_interface =
    241  {
    242    otv_validate        /* validate */
    243  };
    244 
    245 
    246  static
    247  const FT_ServiceDescRec  otvalid_services[] =
    248  {
    249    { FT_SERVICE_ID_OPENTYPE_VALIDATE, &otvalid_interface },
    250    { NULL, NULL }
    251  };
    252 
    253 
    254  static FT_Pointer
    255  otvalid_get_service( FT_Module    module,
    256                       const char*  service_id )
    257  {
    258    FT_UNUSED( module );
    259 
    260    return ft_service_list_lookup( otvalid_services, service_id );
    261  }
    262 
    263 
    264  FT_CALLBACK_TABLE_DEF
    265  const FT_Module_Class  otv_module_class =
    266  {
    267    0,
    268    sizeof ( FT_ModuleRec ),
    269    "otvalid",
    270    0x10000L,
    271    0x20000L,
    272 
    273    NULL,              /* module-specific interface */
    274 
    275    (FT_Module_Constructor)NULL,                /* module_init   */
    276    (FT_Module_Destructor) NULL,                /* module_done   */
    277    (FT_Module_Requester)  otvalid_get_service  /* get_interface */
    278  };
    279 
    280 
    281 /* END */