/**************************************************************************** * * gxvcommn.c * * TrueTypeGX/AAT common tables validation (body). * * Copyright (C) 2004-2023 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 "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 … /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** 16bit offset sorter *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ FT_COMPARE_DEF( int ) gxv_compare_ushort_offset( const void* a, const void* b ) { … } FT_LOCAL_DEF( 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 ) { … } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** 32bit offset sorter *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ FT_COMPARE_DEF( int ) gxv_compare_ulong_offset( const void* a, const void* b ) { … } FT_LOCAL_DEF( 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) { … } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** scan value array and get min & max *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ FT_LOCAL_DEF( void ) gxv_array_getlimits_byte( FT_Bytes table, FT_Bytes limit, FT_Byte* min, FT_Byte* max, GXV_Validator gxvalid ) { … } FT_LOCAL_DEF( void ) gxv_array_getlimits_ushort( FT_Bytes table, FT_Bytes limit, FT_UShort* min, FT_UShort* max, GXV_Validator gxvalid ) { … } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** BINSEARCHHEADER *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ GXV_BinSrchHeader; static void gxv_BinSrchHeader_check_consistency( GXV_BinSrchHeader* binSrchHeader, GXV_Validator gxvalid ) { … } /* * parser & validator of BinSrchHeader * which is used in LookupTable format 2, 4, 6. * * Essential parameters (unitSize, nUnits) are returned by * given pointer, others (searchRange, entrySelector, rangeShift) * can be calculated by essential parameters, so they are just * validated and discarded. * * However, wrong values in searchRange, entrySelector, rangeShift * won't cause fatal errors, because these parameters might be * only used in old m68k font driver in MacOS. * -- suzuki toshiya <[email protected]> */ FT_LOCAL_DEF( void ) gxv_BinSrchHeader_validate( FT_Bytes table, FT_Bytes limit, FT_UShort* unitSize_p, FT_UShort* nUnits_p, GXV_Validator gxvalid ) { … } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** LOOKUP TABLE *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ #define GXV_LOOKUP_VALUE_LOAD( P, SIGNSPEC ) … static GXV_LookupValueDesc gxv_lookup_value_load( FT_Bytes p, GXV_LookupValue_SignSpec signspec ) { … } #define GXV_UNITSIZE_VALIDATE( FORMAT, UNITSIZE, NUNITS, CORRECTSIZE ) … /* ================= Simple Array Format 0 Lookup Table ================ */ static void gxv_LookupTable_fmt0_validate( FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid ) { … } /* ================= Segment Single Format 2 Lookup Table ============== */ /* * Apple spec says: * * To guarantee that a binary search terminates, you must include one or * more special `end of search table' values at the end of the data to * be searched. The number of termination values that need to be * included is table-specific. The value that indicates binary search * termination is 0xFFFF. * * The problem is that nUnits does not include this end-marker. It's * quite difficult to discriminate whether the following 0xFFFF comes from * the end-marker or some next data. * * -- suzuki toshiya <[email protected]> */ static void gxv_LookupTable_fmt2_skip_endmarkers( FT_Bytes table, FT_UShort unitSize, GXV_Validator gxvalid ) { … } static void gxv_LookupTable_fmt2_validate( FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid ) { … } /* ================= Segment Array Format 4 Lookup Table =============== */ static void gxv_LookupTable_fmt4_validate( FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid ) { … } /* ================= Segment Table Format 6 Lookup Table =============== */ static void gxv_LookupTable_fmt6_skip_endmarkers( FT_Bytes table, FT_UShort unitSize, GXV_Validator gxvalid ) { … } static void gxv_LookupTable_fmt6_validate( FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid ) { … } /* ================= Trimmed Array Format 8 Lookup Table =============== */ static void gxv_LookupTable_fmt8_validate( FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid ) { … } FT_LOCAL_DEF( void ) gxv_LookupTable_validate( FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid ) { … } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** Glyph ID *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ FT_LOCAL_DEF( FT_Int ) gxv_glyphid_validate( FT_UShort gid, GXV_Validator gxvalid ) { … } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** CONTROL POINT *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ FT_LOCAL_DEF( void ) gxv_ctlPoint_validate( FT_UShort gid, FT_UShort ctl_point, GXV_Validator gxvalid ) { … } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** SFNT NAME *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ FT_LOCAL_DEF( void ) gxv_sfntName_validate( FT_UShort name_index, FT_UShort min_index, FT_UShort max_index, GXV_Validator gxvalid ) { … } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** STATE TABLE *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /* -------------------------- Class Table --------------------------- */ /* * highestClass specifies how many classes are defined in this * Class Subtable. Apple spec does not mention whether undefined * holes in the class (e.g.: 0-3 are predefined, 4 is unused, 5 is used) * are permitted. At present, holes in a defined class are not checked. * -- suzuki toshiya <[email protected]> */ static void gxv_ClassTable_validate( FT_Bytes table, FT_UShort* length_p, FT_UShort stateSize, FT_Byte* maxClassID_p, GXV_Validator gxvalid ) { … } /* --------------------------- State Array ----------------------------- */ static void gxv_StateArray_validate( FT_Bytes table, FT_UShort* length_p, FT_Byte maxClassID, FT_UShort stateSize, FT_Byte* maxState_p, FT_Byte* maxEntry_p, GXV_Validator gxvalid ) { … } /* --------------------------- Entry Table ----------------------------- */ static void gxv_EntryTable_validate( FT_Bytes table, FT_UShort* length_p, FT_Byte maxEntry, FT_UShort stateArray, FT_UShort stateArray_length, FT_Byte maxClassID, FT_Bytes statetable_table, FT_Bytes statetable_limit, GXV_Validator gxvalid ) { … } /* =========================== State Table ============================= */ FT_LOCAL_DEF( 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_DEF( void ) gxv_StateTable_validate( FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid ) { … } /* ================= eXtended State Table (for morx) =================== */ FT_LOCAL_DEF( 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 ) { … } static void gxv_XClassTable_lookupval_validate( FT_UShort glyph, GXV_LookupValueCPtr value_p, GXV_Validator gxvalid ) { … } /* +===============+ --------+ | lookup header | | +===============+ | | BinSrchHeader | | +===============+ | | lastGlyph[0] | | +---------------+ | | firstGlyph[0] | | head of lookup table +---------------+ | + | offset[0] | -> | offset [byte] +===============+ | + | lastGlyph[1] | | (glyphID - firstGlyph) * 2 [byte] +---------------+ | | firstGlyph[1] | | +---------------+ | | offset[1] | | +===============+ | | .... | | 16bit value array | +===============+ | | value | <-------+ .... */ static GXV_LookupValueDesc gxv_XClassTable_lookupfmt4_transit( FT_UShort relative_gindex, GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, GXV_Validator gxvalid ) { … } static void gxv_XStateArray_validate( FT_Bytes table, FT_ULong* length_p, FT_UShort maxClassID, FT_ULong stateSize, FT_UShort* maxState_p, FT_UShort* maxEntry_p, GXV_Validator gxvalid ) { … } static void gxv_XEntryTable_validate( FT_Bytes table, FT_ULong* length_p, FT_UShort maxEntry, FT_ULong stateArray_length, FT_UShort maxClassID, FT_Bytes xstatetable_table, FT_Bytes xstatetable_limit, GXV_Validator gxvalid ) { … } FT_LOCAL_DEF( void ) gxv_XStateTable_validate( FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid ) { … } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** Table overlapping *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ static int gxv_compare_ranges( FT_Bytes table1_start, FT_ULong table1_length, FT_Bytes table2_start, FT_ULong table2_length ) { … } FT_LOCAL_DEF( void ) gxv_odtect_add_range( FT_Bytes start, FT_ULong length, const FT_String* name, GXV_odtect_Range odtect ) { … } FT_LOCAL_DEF( void ) gxv_odtect_validate( GXV_odtect_Range odtect, GXV_Validator gxvalid ) { … } /* END */