blob: b79b641142ccab12fe54ae3fb5ce4e3c3f6d7383 [file] [log] [blame]
/****************************************************************************
*
* gxvcommn.h
*
* TrueTypeGX/AAT common tables validation (specification).
*
* Copyright (C) 2004-2021 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.
*
*/
/*
* keywords in variable naming
* ---------------------------
* table: Of type FT_Bytes, pointing to the start of this table/subtable.
* limit: Of type FT_Bytes, pointing to the end of this table/subtable,
* including padding for alignment.
* offset: Of type FT_UInt, the number of octets from the start to target.
* length: Of type FT_UInt, the number of octets from the start to the
* end in this table/subtable, including padding for alignment.
*
* _MIN, _MAX: Should be added to the tail of macros, as INT_MIN, etc.
*/
#ifndef GXVCOMMN_H_
#define GXVCOMMN_H_
#include "gxvalid.h"
#include <freetype/internal/ftdebug.h>
#include <freetype/ftsnames.h>
FT_BEGIN_HEADER
/* some variables are not evaluated or only used in trace */
#ifdef FT_DEBUG_LEVEL_TRACE
#define GXV_LOAD_TRACE_VARS
#else
#undef GXV_LOAD_TRACE_VARS
#endif
#undef GXV_LOAD_UNUSED_VARS /* debug purpose */
#define IS_PARANOID_VALIDATION \
( gxvalid->root->level >= FT_VALIDATE_PARANOID )
#define GXV_SET_ERR_IF_PARANOID( err ) \
do { if ( IS_PARANOID_VALIDATION ) ( err ); } while ( 0 )
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** VALIDATION *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
typedef struct GXV_ValidatorRec_* GXV_Validator;
#define DUMMY_LIMIT 0
typedef void
(*GXV_Validate_Func)( FT_Bytes table,
FT_Bytes limit,
GXV_Validator gxvalid );
/* ====================== LookupTable Validator ======================== */
typedef union GXV_LookupValueDesc_
{
FT_UShort u;
FT_Short s;
} GXV_LookupValueDesc;
typedef const GXV_LookupValueDesc* GXV_LookupValueCPtr;
typedef enum GXV_LookupValue_SignSpec_
{
GXV_LOOKUPVALUE_UNSIGNED = 0,
GXV_LOOKUPVALUE_SIGNED
} GXV_LookupValue_SignSpec;
typedef void
(*GXV_Lookup_Value_Validate_Func)( FT_UShort glyph,
GXV_LookupValueCPtr value_p,
GXV_Validator gxvalid );
typedef GXV_LookupValueDesc
(*GXV_Lookup_Fmt4_Transit_Func)( FT_UShort relative_gindex,
GXV_LookupValueCPtr base_value_p,
FT_Bytes lookuptbl_limit,
GXV_Validator gxvalid );
/* ====================== StateTable Validator ========================= */
typedef enum GXV_GlyphOffset_Format_
{
GXV_GLYPHOFFSET_NONE = -1,
GXV_GLYPHOFFSET_UCHAR = 2,
GXV_GLYPHOFFSET_CHAR,
GXV_GLYPHOFFSET_USHORT = 4,
GXV_GLYPHOFFSET_SHORT,
GXV_GLYPHOFFSET_ULONG = 8,
GXV_GLYPHOFFSET_LONG
} GXV_GlyphOffset_Format;
#define GXV_GLYPHOFFSET_FMT( table ) \
( gxvalid->table.entry_glyphoffset_fmt )
#define GXV_GLYPHOFFSET_SIZE( table ) \
( gxvalid->table.entry_glyphoffset_fmt / 2 )
/* ----------------------- 16bit StateTable ---------------------------- */
typedef union GXV_StateTable_GlyphOffsetDesc_
{
FT_Byte uc;
FT_UShort u; /* same as GXV_LookupValueDesc */
FT_ULong ul;
FT_Char c;
FT_Short s; /* same as GXV_LookupValueDesc */
FT_Long l;
} GXV_StateTable_GlyphOffsetDesc;
typedef const GXV_StateTable_GlyphOffsetDesc* GXV_StateTable_GlyphOffsetCPtr;
typedef void
(*GXV_StateTable_Subtable_Setup_Func)( FT_UShort table_size,
FT_UShort classTable,
FT_UShort stateArray,
FT_UShort entryTable,
FT_UShort* classTable_length_p,
FT_UShort* stateArray_length_p,
FT_UShort* entryTable_length_p,
GXV_Validator gxvalid );
typedef void
(*GXV_StateTable_Entry_Validate_Func)(
FT_Byte state,
FT_UShort flags,
GXV_StateTable_GlyphOffsetCPtr glyphOffset_p,
FT_Bytes statetable_table,
FT_Bytes statetable_limit,
GXV_Validator gxvalid );
typedef void
(*GXV_StateTable_OptData_Load_Func)( FT_Bytes table,
FT_Bytes limit,
GXV_Validator gxvalid );
typedef struct GXV_StateTable_ValidatorRec_
{
GXV_GlyphOffset_Format entry_glyphoffset_fmt;
void* optdata;
GXV_StateTable_Subtable_Setup_Func subtable_setup_func;
GXV_StateTable_Entry_Validate_Func entry_validate_func;
GXV_StateTable_OptData_Load_Func optdata_load_func;
} GXV_StateTable_ValidatorRec, *GXV_StateTable_ValidatorRecData;
/* ---------------------- 32bit XStateTable ---------------------------- */
typedef GXV_StateTable_GlyphOffsetDesc GXV_XStateTable_GlyphOffsetDesc;
typedef const GXV_XStateTable_GlyphOffsetDesc* GXV_XStateTable_GlyphOffsetCPtr;
typedef void
(*GXV_XStateTable_Subtable_Setup_Func)( FT_ULong table_size,
FT_ULong classTable,
FT_ULong stateArray,
FT_ULong entryTable,
FT_ULong* classTable_length_p,
FT_ULong* stateArray_length_p,
FT_ULong* entryTable_length_p,
GXV_Validator gxvalid );
typedef void
(*GXV_XStateTable_Entry_Validate_Func)(
FT_UShort state,
FT_UShort flags,
GXV_StateTable_GlyphOffsetCPtr glyphOffset_p,
FT_Bytes xstatetable_table,
FT_Bytes xstatetable_limit,
GXV_Validator gxvalid );
typedef GXV_StateTable_OptData_Load_Func GXV_XStateTable_OptData_Load_Func;
typedef struct GXV_XStateTable_ValidatorRec_
{
int entry_glyphoffset_fmt;
void* optdata;
GXV_XStateTable_Subtable_Setup_Func subtable_setup_func;
GXV_XStateTable_Entry_Validate_Func entry_validate_func;
GXV_XStateTable_OptData_Load_Func optdata_load_func;
FT_ULong nClasses;
FT_UShort maxClassID;
} GXV_XStateTable_ValidatorRec, *GXV_XStateTable_ValidatorRecData;
/* ===================================================================== */
typedef struct GXV_ValidatorRec_
{
FT_Validator root;
FT_Face face;
void* table_data;
FT_ULong subtable_length;
GXV_LookupValue_SignSpec lookupval_sign;
GXV_Lookup_Value_Validate_Func lookupval_func;
GXV_Lookup_Fmt4_Transit_Func lookupfmt4_trans;
FT_Bytes lookuptbl_head;
FT_UShort min_gid;
FT_UShort max_gid;
GXV_StateTable_ValidatorRec statetable;
GXV_XStateTable_ValidatorRec xstatetable;
#ifdef FT_DEBUG_LEVEL_TRACE
FT_UInt debug_indent;
const FT_String* debug_function_name[3];
#endif
} GXV_ValidatorRec;
#define GXV_TABLE_DATA( tag, field ) \
( ( (GXV_ ## tag ## _Data)gxvalid->table_data )->field )
#undef FT_INVALID_
#define FT_INVALID_( _error ) \
ft_validator_error( gxvalid->root, FT_THROW( _error ) )
#define GXV_LIMIT_CHECK( _count ) \
FT_BEGIN_STMNT \
if ( p + _count > ( limit? limit : gxvalid->root->limit ) ) \
FT_INVALID_TOO_SHORT; \
FT_END_STMNT
#ifdef FT_DEBUG_LEVEL_TRACE
#define GXV_INIT gxvalid->debug_indent = 0
#define GXV_NAME_ENTER( name ) \
FT_BEGIN_STMNT \
gxvalid->debug_indent += 2; \
FT_TRACE4(( "%*.s", gxvalid->debug_indent, "" )); \
FT_TRACE4(( "%s table\n", name )); \
FT_END_STMNT
#define GXV_EXIT gxvalid->debug_indent -= 2
#define GXV_TRACE( s ) \
FT_BEGIN_STMNT \
FT_TRACE4(( "%*.s", gxvalid->debug_indent, "" )); \
FT_TRACE4( s ); \
FT_END_STMNT
#else /* !FT_DEBUG_LEVEL_TRACE */
#define GXV_INIT do { } while ( 0 )
#define GXV_NAME_ENTER( name ) do { } while ( 0 )
#define GXV_EXIT do { } while ( 0 )
#define GXV_TRACE( s ) do { } while ( 0 )
#endif /* !FT_DEBUG_LEVEL_TRACE */
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** 32bit alignment checking *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
#define GXV_32BIT_ALIGNMENT_VALIDATE( a ) \
FT_BEGIN_STMNT \
{ \
if ( (a) & 3 ) \
FT_INVALID_OFFSET; \
} \
FT_END_STMNT
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** Dumping Binary Data *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
#define GXV_TRACE_HEXDUMP( p, len ) \
FT_BEGIN_STMNT \
{ \
FT_Bytes b; \
\
\
for ( b = p; b < (FT_Bytes)p + len; b++ ) \
FT_TRACE1(("\\x%02x", *b)); \
} \
FT_END_STMNT
#define GXV_TRACE_HEXDUMP_C( p, len ) \
FT_BEGIN_STMNT \
{ \
FT_Bytes b; \
\
\
for ( b = p; b < (FT_Bytes)p + len; b++ ) \
if ( 0x40 < *b && *b < 0x7E ) \
FT_TRACE1(("%c", *b)); \
else \
FT_TRACE1(("\\x%02x", *b)); \
} \
FT_END_STMNT
#define GXV_TRACE_HEXDUMP_SFNTNAME( n ) \
GXV_TRACE_HEXDUMP( n.string, n.string_len )
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** LOOKUP TABLE *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
FT_LOCAL( void )
gxv_BinSrchHeader_validate( FT_Bytes p,
FT_Bytes limit,
FT_UShort* unitSize_p,
FT_UShort* nUnits_p,
GXV_Validator gxvalid );
FT_LOCAL( void )
gxv_LookupTable_validate( FT_Bytes table,
FT_Bytes limit,
GXV_Validator gxvalid );
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** Glyph ID *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
FT_LOCAL( FT_Int )
gxv_glyphid_validate( FT_UShort gid,
GXV_Validator gxvalid );
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** CONTROL POINT *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
FT_LOCAL( void )
gxv_ctlPoint_validate( FT_UShort gid,
FT_UShort ctl_point,
GXV_Validator gxvalid );
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** SFNT NAME *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
FT_LOCAL( void )
gxv_sfntName_validate( FT_UShort name_index,
FT_UShort min_index,
FT_UShort max_index,
GXV_Validator gxvalid );
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** STATE TABLE *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
FT_LOCAL( void )
gxv_StateTable_subtable_setup( FT_UShort table_size,
FT_UShort classTable,
FT_UShort stateArray,
FT_UShort entryTable,
FT_UShort* classTable_length_p,
FT_UShort* stateArray_length_p,
FT_UShort* entryTable_length_p,
GXV_Validator gxvalid );
FT_LOCAL( void )
gxv_XStateTable_subtable_setup( FT_ULong table_size,
FT_ULong classTable,
FT_ULong stateArray,
FT_ULong entryTable,
FT_ULong* classTable_length_p,
FT_ULong* stateArray_length_p,
FT_ULong* entryTable_length_p,
GXV_Validator gxvalid );
FT_LOCAL( void )
gxv_StateTable_validate( FT_Bytes table,
FT_Bytes limit,
GXV_Validator gxvalid );
FT_LOCAL( void )
gxv_XStateTable_validate( FT_Bytes table,
FT_Bytes limit,
GXV_Validator gxvalid );
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** UTILITY MACROS AND FUNCTIONS *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
FT_LOCAL( void )
gxv_array_getlimits_byte( FT_Bytes table,
FT_Bytes limit,
FT_Byte* min,
FT_Byte* max,
GXV_Validator gxvalid );
FT_LOCAL( void )
gxv_array_getlimits_ushort( FT_Bytes table,
FT_Bytes limit,
FT_UShort* min,
FT_UShort* max,
GXV_Validator gxvalid );
FT_LOCAL( void )
gxv_set_length_by_ushort_offset( FT_UShort* offset,
FT_UShort** length,
FT_UShort* buff,
FT_UInt nmemb,
FT_UShort limit,
GXV_Validator gxvalid );
FT_LOCAL( void )
gxv_set_length_by_ulong_offset( FT_ULong* offset,
FT_ULong** length,
FT_ULong* buff,
FT_UInt nmemb,
FT_ULong limit,
GXV_Validator gxvalid);
#define GXV_SUBTABLE_OFFSET_CHECK( _offset ) \
FT_BEGIN_STMNT \
if ( (_offset) > gxvalid->subtable_length ) \
FT_INVALID_OFFSET; \
FT_END_STMNT
#define GXV_SUBTABLE_LIMIT_CHECK( _count ) \
FT_BEGIN_STMNT \
if ( ( p + (_count) - gxvalid->subtable_start ) > \
gxvalid->subtable_length ) \
FT_INVALID_TOO_SHORT; \
FT_END_STMNT
#define GXV_USHORT_TO_SHORT( _us ) \
( ( 0x8000U < ( _us ) ) ? ( ( _us ) - 0x8000U ) : ( _us ) )
#define GXV_STATETABLE_HEADER_SIZE ( 2 + 2 + 2 + 2 )
#define GXV_STATEHEADER_SIZE GXV_STATETABLE_HEADER_SIZE
#define GXV_XSTATETABLE_HEADER_SIZE ( 4 + 4 + 4 + 4 )
#define GXV_XSTATEHEADER_SIZE GXV_XSTATETABLE_HEADER_SIZE
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** Table overlapping *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
typedef struct GXV_odtect_DataRec_
{
FT_Bytes start;
FT_ULong length;
FT_String* name;
} GXV_odtect_DataRec, *GXV_odtect_Data;
typedef struct GXV_odtect_RangeRec_
{
FT_UInt nRanges;
GXV_odtect_Data range;
} GXV_odtect_RangeRec, *GXV_odtect_Range;
FT_LOCAL( void )
gxv_odtect_add_range( FT_Bytes start,
FT_ULong length,
const FT_String* name,
GXV_odtect_Range odtect );
FT_LOCAL( void )
gxv_odtect_validate( GXV_odtect_Range odtect,
GXV_Validator gxvalid );
#define GXV_ODTECT( n, odtect ) \
GXV_odtect_DataRec odtect ## _range[n]; \
GXV_odtect_RangeRec odtect ## _rec = { 0, NULL }; \
GXV_odtect_Range odtect = NULL
#define GXV_ODTECT_INIT( odtect ) \
FT_BEGIN_STMNT \
odtect ## _rec.nRanges = 0; \
odtect ## _rec.range = odtect ## _range; \
odtect = & odtect ## _rec; \
FT_END_STMNT
/* */
FT_END_HEADER
#endif /* GXVCOMMN_H_ */
/* END */