summaryrefslogtreecommitdiffstats
path: root/src/gxvalid/gxvtrak.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gxvalid/gxvtrak.c')
-rw-r--r--src/gxvalid/gxvtrak.c277
1 files changed, 277 insertions, 0 deletions
diff --git a/src/gxvalid/gxvtrak.c b/src/gxvalid/gxvtrak.c
new file mode 100644
index 0000000..432ee4e
--- /dev/null
+++ b/src/gxvalid/gxvtrak.c
@@ -0,0 +1,277 @@
+/***************************************************************************/
+/* */
+/* gxvtrak.c */
+/* */
+/* TrueTypeGX/AAT trak table validation (body). */
+/* */
+/* Copyright 2004, 2005 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 "gxvalid.h"
+#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 trace_gxvtrak
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+ /***** Data and Types *****/
+ /***** *****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ /*
+ * referred track table format specification:
+ * http://developer.apple.com/fonts/TTRefMan/RM06/Chap6trak.html
+ * last update was 1996.
+ * ----------------------------------------------
+ * [MINIMUM HEADER]: GXV_TRAK_SIZE_MIN
+ * version (fixed: 32bit) = 0x00010000
+ * format (uint16: 16bit) = 0 is only defined (1996)
+ * horizOffset (uint16: 16bit)
+ * vertOffset (uint16: 16bit)
+ * reserved (uint16: 16bit) = 0
+ * ----------------------------------------------
+ * [VARIABLE BODY]:
+ * horizData
+ * header ( 2 + 2 + 4
+ * trackTable + nTracks * ( 4 + 2 + 2 )
+ * sizeTable + nSizes * 4 )
+ * ----------------------------------------------
+ * vertData
+ * header ( 2 + 2 + 4
+ * trackTable + nTracks * ( 4 + 2 + 2 )
+ * sizeTable + nSizes * 4 )
+ * ----------------------------------------------
+ */
+ typedef struct GXV_trak_DataRec_
+ {
+ FT_UShort trackValueOffset_min;
+ FT_UShort trackValueOffset_max;
+
+ } GXV_trak_DataRec, *GXV_trak_Data;
+
+
+#define GXV_TRAK_DATA( FIELD ) GXV_TABLE_DATA( trak, FIELD )
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+ /***** UTILITY FUNCTIONS *****/
+ /***** *****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ static void
+ gxv_trak_trackTable_validate( FT_Bytes table,
+ FT_Bytes limit,
+ FT_UShort nTracks,
+ GXV_Validator valid )
+ {
+ FT_Bytes p = table;
+
+ FT_Fixed track;
+ FT_UShort nameIndex;
+ FT_UShort offset;
+ FT_UShort i;
+
+
+ GXV_NAME_ENTER( "trackTable" );
+
+ GXV_TRAK_DATA( trackValueOffset_min ) = 0xFFFFU;
+ GXV_TRAK_DATA( trackValueOffset_max ) = 0x0000;
+
+ for ( i = 0; i < nTracks; i ++ )
+ {
+ GXV_LIMIT_CHECK( 4 + 2 + 2 );
+ track = FT_NEXT_LONG( p );
+ nameIndex = FT_NEXT_USHORT( p );
+ offset = FT_NEXT_USHORT( p );
+
+ if ( offset < GXV_TRAK_DATA( trackValueOffset_min ) )
+ GXV_TRAK_DATA( trackValueOffset_min ) = offset;
+ if ( offset > GXV_TRAK_DATA( trackValueOffset_max ) )
+ GXV_TRAK_DATA( trackValueOffset_max ) = offset;
+
+ gxv_sfntName_validate( nameIndex, 256, 32767, valid );
+ }
+
+ valid->subtable_length = p - table;
+ GXV_EXIT;
+ }
+
+
+ static void
+ gxv_trak_trackData_validate( FT_Bytes table,
+ FT_Bytes limit,
+ GXV_Validator valid )
+ {
+ FT_Bytes p = table;
+ FT_UShort nTracks;
+ FT_UShort nSizes;
+ FT_ULong sizeTableOffset;
+
+ GXV_ODTECT( 4, odtect );
+
+
+ GXV_ODTECT_INIT( odtect );
+ GXV_NAME_ENTER( "trackData" );
+
+ /* read the header of trackData */
+ GXV_LIMIT_CHECK( 2 + 2 + 4 );
+ nTracks = FT_NEXT_USHORT( p );
+ nSizes = FT_NEXT_USHORT( p );
+ sizeTableOffset = FT_NEXT_ULONG( p );
+
+ gxv_odtect_add_range( table, p - table, "trackData header", odtect );
+
+ /* validate trackTable */
+ gxv_trak_trackTable_validate( p, limit, nTracks, valid );
+ gxv_odtect_add_range( p, valid->subtable_length,
+ "trackTable", odtect );
+
+ /* sizeTable is array of FT_Fixed, don't check contents */
+ p = valid->root->base + sizeTableOffset;
+ GXV_LIMIT_CHECK( nSizes * 4 );
+ gxv_odtect_add_range( p, nSizes * 4, "sizeTable", odtect );
+
+ /* validate trackValueOffet */
+ p = valid->root->base + GXV_TRAK_DATA( trackValueOffset_min );
+ if ( limit - p < nTracks * nSizes * 2 )
+ GXV_TRACE(( "too short trackValue array\n" ));
+
+ p = valid->root->base + GXV_TRAK_DATA( trackValueOffset_max );
+ GXV_LIMIT_CHECK( nSizes * 2 );
+
+ gxv_odtect_add_range( valid->root->base
+ + GXV_TRAK_DATA( trackValueOffset_min ),
+ GXV_TRAK_DATA( trackValueOffset_max )
+ - GXV_TRAK_DATA( trackValueOffset_min )
+ + nSizes * 2,
+ "trackValue array", odtect );
+
+ gxv_odtect_validate( odtect, valid );
+
+ GXV_EXIT;
+ }
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /***** *****/
+ /***** trak TABLE *****/
+ /***** *****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ FT_LOCAL_DEF( void )
+ gxv_trak_validate( FT_Bytes table,
+ FT_Face face,
+ FT_Validator ftvalid )
+ {
+ FT_Bytes p = table;
+ FT_Bytes limit = 0;
+ FT_UInt table_size;
+
+ GXV_ValidatorRec validrec;
+ GXV_Validator valid = &validrec;
+ GXV_trak_DataRec trakrec;
+ GXV_trak_Data trak = &trakrec;
+
+ FT_ULong version;
+ FT_UShort format;
+ FT_UShort horizOffset;
+ FT_UShort vertOffset;
+ FT_UShort reserved;
+
+
+ GXV_ODTECT( 3, odtect );
+
+ GXV_ODTECT_INIT( odtect );
+ valid->root = ftvalid;
+ valid->table_data = trak;
+ valid->face = face;
+
+ limit = valid->root->limit;
+ table_size = limit - table;
+
+ FT_TRACE3(( "validating `trak' table\n" ));
+ GXV_INIT;
+
+ GXV_LIMIT_CHECK( 4 + 2 + 2 + 2 + 2 );
+ version = FT_NEXT_ULONG( p );
+ format = FT_NEXT_USHORT( p );
+ horizOffset = FT_NEXT_USHORT( p );
+ vertOffset = FT_NEXT_USHORT( p );
+ reserved = FT_NEXT_USHORT( p );
+
+ GXV_TRACE(( " (version = 0x%08x)\n", version ));
+ GXV_TRACE(( " (format = 0x%04x)\n", format ));
+ GXV_TRACE(( " (horizOffset = 0x%04x)\n", horizOffset ));
+ GXV_TRACE(( " (vertOffset = 0x%04x)\n", vertOffset ));
+ GXV_TRACE(( " (reserved = 0x%04x)\n", reserved ));
+
+ /* Version 1.0 (always:1996) */
+ if ( version != 0x00010000UL )
+ FT_INVALID_FORMAT;
+
+ /* format 0 (always:1996) */
+ if ( format != 0x0000 )
+ FT_INVALID_FORMAT;
+
+ GXV_32BIT_ALIGNMENT_VALIDATE( horizOffset );
+ GXV_32BIT_ALIGNMENT_VALIDATE( vertOffset );
+
+ /* Reserved Fixed Value (always) */
+ if ( reserved != 0x0000 )
+ FT_INVALID_DATA;
+
+ /* validate trackData */
+ if ( 0 < horizOffset )
+ {
+ gxv_trak_trackData_validate( table + horizOffset, limit, valid );
+ gxv_odtect_add_range( table + horizOffset, valid->subtable_length,
+ "horizJustData", odtect );
+ }
+
+ if ( 0 < vertOffset )
+ {
+ gxv_trak_trackData_validate( table + vertOffset, limit, valid );
+ gxv_odtect_add_range( table + vertOffset, valid->subtable_length,
+ "vertJustData", odtect );
+ }
+
+ gxv_odtect_validate( odtect, valid );
+
+ FT_TRACE4(( "\n" ));
+ }
+
+
+/* END */