/src/freetype/src/gxvalid/gxvtrak.c

https://bitbucket.org/cabalistic/ogredeps/ · C · 286 lines · 143 code · 60 blank · 83 comment · 15 complexity · 2215414ec2e394cee668b20fc638b58a MD5 · raw file

  1. /***************************************************************************/
  2. /* */
  3. /* gxvtrak.c */
  4. /* */
  5. /* TrueTypeGX/AAT trak table validation (body). */
  6. /* */
  7. /* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */
  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. /* gxvalid is derived from both gxlayout module and otvalid module. */
  20. /* Development of gxlayout is supported by the Information-technology */
  21. /* Promotion Agency(IPA), Japan. */
  22. /* */
  23. /***************************************************************************/
  24. #include "gxvalid.h"
  25. #include "gxvcommn.h"
  26. /*************************************************************************/
  27. /* */
  28. /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
  29. /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
  30. /* messages during execution. */
  31. /* */
  32. #undef FT_COMPONENT
  33. #define FT_COMPONENT trace_gxvtrak
  34. /*************************************************************************/
  35. /*************************************************************************/
  36. /***** *****/
  37. /***** Data and Types *****/
  38. /***** *****/
  39. /*************************************************************************/
  40. /*************************************************************************/
  41. /*
  42. * referred track table format specification:
  43. * http://developer.apple.com/fonts/TTRefMan/RM06/Chap6trak.html
  44. * last update was 1996.
  45. * ----------------------------------------------
  46. * [MINIMUM HEADER]: GXV_TRAK_SIZE_MIN
  47. * version (fixed: 32bit) = 0x00010000
  48. * format (uint16: 16bit) = 0 is only defined (1996)
  49. * horizOffset (uint16: 16bit)
  50. * vertOffset (uint16: 16bit)
  51. * reserved (uint16: 16bit) = 0
  52. * ----------------------------------------------
  53. * [VARIABLE BODY]:
  54. * horizData
  55. * header ( 2 + 2 + 4
  56. * trackTable + nTracks * ( 4 + 2 + 2 )
  57. * sizeTable + nSizes * 4 )
  58. * ----------------------------------------------
  59. * vertData
  60. * header ( 2 + 2 + 4
  61. * trackTable + nTracks * ( 4 + 2 + 2 )
  62. * sizeTable + nSizes * 4 )
  63. * ----------------------------------------------
  64. */
  65. typedef struct GXV_trak_DataRec_
  66. {
  67. FT_UShort trackValueOffset_min;
  68. FT_UShort trackValueOffset_max;
  69. } GXV_trak_DataRec, *GXV_trak_Data;
  70. #define GXV_TRAK_DATA( FIELD ) GXV_TABLE_DATA( trak, FIELD )
  71. /*************************************************************************/
  72. /*************************************************************************/
  73. /***** *****/
  74. /***** UTILITY FUNCTIONS *****/
  75. /***** *****/
  76. /*************************************************************************/
  77. /*************************************************************************/
  78. static void
  79. gxv_trak_trackTable_validate( FT_Bytes table,
  80. FT_Bytes limit,
  81. FT_UShort nTracks,
  82. GXV_Validator valid )
  83. {
  84. FT_Bytes p = table;
  85. FT_Fixed track, t;
  86. FT_UShort nameIndex;
  87. FT_UShort offset;
  88. FT_UShort i, j;
  89. GXV_NAME_ENTER( "trackTable" );
  90. GXV_TRAK_DATA( trackValueOffset_min ) = 0xFFFFU;
  91. GXV_TRAK_DATA( trackValueOffset_max ) = 0x0000;
  92. GXV_LIMIT_CHECK( nTracks * ( 4 + 2 + 2 ) );
  93. for ( i = 0; i < nTracks; i ++ )
  94. {
  95. p = table + i * ( 4 + 2 + 2 );
  96. track = FT_NEXT_LONG( p );
  97. nameIndex = FT_NEXT_USHORT( p );
  98. offset = FT_NEXT_USHORT( p );
  99. if ( offset < GXV_TRAK_DATA( trackValueOffset_min ) )
  100. GXV_TRAK_DATA( trackValueOffset_min ) = offset;
  101. if ( offset > GXV_TRAK_DATA( trackValueOffset_max ) )
  102. GXV_TRAK_DATA( trackValueOffset_max ) = offset;
  103. gxv_sfntName_validate( nameIndex, 256, 32767, valid );
  104. for ( j = i; j < nTracks; j ++ )
  105. {
  106. p = table + j * ( 4 + 2 + 2 );
  107. t = FT_NEXT_LONG( p );
  108. if ( t == track )
  109. GXV_TRACE(( "duplicated entries found for track value 0x%x\n",
  110. track ));
  111. }
  112. }
  113. valid->subtable_length = p - table;
  114. GXV_EXIT;
  115. }
  116. static void
  117. gxv_trak_trackData_validate( FT_Bytes table,
  118. FT_Bytes limit,
  119. GXV_Validator valid )
  120. {
  121. FT_Bytes p = table;
  122. FT_UShort nTracks;
  123. FT_UShort nSizes;
  124. FT_ULong sizeTableOffset;
  125. GXV_ODTECT( 4, odtect );
  126. GXV_ODTECT_INIT( odtect );
  127. GXV_NAME_ENTER( "trackData" );
  128. /* read the header of trackData */
  129. GXV_LIMIT_CHECK( 2 + 2 + 4 );
  130. nTracks = FT_NEXT_USHORT( p );
  131. nSizes = FT_NEXT_USHORT( p );
  132. sizeTableOffset = FT_NEXT_ULONG( p );
  133. gxv_odtect_add_range( table, p - table, "trackData header", odtect );
  134. /* validate trackTable */
  135. gxv_trak_trackTable_validate( p, limit, nTracks, valid );
  136. gxv_odtect_add_range( p, valid->subtable_length,
  137. "trackTable", odtect );
  138. /* sizeTable is array of FT_Fixed, don't check contents */
  139. p = valid->root->base + sizeTableOffset;
  140. GXV_LIMIT_CHECK( nSizes * 4 );
  141. gxv_odtect_add_range( p, nSizes * 4, "sizeTable", odtect );
  142. /* validate trackValueOffet */
  143. p = valid->root->base + GXV_TRAK_DATA( trackValueOffset_min );
  144. if ( limit - p < nTracks * nSizes * 2 )
  145. GXV_TRACE(( "too short trackValue array\n" ));
  146. p = valid->root->base + GXV_TRAK_DATA( trackValueOffset_max );
  147. GXV_LIMIT_CHECK( nSizes * 2 );
  148. gxv_odtect_add_range( valid->root->base
  149. + GXV_TRAK_DATA( trackValueOffset_min ),
  150. GXV_TRAK_DATA( trackValueOffset_max )
  151. - GXV_TRAK_DATA( trackValueOffset_min )
  152. + nSizes * 2,
  153. "trackValue array", odtect );
  154. gxv_odtect_validate( odtect, valid );
  155. GXV_EXIT;
  156. }
  157. /*************************************************************************/
  158. /*************************************************************************/
  159. /***** *****/
  160. /***** trak TABLE *****/
  161. /***** *****/
  162. /*************************************************************************/
  163. /*************************************************************************/
  164. FT_LOCAL_DEF( void )
  165. gxv_trak_validate( FT_Bytes table,
  166. FT_Face face,
  167. FT_Validator ftvalid )
  168. {
  169. FT_Bytes p = table;
  170. FT_Bytes limit = 0;
  171. GXV_ValidatorRec validrec;
  172. GXV_Validator valid = &validrec;
  173. GXV_trak_DataRec trakrec;
  174. GXV_trak_Data trak = &trakrec;
  175. FT_ULong version;
  176. FT_UShort format;
  177. FT_UShort horizOffset;
  178. FT_UShort vertOffset;
  179. FT_UShort reserved;
  180. GXV_ODTECT( 3, odtect );
  181. GXV_ODTECT_INIT( odtect );
  182. valid->root = ftvalid;
  183. valid->table_data = trak;
  184. valid->face = face;
  185. limit = valid->root->limit;
  186. FT_TRACE3(( "validating `trak' table\n" ));
  187. GXV_INIT;
  188. GXV_LIMIT_CHECK( 4 + 2 + 2 + 2 + 2 );
  189. version = FT_NEXT_ULONG( p );
  190. format = FT_NEXT_USHORT( p );
  191. horizOffset = FT_NEXT_USHORT( p );
  192. vertOffset = FT_NEXT_USHORT( p );
  193. reserved = FT_NEXT_USHORT( p );
  194. GXV_TRACE(( " (version = 0x%08x)\n", version ));
  195. GXV_TRACE(( " (format = 0x%04x)\n", format ));
  196. GXV_TRACE(( " (horizOffset = 0x%04x)\n", horizOffset ));
  197. GXV_TRACE(( " (vertOffset = 0x%04x)\n", vertOffset ));
  198. GXV_TRACE(( " (reserved = 0x%04x)\n", reserved ));
  199. /* Version 1.0 (always:1996) */
  200. if ( version != 0x00010000UL )
  201. FT_INVALID_FORMAT;
  202. /* format 0 (always:1996) */
  203. if ( format != 0x0000 )
  204. FT_INVALID_FORMAT;
  205. GXV_32BIT_ALIGNMENT_VALIDATE( horizOffset );
  206. GXV_32BIT_ALIGNMENT_VALIDATE( vertOffset );
  207. /* Reserved Fixed Value (always) */
  208. if ( reserved != 0x0000 )
  209. FT_INVALID_DATA;
  210. /* validate trackData */
  211. if ( 0 < horizOffset )
  212. {
  213. gxv_trak_trackData_validate( table + horizOffset, limit, valid );
  214. gxv_odtect_add_range( table + horizOffset, valid->subtable_length,
  215. "horizJustData", odtect );
  216. }
  217. if ( 0 < vertOffset )
  218. {
  219. gxv_trak_trackData_validate( table + vertOffset, limit, valid );
  220. gxv_odtect_add_range( table + vertOffset, valid->subtable_length,
  221. "vertJustData", odtect );
  222. }
  223. gxv_odtect_validate( odtect, valid );
  224. FT_TRACE4(( "\n" ));
  225. }
  226. /* END */