/src/freetype/src/otvalid/otvcommn.c

https://bitbucket.org/cabalistic/ogredeps/ · C · 1086 lines · 613 code · 339 blank · 134 comment · 76 complexity · 81979eae8db8a538ab47fc2c98d2d83c MD5 · raw file

  1. /***************************************************************************/
  2. /* */
  3. /* otvcommn.c */
  4. /* */
  5. /* OpenType common tables validation (body). */
  6. /* */
  7. /* Copyright 2004, 2005, 2006, 2007 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. #include "otvcommn.h"
  18. /*************************************************************************/
  19. /* */
  20. /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
  21. /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
  22. /* messages during execution. */
  23. /* */
  24. #undef FT_COMPONENT
  25. #define FT_COMPONENT trace_otvcommon
  26. /*************************************************************************/
  27. /*************************************************************************/
  28. /***** *****/
  29. /***** COVERAGE TABLE *****/
  30. /***** *****/
  31. /*************************************************************************/
  32. /*************************************************************************/
  33. FT_LOCAL_DEF( void )
  34. otv_Coverage_validate( FT_Bytes table,
  35. OTV_Validator valid,
  36. FT_Int expected_count )
  37. {
  38. FT_Bytes p = table;
  39. FT_UInt CoverageFormat;
  40. FT_UInt total = 0;
  41. OTV_NAME_ENTER( "Coverage" );
  42. OTV_LIMIT_CHECK( 4 );
  43. CoverageFormat = FT_NEXT_USHORT( p );
  44. OTV_TRACE(( " (format %d)\n", CoverageFormat ));
  45. switch ( CoverageFormat )
  46. {
  47. case 1: /* CoverageFormat1 */
  48. {
  49. FT_UInt GlyphCount;
  50. FT_UInt i;
  51. GlyphCount = FT_NEXT_USHORT( p );
  52. OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
  53. OTV_LIMIT_CHECK( GlyphCount * 2 ); /* GlyphArray */
  54. for ( i = 0; i < GlyphCount; ++i )
  55. {
  56. FT_UInt gid;
  57. gid = FT_NEXT_USHORT( p );
  58. if ( gid >= valid->glyph_count )
  59. FT_INVALID_GLYPH_ID;
  60. }
  61. total = GlyphCount;
  62. }
  63. break;
  64. case 2: /* CoverageFormat2 */
  65. {
  66. FT_UInt n, RangeCount;
  67. FT_UInt Start, End, StartCoverageIndex, last = 0;
  68. RangeCount = FT_NEXT_USHORT( p );
  69. OTV_TRACE(( " (RangeCount = %d)\n", RangeCount ));
  70. OTV_LIMIT_CHECK( RangeCount * 6 );
  71. /* RangeRecord */
  72. for ( n = 0; n < RangeCount; n++ )
  73. {
  74. Start = FT_NEXT_USHORT( p );
  75. End = FT_NEXT_USHORT( p );
  76. StartCoverageIndex = FT_NEXT_USHORT( p );
  77. if ( Start > End || StartCoverageIndex != total )
  78. FT_INVALID_DATA;
  79. if ( End >= valid->glyph_count )
  80. FT_INVALID_GLYPH_ID;
  81. if ( n > 0 && Start <= last )
  82. FT_INVALID_DATA;
  83. total += End - Start + 1;
  84. last = End;
  85. }
  86. }
  87. break;
  88. default:
  89. FT_INVALID_FORMAT;
  90. }
  91. /* Generally, a coverage table offset has an associated count field. */
  92. /* The number of glyphs in the table should match this field. If */
  93. /* there is no associated count, a value of -1 tells us not to check. */
  94. if ( expected_count != -1 && (FT_UInt)expected_count != total )
  95. FT_INVALID_DATA;
  96. OTV_EXIT;
  97. }
  98. FT_LOCAL_DEF( FT_UInt )
  99. otv_Coverage_get_first( FT_Bytes table )
  100. {
  101. FT_Bytes p = table;
  102. p += 4; /* skip CoverageFormat and Glyph/RangeCount */
  103. return FT_NEXT_USHORT( p );
  104. }
  105. FT_LOCAL_DEF( FT_UInt )
  106. otv_Coverage_get_last( FT_Bytes table )
  107. {
  108. FT_Bytes p = table;
  109. FT_UInt CoverageFormat = FT_NEXT_USHORT( p );
  110. FT_UInt count = FT_NEXT_USHORT( p ); /* Glyph/RangeCount */
  111. FT_UInt result = 0;
  112. switch ( CoverageFormat )
  113. {
  114. case 1:
  115. p += ( count - 1 ) * 2;
  116. result = FT_NEXT_USHORT( p );
  117. break;
  118. case 2:
  119. p += ( count - 1 ) * 6 + 2;
  120. result = FT_NEXT_USHORT( p );
  121. break;
  122. default:
  123. ;
  124. }
  125. return result;
  126. }
  127. FT_LOCAL_DEF( FT_UInt )
  128. otv_Coverage_get_count( FT_Bytes table )
  129. {
  130. FT_Bytes p = table;
  131. FT_UInt CoverageFormat = FT_NEXT_USHORT( p );
  132. FT_UInt count = FT_NEXT_USHORT( p ); /* Glyph/RangeCount */
  133. FT_UInt result = 0;
  134. switch ( CoverageFormat )
  135. {
  136. case 1:
  137. return count;
  138. case 2:
  139. {
  140. FT_UInt Start, End;
  141. for ( ; count > 0; count-- )
  142. {
  143. Start = FT_NEXT_USHORT( p );
  144. End = FT_NEXT_USHORT( p );
  145. p += 2; /* skip StartCoverageIndex */
  146. result += End - Start + 1;
  147. }
  148. }
  149. break;
  150. default:
  151. ;
  152. }
  153. return result;
  154. }
  155. /*************************************************************************/
  156. /*************************************************************************/
  157. /***** *****/
  158. /***** CLASS DEFINITION TABLE *****/
  159. /***** *****/
  160. /*************************************************************************/
  161. /*************************************************************************/
  162. FT_LOCAL_DEF( void )
  163. otv_ClassDef_validate( FT_Bytes table,
  164. OTV_Validator valid )
  165. {
  166. FT_Bytes p = table;
  167. FT_UInt ClassFormat;
  168. OTV_NAME_ENTER( "ClassDef" );
  169. OTV_LIMIT_CHECK( 4 );
  170. ClassFormat = FT_NEXT_USHORT( p );
  171. OTV_TRACE(( " (format %d)\n", ClassFormat ));
  172. switch ( ClassFormat )
  173. {
  174. case 1: /* ClassDefFormat1 */
  175. {
  176. FT_UInt StartGlyph;
  177. FT_UInt GlyphCount;
  178. OTV_LIMIT_CHECK( 4 );
  179. StartGlyph = FT_NEXT_USHORT( p );
  180. GlyphCount = FT_NEXT_USHORT( p );
  181. OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
  182. OTV_LIMIT_CHECK( GlyphCount * 2 ); /* ClassValueArray */
  183. if ( StartGlyph + GlyphCount - 1 >= valid->glyph_count )
  184. FT_INVALID_GLYPH_ID;
  185. }
  186. break;
  187. case 2: /* ClassDefFormat2 */
  188. {
  189. FT_UInt n, ClassRangeCount;
  190. FT_UInt Start, End, last = 0;
  191. ClassRangeCount = FT_NEXT_USHORT( p );
  192. OTV_TRACE(( " (ClassRangeCount = %d)\n", ClassRangeCount ));
  193. OTV_LIMIT_CHECK( ClassRangeCount * 6 );
  194. /* ClassRangeRecord */
  195. for ( n = 0; n < ClassRangeCount; n++ )
  196. {
  197. Start = FT_NEXT_USHORT( p );
  198. End = FT_NEXT_USHORT( p );
  199. p += 2; /* skip Class */
  200. if ( Start > End || ( n > 0 && Start <= last ) )
  201. FT_INVALID_DATA;
  202. if ( End >= valid->glyph_count )
  203. FT_INVALID_GLYPH_ID;
  204. last = End;
  205. }
  206. }
  207. break;
  208. default:
  209. FT_INVALID_FORMAT;
  210. }
  211. /* no need to check glyph indices used as input to class definition */
  212. /* tables since even invalid glyph indices return a meaningful result */
  213. OTV_EXIT;
  214. }
  215. /*************************************************************************/
  216. /*************************************************************************/
  217. /***** *****/
  218. /***** DEVICE TABLE *****/
  219. /***** *****/
  220. /*************************************************************************/
  221. /*************************************************************************/
  222. FT_LOCAL_DEF( void )
  223. otv_Device_validate( FT_Bytes table,
  224. OTV_Validator valid )
  225. {
  226. FT_Bytes p = table;
  227. FT_UInt StartSize, EndSize, DeltaFormat, count;
  228. OTV_NAME_ENTER( "Device" );
  229. OTV_LIMIT_CHECK( 8 );
  230. StartSize = FT_NEXT_USHORT( p );
  231. EndSize = FT_NEXT_USHORT( p );
  232. DeltaFormat = FT_NEXT_USHORT( p );
  233. if ( DeltaFormat < 1 || DeltaFormat > 3 )
  234. FT_INVALID_FORMAT;
  235. if ( EndSize < StartSize )
  236. FT_INVALID_DATA;
  237. count = EndSize - StartSize + 1;
  238. OTV_LIMIT_CHECK( ( 1 << DeltaFormat ) * count / 8 ); /* DeltaValue */
  239. OTV_EXIT;
  240. }
  241. /*************************************************************************/
  242. /*************************************************************************/
  243. /***** *****/
  244. /***** LOOKUPS *****/
  245. /***** *****/
  246. /*************************************************************************/
  247. /*************************************************************************/
  248. /* uses valid->type_count */
  249. /* uses valid->type_funcs */
  250. FT_LOCAL_DEF( void )
  251. otv_Lookup_validate( FT_Bytes table,
  252. OTV_Validator valid )
  253. {
  254. FT_Bytes p = table;
  255. FT_UInt LookupType, SubTableCount;
  256. OTV_Validate_Func validate;
  257. OTV_NAME_ENTER( "Lookup" );
  258. OTV_LIMIT_CHECK( 6 );
  259. LookupType = FT_NEXT_USHORT( p );
  260. p += 2; /* skip LookupFlag */
  261. SubTableCount = FT_NEXT_USHORT( p );
  262. OTV_TRACE(( " (type %d)\n", LookupType ));
  263. if ( LookupType == 0 || LookupType > valid->type_count )
  264. FT_INVALID_DATA;
  265. validate = valid->type_funcs[LookupType - 1];
  266. OTV_TRACE(( " (SubTableCount = %d)\n", SubTableCount ));
  267. OTV_LIMIT_CHECK( SubTableCount * 2 );
  268. /* SubTable */
  269. for ( ; SubTableCount > 0; SubTableCount-- )
  270. validate( table + FT_NEXT_USHORT( p ), valid );
  271. OTV_EXIT;
  272. }
  273. /* uses valid->lookup_count */
  274. FT_LOCAL_DEF( void )
  275. otv_LookupList_validate( FT_Bytes table,
  276. OTV_Validator valid )
  277. {
  278. FT_Bytes p = table;
  279. FT_UInt LookupCount;
  280. OTV_NAME_ENTER( "LookupList" );
  281. OTV_LIMIT_CHECK( 2 );
  282. LookupCount = FT_NEXT_USHORT( p );
  283. OTV_TRACE(( " (LookupCount = %d)\n", LookupCount ));
  284. OTV_LIMIT_CHECK( LookupCount * 2 );
  285. valid->lookup_count = LookupCount;
  286. /* Lookup */
  287. for ( ; LookupCount > 0; LookupCount-- )
  288. otv_Lookup_validate( table + FT_NEXT_USHORT( p ), valid );
  289. OTV_EXIT;
  290. }
  291. static FT_UInt
  292. otv_LookupList_get_count( FT_Bytes table )
  293. {
  294. return FT_NEXT_USHORT( table );
  295. }
  296. /*************************************************************************/
  297. /*************************************************************************/
  298. /***** *****/
  299. /***** FEATURES *****/
  300. /***** *****/
  301. /*************************************************************************/
  302. /*************************************************************************/
  303. /* uses valid->lookup_count */
  304. FT_LOCAL_DEF( void )
  305. otv_Feature_validate( FT_Bytes table,
  306. OTV_Validator valid )
  307. {
  308. FT_Bytes p = table;
  309. FT_UInt LookupCount;
  310. OTV_NAME_ENTER( "Feature" );
  311. OTV_LIMIT_CHECK( 4 );
  312. p += 2; /* skip FeatureParams (unused) */
  313. LookupCount = FT_NEXT_USHORT( p );
  314. OTV_TRACE(( " (LookupCount = %d)\n", LookupCount ));
  315. OTV_LIMIT_CHECK( LookupCount * 2 );
  316. /* LookupListIndex */
  317. for ( ; LookupCount > 0; LookupCount-- )
  318. if ( FT_NEXT_USHORT( p ) >= valid->lookup_count )
  319. FT_INVALID_DATA;
  320. OTV_EXIT;
  321. }
  322. static FT_UInt
  323. otv_Feature_get_count( FT_Bytes table )
  324. {
  325. return FT_NEXT_USHORT( table );
  326. }
  327. /* sets valid->lookup_count */
  328. FT_LOCAL_DEF( void )
  329. otv_FeatureList_validate( FT_Bytes table,
  330. FT_Bytes lookups,
  331. OTV_Validator valid )
  332. {
  333. FT_Bytes p = table;
  334. FT_UInt FeatureCount;
  335. OTV_NAME_ENTER( "FeatureList" );
  336. OTV_LIMIT_CHECK( 2 );
  337. FeatureCount = FT_NEXT_USHORT( p );
  338. OTV_TRACE(( " (FeatureCount = %d)\n", FeatureCount ));
  339. OTV_LIMIT_CHECK( FeatureCount * 2 );
  340. valid->lookup_count = otv_LookupList_get_count( lookups );
  341. /* FeatureRecord */
  342. for ( ; FeatureCount > 0; FeatureCount-- )
  343. {
  344. p += 4; /* skip FeatureTag */
  345. /* Feature */
  346. otv_Feature_validate( table + FT_NEXT_USHORT( p ), valid );
  347. }
  348. OTV_EXIT;
  349. }
  350. /*************************************************************************/
  351. /*************************************************************************/
  352. /***** *****/
  353. /***** LANGUAGE SYSTEM *****/
  354. /***** *****/
  355. /*************************************************************************/
  356. /*************************************************************************/
  357. /* uses valid->extra1 (number of features) */
  358. FT_LOCAL_DEF( void )
  359. otv_LangSys_validate( FT_Bytes table,
  360. OTV_Validator valid )
  361. {
  362. FT_Bytes p = table;
  363. FT_UInt ReqFeatureIndex;
  364. FT_UInt FeatureCount;
  365. OTV_NAME_ENTER( "LangSys" );
  366. OTV_LIMIT_CHECK( 6 );
  367. p += 2; /* skip LookupOrder (unused) */
  368. ReqFeatureIndex = FT_NEXT_USHORT( p );
  369. FeatureCount = FT_NEXT_USHORT( p );
  370. OTV_TRACE(( " (ReqFeatureIndex = %d)\n", ReqFeatureIndex ));
  371. OTV_TRACE(( " (FeatureCount = %d)\n", FeatureCount ));
  372. if ( ReqFeatureIndex != 0xFFFFU && ReqFeatureIndex >= valid->extra1 )
  373. FT_INVALID_DATA;
  374. OTV_LIMIT_CHECK( FeatureCount * 2 );
  375. /* FeatureIndex */
  376. for ( ; FeatureCount > 0; FeatureCount-- )
  377. if ( FT_NEXT_USHORT( p ) >= valid->extra1 )
  378. FT_INVALID_DATA;
  379. OTV_EXIT;
  380. }
  381. /*************************************************************************/
  382. /*************************************************************************/
  383. /***** *****/
  384. /***** SCRIPTS *****/
  385. /***** *****/
  386. /*************************************************************************/
  387. /*************************************************************************/
  388. FT_LOCAL_DEF( void )
  389. otv_Script_validate( FT_Bytes table,
  390. OTV_Validator valid )
  391. {
  392. FT_UInt DefaultLangSys, LangSysCount;
  393. FT_Bytes p = table;
  394. OTV_NAME_ENTER( "Script" );
  395. OTV_LIMIT_CHECK( 4 );
  396. DefaultLangSys = FT_NEXT_USHORT( p );
  397. LangSysCount = FT_NEXT_USHORT( p );
  398. OTV_TRACE(( " (LangSysCount = %d)\n", LangSysCount ));
  399. if ( DefaultLangSys != 0 )
  400. otv_LangSys_validate( table + DefaultLangSys, valid );
  401. OTV_LIMIT_CHECK( LangSysCount * 6 );
  402. /* LangSysRecord */
  403. for ( ; LangSysCount > 0; LangSysCount-- )
  404. {
  405. p += 4; /* skip LangSysTag */
  406. /* LangSys */
  407. otv_LangSys_validate( table + FT_NEXT_USHORT( p ), valid );
  408. }
  409. OTV_EXIT;
  410. }
  411. /* sets valid->extra1 (number of features) */
  412. FT_LOCAL_DEF( void )
  413. otv_ScriptList_validate( FT_Bytes table,
  414. FT_Bytes features,
  415. OTV_Validator valid )
  416. {
  417. FT_UInt ScriptCount;
  418. FT_Bytes p = table;
  419. OTV_NAME_ENTER( "ScriptList" );
  420. OTV_LIMIT_CHECK( 2 );
  421. ScriptCount = FT_NEXT_USHORT( p );
  422. OTV_TRACE(( " (ScriptCount = %d)\n", ScriptCount ));
  423. OTV_LIMIT_CHECK( ScriptCount * 6 );
  424. valid->extra1 = otv_Feature_get_count( features );
  425. /* ScriptRecord */
  426. for ( ; ScriptCount > 0; ScriptCount-- )
  427. {
  428. p += 4; /* skip ScriptTag */
  429. otv_Script_validate( table + FT_NEXT_USHORT( p ), valid ); /* Script */
  430. }
  431. OTV_EXIT;
  432. }
  433. /*************************************************************************/
  434. /*************************************************************************/
  435. /***** *****/
  436. /***** UTILITY FUNCTIONS *****/
  437. /***** *****/
  438. /*************************************************************************/
  439. /*************************************************************************/
  440. /*
  441. u: uint16
  442. ux: unit16 [x]
  443. s: struct
  444. sx: struct [x]
  445. sxy: struct [x], using external y count
  446. x: uint16 x
  447. C: Coverage
  448. O: Offset
  449. On: Offset (NULL)
  450. Ox: Offset [x]
  451. Onx: Offset (NULL) [x]
  452. */
  453. FT_LOCAL_DEF( void )
  454. otv_x_Ox( FT_Bytes table,
  455. OTV_Validator valid )
  456. {
  457. FT_Bytes p = table;
  458. FT_UInt Count;
  459. OTV_Validate_Func func;
  460. OTV_ENTER;
  461. OTV_LIMIT_CHECK( 2 );
  462. Count = FT_NEXT_USHORT( p );
  463. OTV_TRACE(( " (Count = %d)\n", Count ));
  464. OTV_LIMIT_CHECK( Count * 2 );
  465. valid->nesting_level++;
  466. func = valid->func[valid->nesting_level];
  467. for ( ; Count > 0; Count-- )
  468. func( table + FT_NEXT_USHORT( p ), valid );
  469. valid->nesting_level--;
  470. OTV_EXIT;
  471. }
  472. FT_LOCAL_DEF( void )
  473. otv_u_C_x_Ox( FT_Bytes table,
  474. OTV_Validator valid )
  475. {
  476. FT_Bytes p = table;
  477. FT_UInt Count, Coverage;
  478. OTV_Validate_Func func;
  479. OTV_ENTER;
  480. p += 2; /* skip Format */
  481. OTV_LIMIT_CHECK( 4 );
  482. Coverage = FT_NEXT_USHORT( p );
  483. Count = FT_NEXT_USHORT( p );
  484. OTV_TRACE(( " (Count = %d)\n", Count ));
  485. otv_Coverage_validate( table + Coverage, valid, Count );
  486. OTV_LIMIT_CHECK( Count * 2 );
  487. valid->nesting_level++;
  488. func = valid->func[valid->nesting_level];
  489. for ( ; Count > 0; Count-- )
  490. func( table + FT_NEXT_USHORT( p ), valid );
  491. valid->nesting_level--;
  492. OTV_EXIT;
  493. }
  494. /* uses valid->extra1 (if > 0: array value limit) */
  495. FT_LOCAL_DEF( void )
  496. otv_x_ux( FT_Bytes table,
  497. OTV_Validator valid )
  498. {
  499. FT_Bytes p = table;
  500. FT_UInt Count;
  501. OTV_ENTER;
  502. OTV_LIMIT_CHECK( 2 );
  503. Count = FT_NEXT_USHORT( p );
  504. OTV_TRACE(( " (Count = %d)\n", Count ));
  505. OTV_LIMIT_CHECK( Count * 2 );
  506. if ( valid->extra1 )
  507. {
  508. for ( ; Count > 0; Count-- )
  509. if ( FT_NEXT_USHORT( p ) >= valid->extra1 )
  510. FT_INVALID_DATA;
  511. }
  512. OTV_EXIT;
  513. }
  514. /* `ux' in the function's name is not really correct since only x-1 */
  515. /* elements are tested */
  516. /* uses valid->extra1 (array value limit) */
  517. FT_LOCAL_DEF( void )
  518. otv_x_y_ux_sy( FT_Bytes table,
  519. OTV_Validator valid )
  520. {
  521. FT_Bytes p = table;
  522. FT_UInt Count1, Count2;
  523. OTV_ENTER;
  524. OTV_LIMIT_CHECK( 4 );
  525. Count1 = FT_NEXT_USHORT( p );
  526. Count2 = FT_NEXT_USHORT( p );
  527. OTV_TRACE(( " (Count1 = %d)\n", Count1 ));
  528. OTV_TRACE(( " (Count2 = %d)\n", Count2 ));
  529. if ( Count1 == 0 )
  530. FT_INVALID_DATA;
  531. OTV_LIMIT_CHECK( ( Count1 - 1 ) * 2 + Count2 * 4 );
  532. p += ( Count1 - 1 ) * 2;
  533. for ( ; Count2 > 0; Count2-- )
  534. {
  535. if ( FT_NEXT_USHORT( p ) >= Count1 )
  536. FT_INVALID_DATA;
  537. if ( FT_NEXT_USHORT( p ) >= valid->extra1 )
  538. FT_INVALID_DATA;
  539. }
  540. OTV_EXIT;
  541. }
  542. /* `uy' in the function's name is not really correct since only y-1 */
  543. /* elements are tested */
  544. /* uses valid->extra1 (array value limit) */
  545. FT_LOCAL_DEF( void )
  546. otv_x_ux_y_uy_z_uz_p_sp( FT_Bytes table,
  547. OTV_Validator valid )
  548. {
  549. FT_Bytes p = table;
  550. FT_UInt BacktrackCount, InputCount, LookaheadCount;
  551. FT_UInt Count;
  552. OTV_ENTER;
  553. OTV_LIMIT_CHECK( 2 );
  554. BacktrackCount = FT_NEXT_USHORT( p );
  555. OTV_TRACE(( " (BacktrackCount = %d)\n", BacktrackCount ));
  556. OTV_LIMIT_CHECK( BacktrackCount * 2 + 2 );
  557. p += BacktrackCount * 2;
  558. InputCount = FT_NEXT_USHORT( p );
  559. if ( InputCount == 0 )
  560. FT_INVALID_DATA;
  561. OTV_TRACE(( " (InputCount = %d)\n", InputCount ));
  562. OTV_LIMIT_CHECK( InputCount * 2 );
  563. p += ( InputCount - 1 ) * 2;
  564. LookaheadCount = FT_NEXT_USHORT( p );
  565. OTV_TRACE(( " (LookaheadCount = %d)\n", LookaheadCount ));
  566. OTV_LIMIT_CHECK( LookaheadCount * 2 + 2 );
  567. p += LookaheadCount * 2;
  568. Count = FT_NEXT_USHORT( p );
  569. OTV_TRACE(( " (Count = %d)\n", Count ));
  570. OTV_LIMIT_CHECK( Count * 4 );
  571. for ( ; Count > 0; Count-- )
  572. {
  573. if ( FT_NEXT_USHORT( p ) >= InputCount )
  574. FT_INVALID_DATA;
  575. if ( FT_NEXT_USHORT( p ) >= valid->extra1 )
  576. FT_INVALID_DATA;
  577. }
  578. OTV_EXIT;
  579. }
  580. /* sets valid->extra1 (valid->lookup_count) */
  581. FT_LOCAL_DEF( void )
  582. otv_u_O_O_x_Onx( FT_Bytes table,
  583. OTV_Validator valid )
  584. {
  585. FT_Bytes p = table;
  586. FT_UInt Coverage, ClassDef, ClassSetCount;
  587. OTV_Validate_Func func;
  588. OTV_ENTER;
  589. p += 2; /* skip Format */
  590. OTV_LIMIT_CHECK( 6 );
  591. Coverage = FT_NEXT_USHORT( p );
  592. ClassDef = FT_NEXT_USHORT( p );
  593. ClassSetCount = FT_NEXT_USHORT( p );
  594. OTV_TRACE(( " (ClassSetCount = %d)\n", ClassSetCount ));
  595. otv_Coverage_validate( table + Coverage, valid, -1 );
  596. otv_ClassDef_validate( table + ClassDef, valid );
  597. OTV_LIMIT_CHECK( ClassSetCount * 2 );
  598. valid->nesting_level++;
  599. func = valid->func[valid->nesting_level];
  600. valid->extra1 = valid->lookup_count;
  601. for ( ; ClassSetCount > 0; ClassSetCount-- )
  602. {
  603. FT_UInt offset = FT_NEXT_USHORT( p );
  604. if ( offset )
  605. func( table + offset, valid );
  606. }
  607. valid->nesting_level--;
  608. OTV_EXIT;
  609. }
  610. /* uses valid->lookup_count */
  611. FT_LOCAL_DEF( void )
  612. otv_u_x_y_Ox_sy( FT_Bytes table,
  613. OTV_Validator valid )
  614. {
  615. FT_Bytes p = table;
  616. FT_UInt GlyphCount, Count, count1;
  617. OTV_ENTER;
  618. p += 2; /* skip Format */
  619. OTV_LIMIT_CHECK( 4 );
  620. GlyphCount = FT_NEXT_USHORT( p );
  621. Count = FT_NEXT_USHORT( p );
  622. OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
  623. OTV_TRACE(( " (Count = %d)\n", Count ));
  624. OTV_LIMIT_CHECK( GlyphCount * 2 + Count * 4 );
  625. for ( count1 = GlyphCount; count1 > 0; count1-- )
  626. otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
  627. for ( ; Count > 0; Count-- )
  628. {
  629. if ( FT_NEXT_USHORT( p ) >= GlyphCount )
  630. FT_INVALID_DATA;
  631. if ( FT_NEXT_USHORT( p ) >= valid->lookup_count )
  632. FT_INVALID_DATA;
  633. }
  634. OTV_EXIT;
  635. }
  636. /* sets valid->extra1 (valid->lookup_count) */
  637. FT_LOCAL_DEF( void )
  638. otv_u_O_O_O_O_x_Onx( FT_Bytes table,
  639. OTV_Validator valid )
  640. {
  641. FT_Bytes p = table;
  642. FT_UInt Coverage;
  643. FT_UInt BacktrackClassDef, InputClassDef, LookaheadClassDef;
  644. FT_UInt ChainClassSetCount;
  645. OTV_Validate_Func func;
  646. OTV_ENTER;
  647. p += 2; /* skip Format */
  648. OTV_LIMIT_CHECK( 10 );
  649. Coverage = FT_NEXT_USHORT( p );
  650. BacktrackClassDef = FT_NEXT_USHORT( p );
  651. InputClassDef = FT_NEXT_USHORT( p );
  652. LookaheadClassDef = FT_NEXT_USHORT( p );
  653. ChainClassSetCount = FT_NEXT_USHORT( p );
  654. OTV_TRACE(( " (ChainClassSetCount = %d)\n", ChainClassSetCount ));
  655. otv_Coverage_validate( table + Coverage, valid, -1 );
  656. otv_ClassDef_validate( table + BacktrackClassDef, valid );
  657. otv_ClassDef_validate( table + InputClassDef, valid );
  658. otv_ClassDef_validate( table + LookaheadClassDef, valid );
  659. OTV_LIMIT_CHECK( ChainClassSetCount * 2 );
  660. valid->nesting_level++;
  661. func = valid->func[valid->nesting_level];
  662. valid->extra1 = valid->lookup_count;
  663. for ( ; ChainClassSetCount > 0; ChainClassSetCount-- )
  664. {
  665. FT_UInt offset = FT_NEXT_USHORT( p );
  666. if ( offset )
  667. func( table + offset, valid );
  668. }
  669. valid->nesting_level--;
  670. OTV_EXIT;
  671. }
  672. /* uses valid->lookup_count */
  673. FT_LOCAL_DEF( void )
  674. otv_u_x_Ox_y_Oy_z_Oz_p_sp( FT_Bytes table,
  675. OTV_Validator valid )
  676. {
  677. FT_Bytes p = table;
  678. FT_UInt BacktrackGlyphCount, InputGlyphCount, LookaheadGlyphCount;
  679. FT_UInt count1, count2;
  680. OTV_ENTER;
  681. p += 2; /* skip Format */
  682. OTV_LIMIT_CHECK( 2 );
  683. BacktrackGlyphCount = FT_NEXT_USHORT( p );
  684. OTV_TRACE(( " (BacktrackGlyphCount = %d)\n", BacktrackGlyphCount ));
  685. OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 );
  686. for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- )
  687. otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
  688. InputGlyphCount = FT_NEXT_USHORT( p );
  689. OTV_TRACE(( " (InputGlyphCount = %d)\n", InputGlyphCount ));
  690. OTV_LIMIT_CHECK( InputGlyphCount * 2 + 2 );
  691. for ( count1 = InputGlyphCount; count1 > 0; count1-- )
  692. otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
  693. LookaheadGlyphCount = FT_NEXT_USHORT( p );
  694. OTV_TRACE(( " (LookaheadGlyphCount = %d)\n", LookaheadGlyphCount ));
  695. OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 );
  696. for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- )
  697. otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
  698. count2 = FT_NEXT_USHORT( p );
  699. OTV_TRACE(( " (Count = %d)\n", count2 ));
  700. OTV_LIMIT_CHECK( count2 * 4 );
  701. for ( ; count2 > 0; count2-- )
  702. {
  703. if ( FT_NEXT_USHORT( p ) >= InputGlyphCount )
  704. FT_INVALID_DATA;
  705. if ( FT_NEXT_USHORT( p ) >= valid->lookup_count )
  706. FT_INVALID_DATA;
  707. }
  708. OTV_EXIT;
  709. }
  710. FT_LOCAL_DEF( FT_UInt )
  711. otv_GSUBGPOS_get_Lookup_count( FT_Bytes table )
  712. {
  713. FT_Bytes p = table + 8;
  714. return otv_LookupList_get_count( table + FT_NEXT_USHORT( p ) );
  715. }
  716. FT_LOCAL_DEF( FT_UInt )
  717. otv_GSUBGPOS_have_MarkAttachmentType_flag( FT_Bytes table )
  718. {
  719. FT_Bytes p, lookup;
  720. FT_UInt count;
  721. if ( !table )
  722. return 0;
  723. /* LookupList */
  724. p = table + 8;
  725. table += FT_NEXT_USHORT( p );
  726. /* LookupCount */
  727. p = table;
  728. count = FT_NEXT_USHORT( p );
  729. for ( ; count > 0; count-- )
  730. {
  731. FT_Bytes oldp;
  732. /* Lookup */
  733. lookup = table + FT_NEXT_USHORT( p );
  734. oldp = p;
  735. /* LookupFlag */
  736. p = lookup + 2;
  737. if ( FT_NEXT_USHORT( p ) & 0xFF00U )
  738. return 1;
  739. p = oldp;
  740. }
  741. return 0;
  742. }
  743. /* END */