PageRenderTime 54ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/gfx/ots/src/layout.cc

https://bitbucket.org/MeeGoAdmin/mozilla-central/
C++ | 1477 lines | 1251 code | 163 blank | 63 comment | 350 complexity | ac95b6fe2787ef2b2bd0379391d5f635 MD5 | raw file
Possible License(s): AGPL-1.0, MIT, BSD-3-Clause, Apache-2.0, LGPL-2.1, 0BSD, LGPL-3.0, MPL-2.0-no-copyleft-exception, GPL-2.0, JSON
  1. // Copyright (c) 2011 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "layout.h"
  5. #include <limits>
  6. #include <vector>
  7. #include "gdef.h"
  8. // OpenType Layout Common Table Formats
  9. // http://www.microsoft.com/typography/otspec/chapter2.htm
  10. namespace {
  11. // The 'DFLT' tag of script table.
  12. const uint32_t kScriptTableTagDflt = 0x44464c54;
  13. // The value which represents there is no required feature index.
  14. const uint16_t kNoRequiredFeatureIndexDefined = 0xFFFF;
  15. // The lookup flag bit which indicates existence of MarkFilteringSet.
  16. const uint16_t kUseMarkFilteringSetBit = 0x0010;
  17. // The lookup flags which require GDEF table.
  18. const uint16_t kGdefRequiredFlags = 0x0002 | 0x0004 | 0x0008;
  19. // The mask for MarkAttachmentType.
  20. const uint16_t kMarkAttachmentTypeMask = 0xFF00;
  21. // The maximum type number of format for device tables.
  22. const uint16_t kMaxDeltaFormatType = 3;
  23. // The maximum number of class value.
  24. const uint16_t kMaxClassDefValue = 0xFFFF;
  25. struct ScriptRecord {
  26. uint32_t tag;
  27. uint16_t offset;
  28. };
  29. struct LangSysRecord {
  30. uint32_t tag;
  31. uint16_t offset;
  32. };
  33. struct FeatureRecord {
  34. uint32_t tag;
  35. uint16_t offset;
  36. };
  37. bool ParseLangSysTable(ots::Buffer *subtable, const uint32_t tag,
  38. const uint16_t num_features) {
  39. uint16_t offset_lookup_order = 0;
  40. uint16_t req_feature_index = 0;
  41. uint16_t feature_count = 0;
  42. if (!subtable->ReadU16(&offset_lookup_order) ||
  43. !subtable->ReadU16(&req_feature_index) ||
  44. !subtable->ReadU16(&feature_count)) {
  45. return OTS_FAILURE();
  46. }
  47. // |offset_lookup_order| is reserved and should be NULL.
  48. if (offset_lookup_order != 0) {
  49. return OTS_FAILURE();
  50. }
  51. if (req_feature_index != kNoRequiredFeatureIndexDefined &&
  52. req_feature_index >= num_features) {
  53. return OTS_FAILURE();
  54. }
  55. if (feature_count > num_features) {
  56. return OTS_FAILURE();
  57. }
  58. for (unsigned i = 0; i < feature_count; ++i) {
  59. uint16_t feature_index = 0;
  60. if (!subtable->ReadU16(&feature_index)) {
  61. return OTS_FAILURE();
  62. }
  63. if (feature_index >= num_features) {
  64. return OTS_FAILURE();
  65. }
  66. }
  67. return true;
  68. }
  69. bool ParseScriptTable(const uint8_t *data, const size_t length,
  70. const uint32_t tag, const uint16_t num_features) {
  71. ots::Buffer subtable(data, length);
  72. uint16_t offset_default_lang_sys = 0;
  73. uint16_t lang_sys_count = 0;
  74. if (!subtable.ReadU16(&offset_default_lang_sys) ||
  75. !subtable.ReadU16(&lang_sys_count)) {
  76. return OTS_FAILURE();
  77. }
  78. // The spec requires a script table for 'DFLT' tag must contain non-NULL
  79. // |offset_default_lang_sys| and |lang_sys_count| == 0
  80. if (tag == kScriptTableTagDflt &&
  81. (offset_default_lang_sys == 0 || lang_sys_count != 0)) {
  82. OTS_WARNING("DFLT table doesn't satisfy the spec.");
  83. return OTS_FAILURE();
  84. }
  85. const unsigned lang_sys_record_end = static_cast<unsigned>(4) +
  86. lang_sys_count * 6;
  87. if (lang_sys_record_end > std::numeric_limits<uint16_t>::max()) {
  88. return OTS_FAILURE();
  89. }
  90. std::vector<LangSysRecord> lang_sys_records;
  91. lang_sys_records.resize(lang_sys_count);
  92. uint32_t last_tag = 0;
  93. for (unsigned i = 0; i < lang_sys_count; ++i) {
  94. if (!subtable.ReadU32(&lang_sys_records[i].tag) ||
  95. !subtable.ReadU16(&lang_sys_records[i].offset)) {
  96. return OTS_FAILURE();
  97. }
  98. // The record array must store the records alphabetically by tag
  99. if (last_tag != 0 && last_tag > lang_sys_records[i].tag) {
  100. return OTS_FAILURE();
  101. }
  102. if (lang_sys_records[i].offset < lang_sys_record_end ||
  103. lang_sys_records[i].offset >= length) {
  104. OTS_WARNING("bad offset to lang sys table: %x",
  105. lang_sys_records[i].offset);
  106. return OTS_FAILURE();
  107. }
  108. last_tag = lang_sys_records[i].tag;
  109. }
  110. // Check lang sys tables
  111. for (unsigned i = 0; i < lang_sys_count; ++i) {
  112. subtable.set_offset(lang_sys_records[i].offset);
  113. if (!ParseLangSysTable(&subtable, lang_sys_records[i].tag, num_features)) {
  114. return OTS_FAILURE();
  115. }
  116. }
  117. return true;
  118. }
  119. bool ParseFeatureTable(const uint8_t *data, const size_t length,
  120. const uint16_t num_lookups) {
  121. ots::Buffer subtable(data, length);
  122. uint16_t offset_feature_params = 0;
  123. uint16_t lookup_count = 0;
  124. if (!subtable.ReadU16(&offset_feature_params) ||
  125. !subtable.ReadU16(&lookup_count)) {
  126. return OTS_FAILURE();
  127. }
  128. const unsigned feature_table_end = static_cast<unsigned>(4) +
  129. num_lookups * 2;
  130. if (feature_table_end > std::numeric_limits<uint16_t>::max()) {
  131. return OTS_FAILURE();
  132. }
  133. // |offset_feature_params| is generally set to NULL.
  134. if (offset_feature_params != 0 &&
  135. (offset_feature_params < feature_table_end ||
  136. offset_feature_params >= length)) {
  137. return OTS_FAILURE();
  138. }
  139. for (unsigned i = 0; i < lookup_count; ++i) {
  140. uint16_t lookup_index = 0;
  141. if (!subtable.ReadU16(&lookup_index)) {
  142. return OTS_FAILURE();
  143. }
  144. // lookup index starts with 0.
  145. if (lookup_index >= num_lookups) {
  146. return OTS_FAILURE();
  147. }
  148. }
  149. return true;
  150. }
  151. bool ParseLookupTable(ots::OpenTypeFile *file, const uint8_t *data,
  152. const size_t length,
  153. const ots::LookupSubtableParser* parser) {
  154. ots::Buffer subtable(data, length);
  155. uint16_t lookup_type = 0;
  156. uint16_t lookup_flag = 0;
  157. uint16_t subtable_count = 0;
  158. if (!subtable.ReadU16(&lookup_type) ||
  159. !subtable.ReadU16(&lookup_flag) ||
  160. !subtable.ReadU16(&subtable_count)) {
  161. return OTS_FAILURE();
  162. }
  163. if (lookup_type == 0 || lookup_type > parser->num_types) {
  164. return OTS_FAILURE();
  165. }
  166. // Check lookup flags.
  167. if ((lookup_flag & kGdefRequiredFlags) &&
  168. (!file->gdef || !file->gdef->has_glyph_class_def)) {
  169. return OTS_FAILURE();
  170. }
  171. if ((lookup_flag & kMarkAttachmentTypeMask) &&
  172. (!file->gdef || !file->gdef->has_mark_attachment_class_def)) {
  173. return OTS_FAILURE();
  174. }
  175. bool use_mark_filtering_set = false;
  176. if (lookup_flag & kUseMarkFilteringSetBit) {
  177. if (!file->gdef || !file->gdef->has_mark_glyph_sets_def) {
  178. return OTS_FAILURE();
  179. }
  180. use_mark_filtering_set = true;
  181. }
  182. std::vector<uint16_t> subtables;
  183. subtables.reserve(subtable_count);
  184. // If the |kUseMarkFilteringSetBit| of |lookup_flag| is set,
  185. // extra 2 bytes will follow after subtable offset array.
  186. const unsigned lookup_table_end =
  187. static_cast<unsigned>(use_mark_filtering_set ? 8 : 6) +
  188. subtable_count * 2;
  189. if (lookup_table_end > std::numeric_limits<uint16_t>::max()) {
  190. return OTS_FAILURE();
  191. }
  192. for (unsigned i = 0; i < subtable_count; ++i) {
  193. uint16_t offset_subtable = 0;
  194. if (!subtable.ReadU16(&offset_subtable)) {
  195. return OTS_FAILURE();
  196. }
  197. if (offset_subtable < lookup_table_end ||
  198. offset_subtable >= length) {
  199. return OTS_FAILURE();
  200. }
  201. subtables.push_back(offset_subtable);
  202. }
  203. if (subtables.size() != subtable_count) {
  204. return OTS_FAILURE();
  205. }
  206. if (use_mark_filtering_set) {
  207. uint16_t mark_filtering_set = 0;
  208. if (!subtable.ReadU16(&mark_filtering_set)) {
  209. return OTS_FAILURE();
  210. }
  211. if (file->gdef->num_mark_glyph_sets == 0 ||
  212. mark_filtering_set >= file->gdef->num_mark_glyph_sets) {
  213. return OTS_FAILURE();
  214. }
  215. }
  216. // Parse lookup subtables for this lookup type.
  217. for (unsigned i = 0; i < subtable_count; ++i) {
  218. if (!parser->Parse(file, data + subtables[i], length - subtables[i],
  219. lookup_type)) {
  220. return OTS_FAILURE();
  221. }
  222. }
  223. return true;
  224. }
  225. bool ParseClassDefFormat1(const uint8_t *data, size_t length,
  226. const uint16_t num_glyphs,
  227. const uint16_t num_classes) {
  228. ots::Buffer subtable(data, length);
  229. // Skip format field.
  230. if (!subtable.Skip(2)) {
  231. return OTS_FAILURE();
  232. }
  233. uint16_t start_glyph = 0;
  234. if (!subtable.ReadU16(&start_glyph)) {
  235. return OTS_FAILURE();
  236. }
  237. if (start_glyph > num_glyphs) {
  238. OTS_WARNING("bad start glyph ID: %u", start_glyph);
  239. return OTS_FAILURE();
  240. }
  241. uint16_t glyph_count = 0;
  242. if (!subtable.ReadU16(&glyph_count)) {
  243. return OTS_FAILURE();
  244. }
  245. if (glyph_count > num_glyphs) {
  246. OTS_WARNING("bad glyph count: %u", glyph_count);
  247. return OTS_FAILURE();
  248. }
  249. for (unsigned i = 0; i < glyph_count; ++i) {
  250. uint16_t class_value = 0;
  251. if (!subtable.ReadU16(&class_value)) {
  252. return OTS_FAILURE();
  253. }
  254. if (class_value > num_classes) {
  255. OTS_WARNING("bad class value: %u", class_value);
  256. return OTS_FAILURE();
  257. }
  258. }
  259. return true;
  260. }
  261. bool ParseClassDefFormat2(const uint8_t *data, size_t length,
  262. const uint16_t num_glyphs,
  263. const uint16_t num_classes) {
  264. ots::Buffer subtable(data, length);
  265. // Skip format field.
  266. if (!subtable.Skip(2)) {
  267. return OTS_FAILURE();
  268. }
  269. uint16_t range_count = 0;
  270. if (!subtable.ReadU16(&range_count)) {
  271. return OTS_FAILURE();
  272. }
  273. if (range_count > num_glyphs) {
  274. OTS_WARNING("bad range count: %u", range_count);
  275. return OTS_FAILURE();
  276. }
  277. uint16_t last_end = 0;
  278. for (unsigned i = 0; i < range_count; ++i) {
  279. uint16_t start = 0;
  280. uint16_t end = 0;
  281. uint16_t class_value = 0;
  282. if (!subtable.ReadU16(&start) ||
  283. !subtable.ReadU16(&end) ||
  284. !subtable.ReadU16(&class_value)) {
  285. return OTS_FAILURE();
  286. }
  287. if (start > end || (last_end && start <= last_end)) {
  288. OTS_WARNING("glyph range is overlapping.");
  289. return OTS_FAILURE();
  290. }
  291. if (class_value > num_classes) {
  292. OTS_WARNING("bad class value: %u", class_value);
  293. return OTS_FAILURE();
  294. }
  295. last_end = end;
  296. }
  297. return true;
  298. }
  299. bool ParseCoverageFormat1(const uint8_t *data, size_t length,
  300. const uint16_t num_glyphs) {
  301. ots::Buffer subtable(data, length);
  302. // Skip format field.
  303. if (!subtable.Skip(2)) {
  304. return OTS_FAILURE();
  305. }
  306. uint16_t glyph_count = 0;
  307. if (!subtable.ReadU16(&glyph_count)) {
  308. return OTS_FAILURE();
  309. }
  310. if (glyph_count > num_glyphs) {
  311. OTS_WARNING("bad glyph count: %u", glyph_count);
  312. return OTS_FAILURE();
  313. }
  314. for (unsigned i = 0; i < glyph_count; ++i) {
  315. uint16_t glyph = 0;
  316. if (!subtable.ReadU16(&glyph)) {
  317. return OTS_FAILURE();
  318. }
  319. if (glyph > num_glyphs) {
  320. OTS_WARNING("bad glyph ID: %u", glyph);
  321. return OTS_FAILURE();
  322. }
  323. }
  324. return true;
  325. }
  326. bool ParseCoverageFormat2(const uint8_t *data, size_t length,
  327. const uint16_t num_glyphs) {
  328. ots::Buffer subtable(data, length);
  329. // Skip format field.
  330. if (!subtable.Skip(2)) {
  331. return OTS_FAILURE();
  332. }
  333. uint16_t range_count = 0;
  334. if (!subtable.ReadU16(&range_count)) {
  335. return OTS_FAILURE();
  336. }
  337. if (range_count > num_glyphs) {
  338. OTS_WARNING("bad range count: %u", range_count);
  339. return OTS_FAILURE();
  340. }
  341. uint16_t last_end = 0;
  342. uint16_t last_start_coverage_index = 0;
  343. for (unsigned i = 0; i < range_count; ++i) {
  344. uint16_t start = 0;
  345. uint16_t end = 0;
  346. uint16_t start_coverage_index = 0;
  347. if (!subtable.ReadU16(&start) ||
  348. !subtable.ReadU16(&end) ||
  349. !subtable.ReadU16(&start_coverage_index)) {
  350. return OTS_FAILURE();
  351. }
  352. if (start > end || (last_end && start <= last_end)) {
  353. OTS_WARNING("glyph range is overlapping.");
  354. return OTS_FAILURE();
  355. }
  356. if (start_coverage_index != last_start_coverage_index) {
  357. OTS_WARNING("bad start coverage index.");
  358. return OTS_FAILURE();
  359. }
  360. last_end = end;
  361. last_start_coverage_index += end - start + 1;
  362. }
  363. return true;
  364. }
  365. // Parsers for Contextual subtables in GSUB/GPOS tables.
  366. bool ParseLookupRecord(ots::Buffer *subtable, const uint16_t num_glyphs,
  367. const uint16_t num_lookups) {
  368. uint16_t sequence_index = 0;
  369. uint16_t lookup_list_index = 0;
  370. if (!subtable->ReadU16(&sequence_index) ||
  371. !subtable->ReadU16(&lookup_list_index)) {
  372. return OTS_FAILURE();
  373. }
  374. if (sequence_index >= num_glyphs) {
  375. return OTS_FAILURE();
  376. }
  377. if (lookup_list_index >= num_lookups) {
  378. return OTS_FAILURE();
  379. }
  380. return true;
  381. }
  382. bool ParseRuleSubtable(const uint8_t *data, const size_t length,
  383. const uint16_t num_glyphs,
  384. const uint16_t num_lookups) {
  385. ots::Buffer subtable(data, length);
  386. uint16_t glyph_count = 0;
  387. uint16_t lookup_count = 0;
  388. if (!subtable.ReadU16(&glyph_count) ||
  389. !subtable.ReadU16(&lookup_count)) {
  390. return OTS_FAILURE();
  391. }
  392. if (glyph_count == 0 || glyph_count >= num_glyphs) {
  393. return OTS_FAILURE();
  394. }
  395. for (unsigned i = 0; i < glyph_count - static_cast<unsigned>(1); ++i) {
  396. uint16_t glyph_id = 0;
  397. if (!subtable.ReadU16(&glyph_id)) {
  398. return OTS_FAILURE();
  399. }
  400. if (glyph_id > num_glyphs) {
  401. return OTS_FAILURE();
  402. }
  403. }
  404. for (unsigned i = 0; i < lookup_count; ++i) {
  405. if (!ParseLookupRecord(&subtable, num_glyphs, num_lookups)) {
  406. return OTS_FAILURE();
  407. }
  408. }
  409. return true;
  410. }
  411. bool ParseRuleSetTable(const uint8_t *data, const size_t length,
  412. const uint16_t num_glyphs,
  413. const uint16_t num_lookups) {
  414. ots::Buffer subtable(data, length);
  415. uint16_t rule_count = 0;
  416. if (!subtable.ReadU16(&rule_count)) {
  417. return OTS_FAILURE();
  418. }
  419. const unsigned rule_end = static_cast<unsigned>(2) +
  420. rule_count * 2;
  421. if (rule_end > std::numeric_limits<uint16_t>::max()) {
  422. return OTS_FAILURE();
  423. }
  424. for (unsigned i = 0; i < rule_count; ++i) {
  425. uint16_t offset_rule = 0;
  426. if (!subtable.ReadU16(&offset_rule)) {
  427. return OTS_FAILURE();
  428. }
  429. if (offset_rule < rule_end || offset_rule >= length) {
  430. return OTS_FAILURE();
  431. }
  432. if (!ParseRuleSubtable(data + offset_rule, length - offset_rule,
  433. num_glyphs, num_lookups)) {
  434. return OTS_FAILURE();
  435. }
  436. }
  437. return true;
  438. }
  439. bool ParseContextFormat1(const uint8_t *data, const size_t length,
  440. const uint16_t num_glyphs,
  441. const uint16_t num_lookups) {
  442. ots::Buffer subtable(data, length);
  443. uint16_t offset_coverage = 0;
  444. uint16_t rule_set_count = 0;
  445. // Skip format field.
  446. if (!subtable.Skip(2) ||
  447. !subtable.ReadU16(&offset_coverage) ||
  448. !subtable.ReadU16(&rule_set_count)) {
  449. return OTS_FAILURE();
  450. }
  451. const unsigned rule_set_end = static_cast<unsigned>(6) +
  452. rule_set_count * 2;
  453. if (rule_set_end > std::numeric_limits<uint16_t>::max()) {
  454. return OTS_FAILURE();
  455. }
  456. if (offset_coverage < rule_set_end || offset_coverage >= length) {
  457. return OTS_FAILURE();
  458. }
  459. if (!ots::ParseCoverageTable(data + offset_coverage,
  460. length - offset_coverage, num_glyphs)) {
  461. return OTS_FAILURE();
  462. }
  463. for (unsigned i = 0; i < rule_set_count; ++i) {
  464. uint16_t offset_rule = 0;
  465. if (!subtable.ReadU16(&offset_rule)) {
  466. return OTS_FAILURE();
  467. }
  468. if (offset_rule < rule_set_end || offset_rule >= length) {
  469. return OTS_FAILURE();
  470. }
  471. if (!ParseRuleSetTable(data + offset_rule, length - offset_rule,
  472. num_glyphs, num_lookups)) {
  473. return OTS_FAILURE();
  474. }
  475. }
  476. return true;
  477. }
  478. bool ParseClassRuleTable(const uint8_t *data, const size_t length,
  479. const uint16_t num_glyphs,
  480. const uint16_t num_lookups) {
  481. ots::Buffer subtable(data, length);
  482. uint16_t glyph_count = 0;
  483. uint16_t lookup_count = 0;
  484. if (!subtable.ReadU16(&glyph_count) ||
  485. !subtable.ReadU16(&lookup_count)) {
  486. return OTS_FAILURE();
  487. }
  488. if (glyph_count == 0 || glyph_count >= num_glyphs) {
  489. return OTS_FAILURE();
  490. }
  491. // ClassRule table contains an array of classes. Each value of classes
  492. // could take arbitrary values including zero so we don't check these value.
  493. const unsigned num_classes = glyph_count - static_cast<unsigned>(1);
  494. if (!subtable.Skip(2 * num_classes)) {
  495. return OTS_FAILURE();
  496. }
  497. for (unsigned i = 0; i < lookup_count; ++i) {
  498. if (!ParseLookupRecord(&subtable, num_glyphs, num_lookups)) {
  499. return OTS_FAILURE();
  500. }
  501. }
  502. return true;
  503. }
  504. bool ParseClassSetTable(const uint8_t *data, const size_t length,
  505. const uint16_t num_glyphs,
  506. const uint16_t num_lookups) {
  507. ots::Buffer subtable(data, length);
  508. uint16_t class_rule_count = 0;
  509. if (!subtable.ReadU16(&class_rule_count)) {
  510. return OTS_FAILURE();
  511. }
  512. const unsigned class_rule_end = static_cast<unsigned>(2) +
  513. class_rule_count * 2;
  514. if (class_rule_end > std::numeric_limits<uint16_t>::max()) {
  515. return OTS_FAILURE();
  516. }
  517. for (unsigned i = 0; i < class_rule_count; ++i) {
  518. uint16_t offset_class_rule = 0;
  519. if (!subtable.ReadU16(&offset_class_rule)) {
  520. return OTS_FAILURE();
  521. }
  522. if (offset_class_rule < class_rule_end || offset_class_rule >= length) {
  523. return OTS_FAILURE();
  524. }
  525. if (!ParseClassRuleTable(data + offset_class_rule,
  526. length - offset_class_rule, num_glyphs,
  527. num_lookups)) {
  528. return OTS_FAILURE();
  529. }
  530. }
  531. return true;
  532. }
  533. bool ParseContextFormat2(const uint8_t *data, const size_t length,
  534. const uint16_t num_glyphs,
  535. const uint16_t num_lookups) {
  536. ots::Buffer subtable(data, length);
  537. uint16_t offset_coverage = 0;
  538. uint16_t offset_class_def = 0;
  539. uint16_t class_set_cnt = 0;
  540. // Skip format field.
  541. if (!subtable.Skip(2) ||
  542. !subtable.ReadU16(&offset_coverage) ||
  543. !subtable.ReadU16(&offset_class_def) ||
  544. !subtable.ReadU16(&class_set_cnt)) {
  545. return OTS_FAILURE();
  546. }
  547. const unsigned class_set_end = static_cast<unsigned>(8) +
  548. class_set_cnt * 2;
  549. if (class_set_end > std::numeric_limits<uint16_t>::max()) {
  550. return OTS_FAILURE();
  551. }
  552. if (offset_coverage < class_set_end || offset_coverage >= length) {
  553. return OTS_FAILURE();
  554. }
  555. if (!ots::ParseCoverageTable(data + offset_coverage,
  556. length - offset_coverage, num_glyphs)) {
  557. return OTS_FAILURE();
  558. }
  559. if (offset_class_def < class_set_end || offset_class_def >= length) {
  560. return OTS_FAILURE();
  561. }
  562. if (!ots::ParseClassDefTable(data + offset_class_def,
  563. length - offset_class_def,
  564. num_glyphs, kMaxClassDefValue)) {
  565. return OTS_FAILURE();
  566. }
  567. for (unsigned i = 0; i < class_set_cnt; ++i) {
  568. uint16_t offset_class_rule = 0;
  569. if (!subtable.ReadU16(&offset_class_rule)) {
  570. return OTS_FAILURE();
  571. }
  572. if (offset_class_rule) {
  573. if (offset_class_rule < class_set_end || offset_class_rule >= length) {
  574. return OTS_FAILURE();
  575. }
  576. if (!ParseClassSetTable(data + offset_class_rule,
  577. length - offset_class_rule, num_glyphs,
  578. num_lookups)) {
  579. return OTS_FAILURE();
  580. }
  581. }
  582. }
  583. return true;
  584. }
  585. bool ParseContextFormat3(const uint8_t *data, const size_t length,
  586. const uint16_t num_glyphs,
  587. const uint16_t num_lookups) {
  588. ots::Buffer subtable(data, length);
  589. uint16_t glyph_count = 0;
  590. uint16_t lookup_count = 0;
  591. // Skip format field.
  592. if (!subtable.Skip(2) ||
  593. !subtable.ReadU16(&glyph_count) ||
  594. !subtable.ReadU16(&lookup_count)) {
  595. return OTS_FAILURE();
  596. }
  597. if (glyph_count >= num_glyphs) {
  598. return OTS_FAILURE();
  599. }
  600. const unsigned lookup_record_end = static_cast<unsigned>(6) +
  601. glyph_count * 2 + lookup_count * 4;
  602. if (lookup_record_end > std::numeric_limits<uint16_t>::max()) {
  603. return OTS_FAILURE();
  604. }
  605. for (unsigned i = 0; i < glyph_count; ++i) {
  606. uint16_t offset_coverage = 0;
  607. if (!subtable.ReadU16(&offset_coverage)) {
  608. return OTS_FAILURE();
  609. }
  610. if (offset_coverage < lookup_record_end || offset_coverage >= length) {
  611. return OTS_FAILURE();
  612. }
  613. if (!ots::ParseCoverageTable(data + offset_coverage,
  614. length - offset_coverage, num_glyphs)) {
  615. return OTS_FAILURE();
  616. }
  617. }
  618. for (unsigned i = 0; i < lookup_count; ++i) {
  619. if (!ParseLookupRecord(&subtable, num_glyphs, num_lookups)) {
  620. return OTS_FAILURE();
  621. }
  622. }
  623. return true;
  624. }
  625. // Parsers for Chaning Contextual subtables in GSUB/GPOS tables.
  626. bool ParseChainRuleSubtable(const uint8_t *data, const size_t length,
  627. const uint16_t num_glyphs,
  628. const uint16_t num_lookups) {
  629. ots::Buffer subtable(data, length);
  630. uint16_t backtrack_count = 0;
  631. if (!subtable.ReadU16(&backtrack_count)) {
  632. return OTS_FAILURE();
  633. }
  634. if (backtrack_count >= num_glyphs) {
  635. return OTS_FAILURE();
  636. }
  637. for (unsigned i = 0; i < backtrack_count; ++i) {
  638. uint16_t glyph_id = 0;
  639. if (!subtable.ReadU16(&glyph_id)) {
  640. return OTS_FAILURE();
  641. }
  642. if (glyph_id > num_glyphs) {
  643. return OTS_FAILURE();
  644. }
  645. }
  646. uint16_t input_count = 0;
  647. if (!subtable.ReadU16(&input_count)) {
  648. return OTS_FAILURE();
  649. }
  650. if (input_count == 0 || input_count >= num_glyphs) {
  651. return OTS_FAILURE();
  652. }
  653. for (unsigned i = 0; i < input_count - static_cast<unsigned>(1); ++i) {
  654. uint16_t glyph_id = 0;
  655. if (!subtable.ReadU16(&glyph_id)) {
  656. return OTS_FAILURE();
  657. }
  658. if (glyph_id > num_glyphs) {
  659. return OTS_FAILURE();
  660. }
  661. }
  662. uint16_t lookahead_count = 0;
  663. if (!subtable.ReadU16(&lookahead_count)) {
  664. return OTS_FAILURE();
  665. }
  666. if (lookahead_count >= num_glyphs) {
  667. return OTS_FAILURE();
  668. }
  669. for (unsigned i = 0; i < lookahead_count; ++i) {
  670. uint16_t glyph_id = 0;
  671. if (!subtable.ReadU16(&glyph_id)) {
  672. return OTS_FAILURE();
  673. }
  674. if (glyph_id > num_glyphs) {
  675. return OTS_FAILURE();
  676. }
  677. }
  678. uint16_t lookup_count = 0;
  679. if (!subtable.ReadU16(&lookup_count)) {
  680. return OTS_FAILURE();
  681. }
  682. for (unsigned i = 0; i < lookup_count; ++i) {
  683. if (!ParseLookupRecord(&subtable, num_glyphs, num_lookups)) {
  684. return OTS_FAILURE();
  685. }
  686. }
  687. return true;
  688. }
  689. bool ParseChainRuleSetTable(const uint8_t *data, const size_t length,
  690. const uint16_t num_glyphs,
  691. const uint16_t num_lookups) {
  692. ots::Buffer subtable(data, length);
  693. uint16_t chain_rule_count = 0;
  694. if (!subtable.ReadU16(&chain_rule_count)) {
  695. return OTS_FAILURE();
  696. }
  697. const unsigned chain_rule_end = static_cast<unsigned>(2) +
  698. chain_rule_count * 2;
  699. if (chain_rule_end > std::numeric_limits<uint16_t>::max()) {
  700. return OTS_FAILURE();
  701. }
  702. for (unsigned i = 0; i < chain_rule_count; ++i) {
  703. uint16_t offset_chain_rule = 0;
  704. if (!subtable.ReadU16(&offset_chain_rule)) {
  705. return OTS_FAILURE();
  706. }
  707. if (offset_chain_rule < chain_rule_end || offset_chain_rule >= length) {
  708. return OTS_FAILURE();
  709. }
  710. if (!ParseChainRuleSubtable(data + offset_chain_rule,
  711. length - offset_chain_rule,
  712. num_glyphs, num_lookups)) {
  713. return OTS_FAILURE();
  714. }
  715. }
  716. return true;
  717. }
  718. bool ParseChainContextFormat1(const uint8_t *data, const size_t length,
  719. const uint16_t num_glyphs,
  720. const uint16_t num_lookups) {
  721. ots::Buffer subtable(data, length);
  722. uint16_t offset_coverage = 0;
  723. uint16_t chain_rule_set_count = 0;
  724. // Skip format field.
  725. if (!subtable.Skip(2) ||
  726. !subtable.ReadU16(&offset_coverage) ||
  727. !subtable.ReadU16(&chain_rule_set_count)) {
  728. return OTS_FAILURE();
  729. }
  730. const unsigned chain_rule_set_end = static_cast<unsigned>(6) +
  731. chain_rule_set_count * 2;
  732. if (chain_rule_set_end > std::numeric_limits<uint16_t>::max()) {
  733. return OTS_FAILURE();
  734. }
  735. if (offset_coverage < chain_rule_set_end || offset_coverage >= length) {
  736. return OTS_FAILURE();
  737. }
  738. if (!ots::ParseCoverageTable(data + offset_coverage,
  739. length - offset_coverage, num_glyphs)) {
  740. return OTS_FAILURE();
  741. }
  742. for (unsigned i = 0; i < chain_rule_set_count; ++i) {
  743. uint16_t offset_chain_rule_set = 0;
  744. if (!subtable.ReadU16(&offset_chain_rule_set)) {
  745. return OTS_FAILURE();
  746. }
  747. if (offset_chain_rule_set < chain_rule_set_end ||
  748. offset_chain_rule_set >= length) {
  749. return OTS_FAILURE();
  750. }
  751. if (!ParseChainRuleSetTable(data + offset_chain_rule_set,
  752. length - offset_chain_rule_set,
  753. num_glyphs, num_lookups)) {
  754. return OTS_FAILURE();
  755. }
  756. }
  757. return true;
  758. }
  759. bool ParseChainClassRuleSubtable(const uint8_t *data, const size_t length,
  760. const uint16_t num_glyphs,
  761. const uint16_t num_lookups) {
  762. ots::Buffer subtable(data, length);
  763. // In this subtable, we don't check the value of classes for now since
  764. // these could take arbitrary values.
  765. uint16_t backtrack_count = 0;
  766. if (!subtable.ReadU16(&backtrack_count)) {
  767. return OTS_FAILURE();
  768. }
  769. if (backtrack_count >= num_glyphs) {
  770. return OTS_FAILURE();
  771. }
  772. if (!subtable.Skip(2 * backtrack_count)) {
  773. return OTS_FAILURE();
  774. }
  775. uint16_t input_count = 0;
  776. if (!subtable.ReadU16(&input_count)) {
  777. return OTS_FAILURE();
  778. }
  779. if (input_count == 0 || input_count >= num_glyphs) {
  780. return OTS_FAILURE();
  781. }
  782. if (!subtable.Skip(2 * (input_count - 1))) {
  783. return OTS_FAILURE();
  784. }
  785. uint16_t lookahead_count = 0;
  786. if (!subtable.ReadU16(&lookahead_count)) {
  787. return OTS_FAILURE();
  788. }
  789. if (lookahead_count >= num_glyphs) {
  790. return OTS_FAILURE();
  791. }
  792. if (!subtable.Skip(2 * lookahead_count)) {
  793. return OTS_FAILURE();
  794. }
  795. uint16_t lookup_count = 0;
  796. if (!subtable.ReadU16(&lookup_count)) {
  797. return OTS_FAILURE();
  798. }
  799. for (unsigned i = 0; i < lookup_count; ++i) {
  800. if (!ParseLookupRecord(&subtable, num_glyphs, num_lookups)) {
  801. return OTS_FAILURE();
  802. }
  803. }
  804. return true;
  805. }
  806. bool ParseChainClassSetTable(const uint8_t *data, const size_t length,
  807. const uint16_t num_glyphs,
  808. const uint16_t num_lookups) {
  809. ots::Buffer subtable(data, length);
  810. uint16_t chain_class_rule_count = 0;
  811. if (!subtable.ReadU16(&chain_class_rule_count)) {
  812. return OTS_FAILURE();
  813. }
  814. const unsigned chain_class_rule_end = static_cast<unsigned>(2) +
  815. chain_class_rule_count * 2;
  816. if (chain_class_rule_end > std::numeric_limits<uint16_t>::max()) {
  817. return OTS_FAILURE();
  818. }
  819. for (unsigned i = 0; i < chain_class_rule_count; ++i) {
  820. uint16_t offset_chain_class_rule = 0;
  821. if (!subtable.ReadU16(&offset_chain_class_rule)) {
  822. return OTS_FAILURE();
  823. }
  824. if (offset_chain_class_rule < chain_class_rule_end ||
  825. offset_chain_class_rule >= length) {
  826. return OTS_FAILURE();
  827. }
  828. if (!ParseChainClassRuleSubtable(data + offset_chain_class_rule,
  829. length - offset_chain_class_rule,
  830. num_glyphs, num_lookups)) {
  831. return OTS_FAILURE();
  832. }
  833. }
  834. return true;
  835. }
  836. bool ParseChainContextFormat2(const uint8_t *data, const size_t length,
  837. const uint16_t num_glyphs,
  838. const uint16_t num_lookups) {
  839. ots::Buffer subtable(data, length);
  840. uint16_t offset_coverage = 0;
  841. uint16_t offset_backtrack_class_def = 0;
  842. uint16_t offset_input_class_def = 0;
  843. uint16_t offset_lookahead_class_def = 0;
  844. uint16_t chain_class_set_count = 0;
  845. // Skip format field.
  846. if (!subtable.Skip(2) ||
  847. !subtable.ReadU16(&offset_coverage) ||
  848. !subtable.ReadU16(&offset_backtrack_class_def) ||
  849. !subtable.ReadU16(&offset_input_class_def) ||
  850. !subtable.ReadU16(&offset_lookahead_class_def) ||
  851. !subtable.ReadU16(&chain_class_set_count)) {
  852. return OTS_FAILURE();
  853. }
  854. const unsigned chain_class_set_end = static_cast<unsigned>(12) +
  855. chain_class_set_count * 2;
  856. if (chain_class_set_end > std::numeric_limits<uint16_t>::max()) {
  857. return OTS_FAILURE();
  858. }
  859. if (offset_coverage < chain_class_set_end || offset_coverage >= length) {
  860. return OTS_FAILURE();
  861. }
  862. if (!ots::ParseCoverageTable(data + offset_coverage,
  863. length - offset_coverage, num_glyphs)) {
  864. return OTS_FAILURE();
  865. }
  866. // Classes for backtrack/lookahead sequences might not be defined.
  867. if (offset_backtrack_class_def) {
  868. if (offset_backtrack_class_def < chain_class_set_end ||
  869. offset_backtrack_class_def >= length) {
  870. return OTS_FAILURE();
  871. }
  872. if (!ots::ParseClassDefTable(data + offset_backtrack_class_def,
  873. length - offset_backtrack_class_def,
  874. num_glyphs, kMaxClassDefValue)) {
  875. return OTS_FAILURE();
  876. }
  877. }
  878. if (offset_input_class_def < chain_class_set_end ||
  879. offset_input_class_def >= length) {
  880. return OTS_FAILURE();
  881. }
  882. if (!ots::ParseClassDefTable(data + offset_input_class_def,
  883. length - offset_input_class_def,
  884. num_glyphs, kMaxClassDefValue)) {
  885. return OTS_FAILURE();
  886. }
  887. if (offset_lookahead_class_def) {
  888. if (offset_lookahead_class_def < chain_class_set_end ||
  889. offset_lookahead_class_def >= length) {
  890. return OTS_FAILURE();
  891. }
  892. if (!ots::ParseClassDefTable(data + offset_lookahead_class_def,
  893. length - offset_lookahead_class_def,
  894. num_glyphs, kMaxClassDefValue)) {
  895. return OTS_FAILURE();
  896. }
  897. }
  898. for (unsigned i = 0; i < chain_class_set_count; ++i) {
  899. uint16_t offset_chain_class_set = 0;
  900. if (!subtable.ReadU16(&offset_chain_class_set)) {
  901. return OTS_FAILURE();
  902. }
  903. // |offset_chain_class_set| could be NULL.
  904. if (offset_chain_class_set) {
  905. if (offset_chain_class_set < chain_class_set_end ||
  906. offset_chain_class_set >= length) {
  907. return OTS_FAILURE();
  908. }
  909. if (!ParseChainClassSetTable(data + offset_chain_class_set,
  910. length - offset_chain_class_set,
  911. num_glyphs, num_lookups)) {
  912. return OTS_FAILURE();
  913. }
  914. }
  915. }
  916. return true;
  917. }
  918. bool ParseChainContextFormat3(const uint8_t *data, const size_t length,
  919. const uint16_t num_glyphs,
  920. const uint16_t num_lookups) {
  921. ots::Buffer subtable(data, length);
  922. uint16_t backtrack_count = 0;
  923. // Skip format field.
  924. if (!subtable.Skip(2) ||
  925. !subtable.ReadU16(&backtrack_count)) {
  926. return OTS_FAILURE();
  927. }
  928. if (backtrack_count >= num_glyphs) {
  929. return OTS_FAILURE();
  930. }
  931. std::vector<uint16_t> offsets_backtrack;
  932. offsets_backtrack.reserve(backtrack_count);
  933. for (unsigned i = 0; i < backtrack_count; ++i) {
  934. uint16_t offset = 0;
  935. if (!subtable.ReadU16(&offset)) {
  936. return OTS_FAILURE();
  937. }
  938. offsets_backtrack.push_back(offset);
  939. }
  940. if (offsets_backtrack.size() != backtrack_count) {
  941. return OTS_FAILURE();
  942. }
  943. uint16_t input_count = 0;
  944. if (!subtable.ReadU16(&input_count)) {
  945. return OTS_FAILURE();
  946. }
  947. if (input_count >= num_glyphs) {
  948. return OTS_FAILURE();
  949. }
  950. std::vector<uint16_t> offsets_input;
  951. offsets_input.reserve(input_count);
  952. for (unsigned i = 0; i < input_count; ++i) {
  953. uint16_t offset = 0;
  954. if (!subtable.ReadU16(&offset)) {
  955. return OTS_FAILURE();
  956. }
  957. offsets_input.push_back(offset);
  958. }
  959. if (offsets_input.size() != input_count) {
  960. return OTS_FAILURE();
  961. }
  962. uint16_t lookahead_count = 0;
  963. if (!subtable.ReadU16(&lookahead_count)) {
  964. return OTS_FAILURE();
  965. }
  966. if (lookahead_count >= num_glyphs) {
  967. return OTS_FAILURE();
  968. }
  969. std::vector<uint16_t> offsets_lookahead;
  970. offsets_lookahead.reserve(lookahead_count);
  971. for (unsigned i = 0; i < lookahead_count; ++i) {
  972. uint16_t offset = 0;
  973. if (!subtable.ReadU16(&offset)) {
  974. return OTS_FAILURE();
  975. }
  976. offsets_lookahead.push_back(offset);
  977. }
  978. if (offsets_lookahead.size() != lookahead_count) {
  979. return OTS_FAILURE();
  980. }
  981. uint16_t lookup_count = 0;
  982. if (!subtable.ReadU16(&lookup_count)) {
  983. return OTS_FAILURE();
  984. }
  985. for (unsigned i = 0; i < lookup_count; ++i) {
  986. if (!ParseLookupRecord(&subtable, num_glyphs, num_lookups)) {
  987. return OTS_FAILURE();
  988. }
  989. }
  990. const unsigned lookup_record_end = static_cast<unsigned>(10) +
  991. (backtrack_count + input_count + lookahead_count) * 2 + lookup_count * 4;
  992. if (lookup_record_end > std::numeric_limits<uint16_t>::max()) {
  993. return OTS_FAILURE();
  994. }
  995. for (unsigned i = 0; i < backtrack_count; ++i) {
  996. if (offsets_backtrack[i] < lookup_record_end ||
  997. offsets_backtrack[i] >= length) {
  998. return OTS_FAILURE();
  999. }
  1000. if (!ots::ParseCoverageTable(data + offsets_backtrack[i],
  1001. length - offsets_backtrack[i], num_glyphs)) {
  1002. return OTS_FAILURE();
  1003. }
  1004. }
  1005. for (unsigned i = 0; i < input_count; ++i) {
  1006. if (offsets_input[i] < lookup_record_end || offsets_input[i] >= length) {
  1007. return OTS_FAILURE();
  1008. }
  1009. if (!ots::ParseCoverageTable(data + offsets_input[i],
  1010. length - offsets_input[i], num_glyphs)) {
  1011. return OTS_FAILURE();
  1012. }
  1013. }
  1014. for (unsigned i = 0; i < lookahead_count; ++i) {
  1015. if (offsets_lookahead[i] < lookup_record_end ||
  1016. offsets_lookahead[i] >= length) {
  1017. return OTS_FAILURE();
  1018. }
  1019. if (!ots::ParseCoverageTable(data + offsets_lookahead[i],
  1020. length - offsets_lookahead[i], num_glyphs)) {
  1021. return OTS_FAILURE();
  1022. }
  1023. }
  1024. return true;
  1025. }
  1026. } // namespace
  1027. namespace ots {
  1028. bool LookupSubtableParser::Parse(const OpenTypeFile *file, const uint8_t *data,
  1029. const size_t length,
  1030. const uint16_t lookup_type) const {
  1031. for (unsigned i = 0; i < num_types; ++i) {
  1032. if (parsers[i].type == lookup_type && parsers[i].parse) {
  1033. if (!parsers[i].parse(file, data, length)) {
  1034. return OTS_FAILURE();
  1035. }
  1036. return true;
  1037. }
  1038. }
  1039. return OTS_FAILURE();
  1040. }
  1041. // Parsing ScriptListTable requires number of features so we need to
  1042. // parse FeatureListTable before calling this function.
  1043. bool ParseScriptListTable(const uint8_t *data, const size_t length,
  1044. const uint16_t num_features) {
  1045. Buffer subtable(data, length);
  1046. uint16_t script_count = 0;
  1047. if (!subtable.ReadU16(&script_count)) {
  1048. return OTS_FAILURE();
  1049. }
  1050. const unsigned script_record_end = static_cast<unsigned>(2) +
  1051. script_count * 6;
  1052. if (script_record_end > std::numeric_limits<uint16_t>::max()) {
  1053. return OTS_FAILURE();
  1054. }
  1055. std::vector<ScriptRecord> script_list;
  1056. script_list.reserve(script_count);
  1057. uint32_t last_tag = 0;
  1058. for (unsigned i = 0; i < script_count; ++i) {
  1059. ScriptRecord record;
  1060. if (!subtable.ReadU32(&record.tag) ||
  1061. !subtable.ReadU16(&record.offset)) {
  1062. return OTS_FAILURE();
  1063. }
  1064. // Script tags should be arranged alphabetically by tag
  1065. if (last_tag != 0 && last_tag > record.tag) {
  1066. // Several fonts don't arrange tags alphabetically.
  1067. // It seems that the order of tags might not be a security issue
  1068. // so we just warn it.
  1069. OTS_WARNING("tags aren't arranged alphabetically.");
  1070. }
  1071. last_tag = record.tag;
  1072. if (record.offset < script_record_end || record.offset >= length) {
  1073. return OTS_FAILURE();
  1074. }
  1075. script_list.push_back(record);
  1076. }
  1077. if (script_list.size() != script_count) {
  1078. return OTS_FAILURE();
  1079. }
  1080. // Check script records.
  1081. for (unsigned i = 0; i < script_count; ++i) {
  1082. if (!ParseScriptTable(data + script_list[i].offset,
  1083. length - script_list[i].offset,
  1084. script_list[i].tag, num_features)) {
  1085. return OTS_FAILURE();
  1086. }
  1087. }
  1088. return true;
  1089. }
  1090. // Parsing FeatureListTable requires number of lookups so we need to parse
  1091. // LookupListTable before calling this function.
  1092. bool ParseFeatureListTable(const uint8_t *data, const size_t length,
  1093. const uint16_t num_lookups,
  1094. uint16_t* num_features) {
  1095. Buffer subtable(data, length);
  1096. uint16_t feature_count = 0;
  1097. if (!subtable.ReadU16(&feature_count)) {
  1098. return OTS_FAILURE();
  1099. }
  1100. std::vector<FeatureRecord> feature_records;
  1101. feature_records.resize(feature_count);
  1102. const unsigned feature_record_end = static_cast<unsigned>(2) +
  1103. feature_count * 6;
  1104. if (feature_record_end > std::numeric_limits<uint16_t>::max()) {
  1105. return OTS_FAILURE();
  1106. }
  1107. uint32_t last_tag = 0;
  1108. for (unsigned i = 0; i < feature_count; ++i) {
  1109. if (!subtable.ReadU32(&feature_records[i].tag) ||
  1110. !subtable.ReadU16(&feature_records[i].offset)) {
  1111. return OTS_FAILURE();
  1112. }
  1113. // Feature record array should be arranged alphabetically by tag
  1114. if (last_tag != 0 && last_tag > feature_records[i].tag) {
  1115. // Several fonts don't arrange tags alphabetically.
  1116. // It seems that the order of tags might not be a security issue
  1117. // so we just warn it.
  1118. OTS_WARNING("tags aren't arranged alphabetically.");
  1119. }
  1120. last_tag = feature_records[i].tag;
  1121. if (feature_records[i].offset < feature_record_end ||
  1122. feature_records[i].offset >= length) {
  1123. return OTS_FAILURE();
  1124. }
  1125. }
  1126. for (unsigned i = 0; i < feature_count; ++i) {
  1127. if (!ParseFeatureTable(data + feature_records[i].offset,
  1128. length - feature_records[i].offset, num_lookups)) {
  1129. return OTS_FAILURE();
  1130. }
  1131. }
  1132. *num_features = feature_count;
  1133. return true;
  1134. }
  1135. // For parsing GPOS/GSUB tables, this function should be called at first to
  1136. // obtain the number of lookups because parsing FeatureTableList requires
  1137. // the number.
  1138. bool ParseLookupListTable(OpenTypeFile *file, const uint8_t *data,
  1139. const size_t length,
  1140. const LookupSubtableParser* parser,
  1141. uint16_t *num_lookups) {
  1142. Buffer subtable(data, length);
  1143. if (!subtable.ReadU16(num_lookups)) {
  1144. return OTS_FAILURE();
  1145. }
  1146. std::vector<uint16_t> lookups;
  1147. lookups.reserve(*num_lookups);
  1148. const unsigned lookup_end = static_cast<unsigned>(2) +
  1149. (*num_lookups) * 2;
  1150. if (lookup_end > std::numeric_limits<uint16_t>::max()) {
  1151. return OTS_FAILURE();
  1152. }
  1153. for (unsigned i = 0; i < *num_lookups; ++i) {
  1154. uint16_t offset = 0;
  1155. if (!subtable.ReadU16(&offset)) {
  1156. return OTS_FAILURE();
  1157. }
  1158. if (offset < lookup_end || offset >= length) {
  1159. return OTS_FAILURE();
  1160. }
  1161. lookups.push_back(offset);
  1162. }
  1163. if (lookups.size() != *num_lookups) {
  1164. return OTS_FAILURE();
  1165. }
  1166. for (unsigned i = 0; i < *num_lookups; ++i) {
  1167. if (!ParseLookupTable(file, data + lookups[i], length - lookups[i],
  1168. parser)) {
  1169. return OTS_FAILURE();
  1170. }
  1171. }
  1172. return true;
  1173. }
  1174. bool ParseClassDefTable(const uint8_t *data, size_t length,
  1175. const uint16_t num_glyphs,
  1176. const uint16_t num_classes) {
  1177. Buffer subtable(data, length);
  1178. uint16_t format = 0;
  1179. if (!subtable.ReadU16(&format)) {
  1180. return OTS_FAILURE();
  1181. }
  1182. if (format == 1) {
  1183. return ParseClassDefFormat1(data, length, num_glyphs, num_classes);
  1184. } else if (format == 2) {
  1185. return ParseClassDefFormat2(data, length, num_glyphs, num_classes);
  1186. }
  1187. return OTS_FAILURE();
  1188. }
  1189. bool ParseCoverageTable(const uint8_t *data, size_t length,
  1190. const uint16_t num_glyphs) {
  1191. Buffer subtable(data, length);
  1192. uint16_t format = 0;
  1193. if (!subtable.ReadU16(&format)) {
  1194. return OTS_FAILURE();
  1195. }
  1196. if (format == 1) {
  1197. return ParseCoverageFormat1(data, length, num_glyphs);
  1198. } else if (format == 2) {
  1199. return ParseCoverageFormat2(data, length, num_glyphs);
  1200. }
  1201. return OTS_FAILURE();
  1202. }
  1203. bool ParseDeviceTable(const uint8_t *data, size_t length) {
  1204. Buffer subtable(data, length);
  1205. uint16_t start_size = 0;
  1206. uint16_t end_size = 0;
  1207. uint16_t delta_format = 0;
  1208. if (!subtable.ReadU16(&start_size) ||
  1209. !subtable.ReadU16(&end_size) ||
  1210. !subtable.ReadU16(&delta_format)) {
  1211. return OTS_FAILURE();
  1212. }
  1213. if (start_size > end_size) {
  1214. OTS_WARNING("bad size range: %u > %u", start_size, end_size);
  1215. return OTS_FAILURE();
  1216. }
  1217. if (delta_format == 0 || delta_format > kMaxDeltaFormatType) {
  1218. OTS_WARNING("bad delta format: %u", delta_format);
  1219. return OTS_FAILURE();
  1220. }
  1221. // The number of delta values per uint16. The device table should contain
  1222. // at least |num_units| * 2 bytes compressed data.
  1223. const unsigned num_units = (end_size - start_size) /
  1224. (1 << (4 - delta_format)) + 1;
  1225. // Just skip |num_units| * 2 bytes since the compressed data could take
  1226. // arbitrary values.
  1227. if (!subtable.Skip(num_units * 2)) {
  1228. return OTS_FAILURE();
  1229. }
  1230. return true;
  1231. }
  1232. bool ParseContextSubtable(const uint8_t *data, const size_t length,
  1233. const uint16_t num_glyphs,
  1234. const uint16_t num_lookups) {
  1235. Buffer subtable(data, length);
  1236. uint16_t format = 0;
  1237. if (!subtable.ReadU16(&format)) {
  1238. return OTS_FAILURE();
  1239. }
  1240. if (format == 1) {
  1241. if (!ParseContextFormat1(data, length, num_glyphs, num_lookups)) {
  1242. return OTS_FAILURE();
  1243. }
  1244. } else if (format == 2) {
  1245. if (!ParseContextFormat2(data, length, num_glyphs, num_lookups)) {
  1246. return OTS_FAILURE();
  1247. }
  1248. } else if (format == 3) {
  1249. if (!ParseContextFormat3(data, length, num_glyphs, num_lookups)) {
  1250. return OTS_FAILURE();
  1251. }
  1252. } else {
  1253. return OTS_FAILURE();
  1254. }
  1255. return true;
  1256. }
  1257. bool ParseChainingContextSubtable(const uint8_t *data, const size_t length,
  1258. const uint16_t num_glyphs,
  1259. const uint16_t num_lookups) {
  1260. Buffer subtable(data, length);
  1261. uint16_t format = 0;
  1262. if (!subtable.ReadU16(&format)) {
  1263. return OTS_FAILURE();
  1264. }
  1265. if (format == 1) {
  1266. if (!ParseChainContextFormat1(data, length, num_glyphs, num_lookups)) {
  1267. return OTS_FAILURE();
  1268. }
  1269. } else if (format == 2) {
  1270. if (!ParseChainContextFormat2(data, length, num_glyphs, num_lookups)) {
  1271. return OTS_FAILURE();
  1272. }
  1273. } else if (format == 3) {
  1274. if (!ParseChainContextFormat3(data, length, num_glyphs, num_lookups)) {
  1275. return OTS_FAILURE();
  1276. }
  1277. } else {
  1278. return OTS_FAILURE();
  1279. }
  1280. return true;
  1281. }
  1282. bool ParseExtensionSubtable(const OpenTypeFile *file,
  1283. const uint8_t *data, const size_t length,
  1284. const LookupSubtableParser* parser) {
  1285. Buffer subtable(data, length);
  1286. uint16_t format = 0;
  1287. uint16_t lookup_type = 0;
  1288. uint32_t offset_extension = 0;
  1289. if (!subtable.ReadU16(&format) ||
  1290. !subtable.ReadU16(&lookup_type) ||
  1291. !subtable.ReadU32(&offset_extension)) {
  1292. return OTS_FAILURE();
  1293. }
  1294. if (format != 1) {
  1295. return OTS_FAILURE();
  1296. }
  1297. // |lookup_type| should be other than |parser->extension_type|.
  1298. if (lookup_type < 1 || lookup_type > parser->num_types ||
  1299. lookup_type == parser->extension_type) {
  1300. return OTS_FAILURE();
  1301. }
  1302. const unsigned format_end = static_cast<unsigned>(8);
  1303. if (offset_extension < format_end ||
  1304. offset_extension >= length) {
  1305. return OTS_FAILURE();
  1306. }
  1307. // Parse the extension subtable of |lookup_type|.
  1308. if (!parser->Parse(file, data + offset_extension, length - offset_extension,
  1309. lookup_type)) {
  1310. return OTS_FAILURE();
  1311. }
  1312. return true;
  1313. }
  1314. } // namespace ots