100b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com// Copyright (c) 2011 The Chromium Authors. All rights reserved. 200b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com// Use of this source code is governed by a BSD-style license that can be 300b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com// found in the LICENSE file. 400b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com 500b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com#include "layout.h" 600b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com 778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com#include <limits> 878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com#include <vector> 978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 1078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com#include "gdef.h" 1178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 1200b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com// OpenType Layout Common Table Formats 1300b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com// http://www.microsoft.com/typography/otspec/chapter2.htm 1400b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com 1500b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.comnamespace { 1600b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com 1778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com// The 'DFLT' tag of script table. 1878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.comconst uint32_t kScriptTableTagDflt = 0x44464c54; 1978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com// The value which represents there is no required feature index. 2078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.comconst uint16_t kNoRequiredFeatureIndexDefined = 0xFFFF; 2178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com// The lookup flag bit which indicates existence of MarkFilteringSet. 2278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.comconst uint16_t kUseMarkFilteringSetBit = 0x0010; 23df5b76f08621c6589b4dde7f0b7177bab1bb297cbashi@chromium.org// The lookup flags which require GDEF table. 24df5b76f08621c6589b4dde7f0b7177bab1bb297cbashi@chromium.orgconst uint16_t kGdefRequiredFlags = 0x0002 | 0x0004 | 0x0008; 2578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com// The mask for MarkAttachmentType. 2678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.comconst uint16_t kMarkAttachmentTypeMask = 0xFF00; 2778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com// The maximum type number of format for device tables. 2878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.comconst uint16_t kMaxDeltaFormatType = 3; 29ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org// The maximum number of class value. 30ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.orgconst uint16_t kMaxClassDefValue = 0xFFFF; 3178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 3278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.comstruct ScriptRecord { 3378a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com uint32_t tag; 3478a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com uint16_t offset; 3578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com}; 3678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 3778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.comstruct LangSysRecord { 3878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com uint32_t tag; 3978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com uint16_t offset; 4078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com}; 4178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 4278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.comstruct FeatureRecord { 4378a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com uint32_t tag; 4478a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com uint16_t offset; 4578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com}; 4678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 4778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.combool ParseLangSysTable(ots::Buffer *subtable, const uint32_t tag, 4878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com const uint16_t num_features) { 4978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com uint16_t offset_lookup_order = 0; 5078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com uint16_t req_feature_index = 0; 5178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com uint16_t feature_count = 0; 5278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (!subtable->ReadU16(&offset_lookup_order) || 5378a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com !subtable->ReadU16(&req_feature_index) || 5478a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com !subtable->ReadU16(&feature_count)) { 5578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 5678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 5778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com // |offset_lookup_order| is reserved and should be NULL. 5878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (offset_lookup_order != 0) { 5978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 6078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 6178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (req_feature_index != kNoRequiredFeatureIndexDefined && 6278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com req_feature_index >= num_features) { 6378a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 6478a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 6578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (feature_count > num_features) { 6678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 6778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 6878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 6978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com for (unsigned i = 0; i < feature_count; ++i) { 7078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com uint16_t feature_index = 0; 7178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (!subtable->ReadU16(&feature_index)) { 7278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 7378a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 7478a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (feature_index >= num_features) { 7578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 7678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 7778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 7878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return true; 7978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com} 8078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 8178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.combool ParseScriptTable(const uint8_t *data, const size_t length, 8278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com const uint32_t tag, const uint16_t num_features) { 8378a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com ots::Buffer subtable(data, length); 8478a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 8578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com uint16_t offset_default_lang_sys = 0; 8678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com uint16_t lang_sys_count = 0; 8778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (!subtable.ReadU16(&offset_default_lang_sys) || 8878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com !subtable.ReadU16(&lang_sys_count)) { 8978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 9078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 9178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 9278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com // The spec requires a script table for 'DFLT' tag must contain non-NULL 9378a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com // |offset_default_lang_sys| and |lang_sys_count| == 0 9478a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (tag == kScriptTableTagDflt && 9578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com (offset_default_lang_sys == 0 || lang_sys_count != 0)) { 9678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com OTS_WARNING("DFLT table doesn't satisfy the spec."); 9778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 9878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 9978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 10026afae8d52d90e194bad9876776d68bc3bb3a1adbashi@chromium.org const unsigned lang_sys_record_end = 10126afae8d52d90e194bad9876776d68bc3bb3a1adbashi@chromium.org 6 * static_cast<unsigned>(lang_sys_count) + 4; 10278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (lang_sys_record_end > std::numeric_limits<uint16_t>::max()) { 10378a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 10478a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 10578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 10678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com std::vector<LangSysRecord> lang_sys_records; 10778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com lang_sys_records.resize(lang_sys_count); 10878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com uint32_t last_tag = 0; 10978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com for (unsigned i = 0; i < lang_sys_count; ++i) { 11078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (!subtable.ReadU32(&lang_sys_records[i].tag) || 11178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com !subtable.ReadU16(&lang_sys_records[i].offset)) { 11278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 11378a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 11478a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com // The record array must store the records alphabetically by tag 11578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (last_tag != 0 && last_tag > lang_sys_records[i].tag) { 11678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 11778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 11878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (lang_sys_records[i].offset < lang_sys_record_end || 11978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com lang_sys_records[i].offset >= length) { 120a574866c0e4b1539098e64422f59d01c80cea6cfbashi@chromium.org OTS_WARNING("bad offset to lang sys table: %x", 121a574866c0e4b1539098e64422f59d01c80cea6cfbashi@chromium.org lang_sys_records[i].offset); 12278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 12378a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 12478a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com last_tag = lang_sys_records[i].tag; 12578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 12678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 12778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com // Check lang sys tables 12878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com for (unsigned i = 0; i < lang_sys_count; ++i) { 12978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com subtable.set_offset(lang_sys_records[i].offset); 13078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (!ParseLangSysTable(&subtable, lang_sys_records[i].tag, num_features)) { 13178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 13278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 13378a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 13478a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 13578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return true; 13678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com} 13778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 13878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.combool ParseFeatureTable(const uint8_t *data, const size_t length, 13978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com const uint16_t num_lookups) { 14078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com ots::Buffer subtable(data, length); 14178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 14278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com uint16_t offset_feature_params = 0; 14378a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com uint16_t lookup_count = 0; 14478a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (!subtable.ReadU16(&offset_feature_params) || 14578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com !subtable.ReadU16(&lookup_count)) { 14678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 14778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 14878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 14926afae8d52d90e194bad9876776d68bc3bb3a1adbashi@chromium.org const unsigned feature_table_end = 15058b44a4cf8d382464149b23b51e400af6114947cbashi@chromium.org 2 * static_cast<unsigned>(lookup_count) + 4; 15178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (feature_table_end > std::numeric_limits<uint16_t>::max()) { 15278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 15378a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 15478a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com // |offset_feature_params| is generally set to NULL. 15578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (offset_feature_params != 0 && 15678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com (offset_feature_params < feature_table_end || 15778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com offset_feature_params >= length)) { 15878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 15978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 16078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 16178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com for (unsigned i = 0; i < lookup_count; ++i) { 16278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com uint16_t lookup_index = 0; 16378a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (!subtable.ReadU16(&lookup_index)) { 16478a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 16578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 16678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com // lookup index starts with 0. 16778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (lookup_index >= num_lookups) { 16878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 16978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 17078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 17178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return true; 17278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com} 17378a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 17478a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.combool ParseLookupTable(ots::OpenTypeFile *file, const uint8_t *data, 175ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const size_t length, 176ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const ots::LookupSubtableParser* parser) { 17778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com ots::Buffer subtable(data, length); 17878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 17978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com uint16_t lookup_type = 0; 18078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com uint16_t lookup_flag = 0; 18178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com uint16_t subtable_count = 0; 18278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (!subtable.ReadU16(&lookup_type) || 18378a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com !subtable.ReadU16(&lookup_flag) || 18478a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com !subtable.ReadU16(&subtable_count)) { 18578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 18678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 18778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 188ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (lookup_type == 0 || lookup_type > parser->num_types) { 18978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 19078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 19178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 19278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com // Check lookup flags. 193df5b76f08621c6589b4dde7f0b7177bab1bb297cbashi@chromium.org if ((lookup_flag & kGdefRequiredFlags) && 194df5b76f08621c6589b4dde7f0b7177bab1bb297cbashi@chromium.org (!file->gdef || !file->gdef->has_glyph_class_def)) { 195df5b76f08621c6589b4dde7f0b7177bab1bb297cbashi@chromium.org return OTS_FAILURE(); 196df5b76f08621c6589b4dde7f0b7177bab1bb297cbashi@chromium.org } 19778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if ((lookup_flag & kMarkAttachmentTypeMask) && 19878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com (!file->gdef || !file->gdef->has_mark_attachment_class_def)) { 19978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 20078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 20178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com bool use_mark_filtering_set = false; 20278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (lookup_flag & kUseMarkFilteringSetBit) { 20378a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (!file->gdef || !file->gdef->has_mark_glyph_sets_def) { 20478a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 20578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 20678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com use_mark_filtering_set = true; 20778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 20878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 20978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com std::vector<uint16_t> subtables; 21078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com subtables.reserve(subtable_count); 21178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com // If the |kUseMarkFilteringSetBit| of |lookup_flag| is set, 21278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com // extra 2 bytes will follow after subtable offset array. 21326afae8d52d90e194bad9876776d68bc3bb3a1adbashi@chromium.org const unsigned lookup_table_end = 2 * static_cast<unsigned>(subtable_count) + 21426afae8d52d90e194bad9876776d68bc3bb3a1adbashi@chromium.org (use_mark_filtering_set ? 8 : 6); 21578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (lookup_table_end > std::numeric_limits<uint16_t>::max()) { 21678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 21778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 21878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com for (unsigned i = 0; i < subtable_count; ++i) { 219e2b566a774d999486a3d0388a9995aca63dcf46bbashi@chromium.org uint16_t offset_subtable = 0; 220e2b566a774d999486a3d0388a9995aca63dcf46bbashi@chromium.org if (!subtable.ReadU16(&offset_subtable)) { 22178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 22278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 223e2b566a774d999486a3d0388a9995aca63dcf46bbashi@chromium.org if (offset_subtable < lookup_table_end || 224e2b566a774d999486a3d0388a9995aca63dcf46bbashi@chromium.org offset_subtable >= length) { 22578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 22678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 227e2b566a774d999486a3d0388a9995aca63dcf46bbashi@chromium.org subtables.push_back(offset_subtable); 22878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 2296b41020e0a52fbc3a257a1b7652a0fcc92f6f9afbashi@chromium.org if (subtables.size() != subtable_count) { 2306b41020e0a52fbc3a257a1b7652a0fcc92f6f9afbashi@chromium.org return OTS_FAILURE(); 2316b41020e0a52fbc3a257a1b7652a0fcc92f6f9afbashi@chromium.org } 23278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 23378a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (use_mark_filtering_set) { 23478a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com uint16_t mark_filtering_set = 0; 23578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (!subtable.ReadU16(&mark_filtering_set)) { 23678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 23778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 23878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (file->gdef->num_mark_glyph_sets == 0 || 23978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com mark_filtering_set >= file->gdef->num_mark_glyph_sets) { 24078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 24178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 24278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 24378a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 24478a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com // Parse lookup subtables for this lookup type. 24578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com for (unsigned i = 0; i < subtable_count; ++i) { 246ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!parser->Parse(file, data + subtables[i], length - subtables[i], 247ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org lookup_type)) { 24878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 24978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 25078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 25178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return true; 25278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com} 25378a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 25400b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.combool ParseClassDefFormat1(const uint8_t *data, size_t length, 25500b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com const uint16_t num_glyphs, 25600b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com const uint16_t num_classes) { 25700b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com ots::Buffer subtable(data, length); 25800b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com 25900b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com // Skip format field. 26000b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com if (!subtable.Skip(2)) { 26100b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com return OTS_FAILURE(); 26200b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com } 26300b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com 26400b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com uint16_t start_glyph = 0; 26500b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com if (!subtable.ReadU16(&start_glyph)) { 26600b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com return OTS_FAILURE(); 26700b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com } 26800b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com if (start_glyph > num_glyphs) { 26900b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com OTS_WARNING("bad start glyph ID: %u", start_glyph); 27000b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com return OTS_FAILURE(); 27100b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com } 27200b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com 27300b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com uint16_t glyph_count = 0; 27400b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com if (!subtable.ReadU16(&glyph_count)) { 27500b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com return OTS_FAILURE(); 27600b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com } 27700b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com if (glyph_count > num_glyphs) { 27800b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com OTS_WARNING("bad glyph count: %u", glyph_count); 27900b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com return OTS_FAILURE(); 28000b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com } 28100b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com for (unsigned i = 0; i < glyph_count; ++i) { 28200b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com uint16_t class_value = 0; 28300b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com if (!subtable.ReadU16(&class_value)) { 28400b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com return OTS_FAILURE(); 28500b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com } 286ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (class_value > num_classes) { 28700b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com OTS_WARNING("bad class value: %u", class_value); 28800b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com return OTS_FAILURE(); 28900b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com } 29000b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com } 29100b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com 29200b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com return true; 29300b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com} 29400b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com 29500b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.combool ParseClassDefFormat2(const uint8_t *data, size_t length, 29600b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com const uint16_t num_glyphs, 29700b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com const uint16_t num_classes) { 29800b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com ots::Buffer subtable(data, length); 29900b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com 30000b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com // Skip format field. 30100b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com if (!subtable.Skip(2)) { 30200b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com return OTS_FAILURE(); 30300b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com } 30400b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com 30500b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com uint16_t range_count = 0; 30600b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com if (!subtable.ReadU16(&range_count)) { 30700b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com return OTS_FAILURE(); 30800b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com } 30900b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com if (range_count > num_glyphs) { 31000b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com OTS_WARNING("bad range count: %u", range_count); 31100b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com return OTS_FAILURE(); 31200b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com } 31300b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com 31400b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com uint16_t last_end = 0; 31500b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com for (unsigned i = 0; i < range_count; ++i) { 31600b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com uint16_t start = 0; 31700b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com uint16_t end = 0; 31800b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com uint16_t class_value = 0; 31900b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com if (!subtable.ReadU16(&start) || 32000b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com !subtable.ReadU16(&end) || 32100b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com !subtable.ReadU16(&class_value)) { 32200b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com return OTS_FAILURE(); 32300b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com } 32400b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com if (start > end || (last_end && start <= last_end)) { 32500b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com OTS_WARNING("glyph range is overlapping."); 32600b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com return OTS_FAILURE(); 32700b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com } 328ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (class_value > num_classes) { 32900b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com OTS_WARNING("bad class value: %u", class_value); 33000b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com return OTS_FAILURE(); 33100b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com } 33278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com last_end = end; 33300b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com } 33400b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com 33500b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com return true; 33600b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com} 33700b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com 33800b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.combool ParseCoverageFormat1(const uint8_t *data, size_t length, 339eea48361b1ffcc1bded0ba25c8f747e634cd8e51ksakamoto@chromium.org const uint16_t num_glyphs, 340eea48361b1ffcc1bded0ba25c8f747e634cd8e51ksakamoto@chromium.org const uint16_t expected_num_glyphs) { 34100b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com ots::Buffer subtable(data, length); 34200b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com 34300b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com // Skip format field. 34400b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com if (!subtable.Skip(2)) { 34500b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com return OTS_FAILURE(); 34600b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com } 34700b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com 34800b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com uint16_t glyph_count = 0; 34900b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com if (!subtable.ReadU16(&glyph_count)) { 35000b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com return OTS_FAILURE(); 35100b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com } 35200b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com if (glyph_count > num_glyphs) { 35300b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com OTS_WARNING("bad glyph count: %u", glyph_count); 35400b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com return OTS_FAILURE(); 35500b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com } 35600b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com for (unsigned i = 0; i < glyph_count; ++i) { 35700b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com uint16_t glyph = 0; 35800b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com if (!subtable.ReadU16(&glyph)) { 35900b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com return OTS_FAILURE(); 36000b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com } 36100b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com if (glyph > num_glyphs) { 36200b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com OTS_WARNING("bad glyph ID: %u", glyph); 36300b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com return OTS_FAILURE(); 36400b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com } 36500b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com } 36600b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com 367eea48361b1ffcc1bded0ba25c8f747e634cd8e51ksakamoto@chromium.org if (expected_num_glyphs && expected_num_glyphs != glyph_count) { 368eea48361b1ffcc1bded0ba25c8f747e634cd8e51ksakamoto@chromium.org OTS_WARNING("unexpected number of glyphs: %u", glyph_count); 369eea48361b1ffcc1bded0ba25c8f747e634cd8e51ksakamoto@chromium.org return OTS_FAILURE(); 370eea48361b1ffcc1bded0ba25c8f747e634cd8e51ksakamoto@chromium.org } 371eea48361b1ffcc1bded0ba25c8f747e634cd8e51ksakamoto@chromium.org 37200b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com return true; 37300b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com} 37400b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com 37500b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.combool ParseCoverageFormat2(const uint8_t *data, size_t length, 376eea48361b1ffcc1bded0ba25c8f747e634cd8e51ksakamoto@chromium.org const uint16_t num_glyphs, 377eea48361b1ffcc1bded0ba25c8f747e634cd8e51ksakamoto@chromium.org const uint16_t expected_num_glyphs) { 37800b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com ots::Buffer subtable(data, length); 37900b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com 38000b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com // Skip format field. 38100b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com if (!subtable.Skip(2)) { 38200b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com return OTS_FAILURE(); 38300b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com } 38400b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com 38500b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com uint16_t range_count = 0; 38600b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com if (!subtable.ReadU16(&range_count)) { 38700b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com return OTS_FAILURE(); 38800b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com } 38978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (range_count > num_glyphs) { 39000b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com OTS_WARNING("bad range count: %u", range_count); 39100b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com return OTS_FAILURE(); 39200b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com } 39300b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com uint16_t last_end = 0; 39478a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com uint16_t last_start_coverage_index = 0; 39500b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com for (unsigned i = 0; i < range_count; ++i) { 39600b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com uint16_t start = 0; 39700b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com uint16_t end = 0; 39800b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com uint16_t start_coverage_index = 0; 39900b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com if (!subtable.ReadU16(&start) || 40000b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com !subtable.ReadU16(&end) || 40100b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com !subtable.ReadU16(&start_coverage_index)) { 40200b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com return OTS_FAILURE(); 40300b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com } 404006c34500789d5bbf2bb077c68381418f25e7e7dagl@chromium.org 405006c34500789d5bbf2bb077c68381418f25e7e7dagl@chromium.org // Some of the Adobe Pro fonts have ranges that overlap by one element: the 406006c34500789d5bbf2bb077c68381418f25e7e7dagl@chromium.org // start of one range is equal to the end of the previous range. Therefore 407006c34500789d5bbf2bb077c68381418f25e7e7dagl@chromium.org // the < in the following condition should be <= were it not for this. 408006c34500789d5bbf2bb077c68381418f25e7e7dagl@chromium.org // See crbug.com/134135. 409006c34500789d5bbf2bb077c68381418f25e7e7dagl@chromium.org if (start > end || (last_end && start < last_end)) { 41000b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com OTS_WARNING("glyph range is overlapping."); 41100b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com return OTS_FAILURE(); 41200b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com } 41378a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (start_coverage_index != last_start_coverage_index) { 41478a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com OTS_WARNING("bad start coverage index."); 41578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 41678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 41778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com last_end = end; 41878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com last_start_coverage_index += end - start + 1; 41900b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com } 42000b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com 421eea48361b1ffcc1bded0ba25c8f747e634cd8e51ksakamoto@chromium.org if (expected_num_glyphs && 422eea48361b1ffcc1bded0ba25c8f747e634cd8e51ksakamoto@chromium.org expected_num_glyphs != last_start_coverage_index) { 423eea48361b1ffcc1bded0ba25c8f747e634cd8e51ksakamoto@chromium.org OTS_WARNING("unexpected number of glyphs: %u", last_start_coverage_index); 424eea48361b1ffcc1bded0ba25c8f747e634cd8e51ksakamoto@chromium.org return OTS_FAILURE(); 425eea48361b1ffcc1bded0ba25c8f747e634cd8e51ksakamoto@chromium.org } 426eea48361b1ffcc1bded0ba25c8f747e634cd8e51ksakamoto@chromium.org 42700b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com return true; 42800b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com} 42900b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com 430ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org// Parsers for Contextual subtables in GSUB/GPOS tables. 431ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 432ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.orgbool ParseLookupRecord(ots::Buffer *subtable, const uint16_t num_glyphs, 433ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t num_lookups) { 434ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t sequence_index = 0; 435ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t lookup_list_index = 0; 436ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable->ReadU16(&sequence_index) || 437ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org !subtable->ReadU16(&lookup_list_index)) { 438ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 439ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 440ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (sequence_index >= num_glyphs) { 441ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 442ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 443ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (lookup_list_index >= num_lookups) { 444ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 445ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 446ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return true; 447ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org} 448ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 449ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.orgbool ParseRuleSubtable(const uint8_t *data, const size_t length, 450ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t num_glyphs, 451ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t num_lookups) { 452ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org ots::Buffer subtable(data, length); 453ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 454ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t glyph_count = 0; 455ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t lookup_count = 0; 456ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.ReadU16(&glyph_count) || 457ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org !subtable.ReadU16(&lookup_count)) { 458ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 459ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 460ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 461ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (glyph_count == 0 || glyph_count >= num_glyphs) { 462ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 463ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 464ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org for (unsigned i = 0; i < glyph_count - static_cast<unsigned>(1); ++i) { 465ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t glyph_id = 0; 466ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.ReadU16(&glyph_id)) { 467ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 468ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 469ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (glyph_id > num_glyphs) { 470ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 471ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 472ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 473ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 474ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org for (unsigned i = 0; i < lookup_count; ++i) { 475ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!ParseLookupRecord(&subtable, num_glyphs, num_lookups)) { 476ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 477ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 478ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 479ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return true; 480ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org} 481ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 482ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.orgbool ParseRuleSetTable(const uint8_t *data, const size_t length, 483ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t num_glyphs, 484ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t num_lookups) { 485ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org ots::Buffer subtable(data, length); 486ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 487ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t rule_count = 0; 488ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.ReadU16(&rule_count)) { 489ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 490ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 49126afae8d52d90e194bad9876776d68bc3bb3a1adbashi@chromium.org const unsigned rule_end = 2 * static_cast<unsigned>(rule_count) + 2; 492ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (rule_end > std::numeric_limits<uint16_t>::max()) { 493ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 494ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 495ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 496ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org for (unsigned i = 0; i < rule_count; ++i) { 497ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t offset_rule = 0; 498ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.ReadU16(&offset_rule)) { 499ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 500ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 501ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (offset_rule < rule_end || offset_rule >= length) { 502ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 503ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 504ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!ParseRuleSubtable(data + offset_rule, length - offset_rule, 505ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org num_glyphs, num_lookups)) { 506ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 507ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 508ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 509ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 510ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return true; 511ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org} 512ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 513ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.orgbool ParseContextFormat1(const uint8_t *data, const size_t length, 514ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t num_glyphs, 515ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t num_lookups) { 516ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org ots::Buffer subtable(data, length); 517ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 518ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t offset_coverage = 0; 519ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t rule_set_count = 0; 520ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org // Skip format field. 521ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.Skip(2) || 522ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org !subtable.ReadU16(&offset_coverage) || 523ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org !subtable.ReadU16(&rule_set_count)) { 524ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 525ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 526ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 527ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const unsigned rule_set_end = static_cast<unsigned>(6) + 528ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org rule_set_count * 2; 529ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (rule_set_end > std::numeric_limits<uint16_t>::max()) { 530ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 531ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 532ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (offset_coverage < rule_set_end || offset_coverage >= length) { 533ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 534ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 535ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!ots::ParseCoverageTable(data + offset_coverage, 536ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org length - offset_coverage, num_glyphs)) { 537ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 538ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 539ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 540ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org for (unsigned i = 0; i < rule_set_count; ++i) { 541ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t offset_rule = 0; 542ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.ReadU16(&offset_rule)) { 543ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 544ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 545ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (offset_rule < rule_set_end || offset_rule >= length) { 546ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 547ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 548ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!ParseRuleSetTable(data + offset_rule, length - offset_rule, 549ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org num_glyphs, num_lookups)) { 550ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 551ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 552ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 553ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 554ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return true; 555ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org} 556ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 557ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.orgbool ParseClassRuleTable(const uint8_t *data, const size_t length, 558ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t num_glyphs, 559ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t num_lookups) { 560ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org ots::Buffer subtable(data, length); 561ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 562ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t glyph_count = 0; 563ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t lookup_count = 0; 564ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.ReadU16(&glyph_count) || 565ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org !subtable.ReadU16(&lookup_count)) { 566ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 567ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 568ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 569ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (glyph_count == 0 || glyph_count >= num_glyphs) { 570ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 571ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 572ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 573ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org // ClassRule table contains an array of classes. Each value of classes 574ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org // could take arbitrary values including zero so we don't check these value. 575ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const unsigned num_classes = glyph_count - static_cast<unsigned>(1); 576ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.Skip(2 * num_classes)) { 577ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 578ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 579ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 580ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org for (unsigned i = 0; i < lookup_count; ++i) { 581ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!ParseLookupRecord(&subtable, num_glyphs, num_lookups)) { 582ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 583ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 584ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 585ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return true; 586ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org} 587ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 588ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.orgbool ParseClassSetTable(const uint8_t *data, const size_t length, 589ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t num_glyphs, 590ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t num_lookups) { 591ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org ots::Buffer subtable(data, length); 592ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 593ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t class_rule_count = 0; 594ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.ReadU16(&class_rule_count)) { 595ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 596ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 59726afae8d52d90e194bad9876776d68bc3bb3a1adbashi@chromium.org const unsigned class_rule_end = 59826afae8d52d90e194bad9876776d68bc3bb3a1adbashi@chromium.org 2 * static_cast<unsigned>(class_rule_count) + 2; 599ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (class_rule_end > std::numeric_limits<uint16_t>::max()) { 600ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 601ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 602ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org for (unsigned i = 0; i < class_rule_count; ++i) { 603ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t offset_class_rule = 0; 604ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.ReadU16(&offset_class_rule)) { 605ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 606ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 607ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (offset_class_rule < class_rule_end || offset_class_rule >= length) { 608ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 609ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 610ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!ParseClassRuleTable(data + offset_class_rule, 611ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org length - offset_class_rule, num_glyphs, 612ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org num_lookups)) { 613ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 614ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 615ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 616ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 617ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return true; 618ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org} 619ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 620ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.orgbool ParseContextFormat2(const uint8_t *data, const size_t length, 621ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t num_glyphs, 622ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t num_lookups) { 623ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org ots::Buffer subtable(data, length); 624ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 625ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t offset_coverage = 0; 626ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t offset_class_def = 0; 627ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t class_set_cnt = 0; 628ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org // Skip format field. 629ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.Skip(2) || 630ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org !subtable.ReadU16(&offset_coverage) || 631ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org !subtable.ReadU16(&offset_class_def) || 632ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org !subtable.ReadU16(&class_set_cnt)) { 633ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 634ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 635ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 63626afae8d52d90e194bad9876776d68bc3bb3a1adbashi@chromium.org const unsigned class_set_end = 2 * static_cast<unsigned>(class_set_cnt) + 8; 637ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (class_set_end > std::numeric_limits<uint16_t>::max()) { 638ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 639ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 640ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (offset_coverage < class_set_end || offset_coverage >= length) { 641ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 642ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 643ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!ots::ParseCoverageTable(data + offset_coverage, 644ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org length - offset_coverage, num_glyphs)) { 645ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 646ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 647ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 648ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (offset_class_def < class_set_end || offset_class_def >= length) { 649ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 650ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 651ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!ots::ParseClassDefTable(data + offset_class_def, 652ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org length - offset_class_def, 653ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org num_glyphs, kMaxClassDefValue)) { 654ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 655ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 656ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 657ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org for (unsigned i = 0; i < class_set_cnt; ++i) { 658ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t offset_class_rule = 0; 659ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.ReadU16(&offset_class_rule)) { 660ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 661ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 662ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (offset_class_rule) { 663ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (offset_class_rule < class_set_end || offset_class_rule >= length) { 664ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 665ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 666ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!ParseClassSetTable(data + offset_class_rule, 667ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org length - offset_class_rule, num_glyphs, 668ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org num_lookups)) { 669ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 670ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 671ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 672ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 673ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 674ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return true; 675ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org} 676ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 677ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.orgbool ParseContextFormat3(const uint8_t *data, const size_t length, 678ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t num_glyphs, 679ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t num_lookups) { 680ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org ots::Buffer subtable(data, length); 681ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 682ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t glyph_count = 0; 683ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t lookup_count = 0; 684ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org // Skip format field. 685ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.Skip(2) || 686ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org !subtable.ReadU16(&glyph_count) || 687ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org !subtable.ReadU16(&lookup_count)) { 688ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 689ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 690ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 691ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (glyph_count >= num_glyphs) { 692ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 693ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 69426afae8d52d90e194bad9876776d68bc3bb3a1adbashi@chromium.org const unsigned lookup_record_end = 2 * static_cast<unsigned>(glyph_count) + 69526afae8d52d90e194bad9876776d68bc3bb3a1adbashi@chromium.org 4 * static_cast<unsigned>(lookup_count) + 6; 696ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (lookup_record_end > std::numeric_limits<uint16_t>::max()) { 697ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 698ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 699ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org for (unsigned i = 0; i < glyph_count; ++i) { 700ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t offset_coverage = 0; 701ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.ReadU16(&offset_coverage)) { 702ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 703ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 704ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (offset_coverage < lookup_record_end || offset_coverage >= length) { 705ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 706ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 707ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!ots::ParseCoverageTable(data + offset_coverage, 708ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org length - offset_coverage, num_glyphs)) { 709ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 710ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 711ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 712ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 713ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org for (unsigned i = 0; i < lookup_count; ++i) { 714ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!ParseLookupRecord(&subtable, num_glyphs, num_lookups)) { 715ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 716ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 717ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 718ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 719ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return true; 720ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org} 721ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 722ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org// Parsers for Chaning Contextual subtables in GSUB/GPOS tables. 723ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 724ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.orgbool ParseChainRuleSubtable(const uint8_t *data, const size_t length, 725ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t num_glyphs, 726ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t num_lookups) { 727ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org ots::Buffer subtable(data, length); 728ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 729ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t backtrack_count = 0; 730ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.ReadU16(&backtrack_count)) { 731ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 732ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 733ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (backtrack_count >= num_glyphs) { 734ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 735ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 736ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org for (unsigned i = 0; i < backtrack_count; ++i) { 737ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t glyph_id = 0; 738ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.ReadU16(&glyph_id)) { 739ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 740ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 741ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (glyph_id > num_glyphs) { 742ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 743ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 744ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 745ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 746ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t input_count = 0; 747ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.ReadU16(&input_count)) { 748ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 749ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 750ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (input_count == 0 || input_count >= num_glyphs) { 751ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 752ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 753ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org for (unsigned i = 0; i < input_count - static_cast<unsigned>(1); ++i) { 754ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t glyph_id = 0; 755ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.ReadU16(&glyph_id)) { 756ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 757ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 758ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (glyph_id > num_glyphs) { 759ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 760ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 761ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 762ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 763ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t lookahead_count = 0; 764ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.ReadU16(&lookahead_count)) { 765ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 766ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 767ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (lookahead_count >= num_glyphs) { 768ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 769ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 770ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org for (unsigned i = 0; i < lookahead_count; ++i) { 771ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t glyph_id = 0; 772ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.ReadU16(&glyph_id)) { 773ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 774ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 775ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (glyph_id > num_glyphs) { 776ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 777ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 778ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 779ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 780ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t lookup_count = 0; 781ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.ReadU16(&lookup_count)) { 782ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 783ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 784ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org for (unsigned i = 0; i < lookup_count; ++i) { 785ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!ParseLookupRecord(&subtable, num_glyphs, num_lookups)) { 786ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 787ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 788ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 789ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 790ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return true; 791ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org} 792ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 793ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.orgbool ParseChainRuleSetTable(const uint8_t *data, const size_t length, 794ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t num_glyphs, 795ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t num_lookups) { 796ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org ots::Buffer subtable(data, length); 797ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 798ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t chain_rule_count = 0; 799ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.ReadU16(&chain_rule_count)) { 800ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 801ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 80226afae8d52d90e194bad9876776d68bc3bb3a1adbashi@chromium.org const unsigned chain_rule_end = 80326afae8d52d90e194bad9876776d68bc3bb3a1adbashi@chromium.org 2 * static_cast<unsigned>(chain_rule_count) + 2; 804ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (chain_rule_end > std::numeric_limits<uint16_t>::max()) { 805ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 806ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 807ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org for (unsigned i = 0; i < chain_rule_count; ++i) { 808ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t offset_chain_rule = 0; 809ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.ReadU16(&offset_chain_rule)) { 810ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 811ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 812ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (offset_chain_rule < chain_rule_end || offset_chain_rule >= length) { 813ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 814ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 815ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!ParseChainRuleSubtable(data + offset_chain_rule, 816ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org length - offset_chain_rule, 817ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org num_glyphs, num_lookups)) { 818ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 819ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 820ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 821ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 822ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return true; 823ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org} 824ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 825ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.orgbool ParseChainContextFormat1(const uint8_t *data, const size_t length, 826ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t num_glyphs, 827ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t num_lookups) { 828ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org ots::Buffer subtable(data, length); 829ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 830ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t offset_coverage = 0; 831ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t chain_rule_set_count = 0; 832ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org // Skip format field. 833ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.Skip(2) || 834ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org !subtable.ReadU16(&offset_coverage) || 835ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org !subtable.ReadU16(&chain_rule_set_count)) { 836ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 837ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 838ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 83926afae8d52d90e194bad9876776d68bc3bb3a1adbashi@chromium.org const unsigned chain_rule_set_end = 84026afae8d52d90e194bad9876776d68bc3bb3a1adbashi@chromium.org 2 * static_cast<unsigned>(chain_rule_set_count) + 6; 841ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (chain_rule_set_end > std::numeric_limits<uint16_t>::max()) { 842ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 843ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 844ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (offset_coverage < chain_rule_set_end || offset_coverage >= length) { 845ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 846ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 847ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!ots::ParseCoverageTable(data + offset_coverage, 848ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org length - offset_coverage, num_glyphs)) { 849ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 850ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 851ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 852ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org for (unsigned i = 0; i < chain_rule_set_count; ++i) { 853ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t offset_chain_rule_set = 0; 854ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.ReadU16(&offset_chain_rule_set)) { 855ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 856ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 857ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (offset_chain_rule_set < chain_rule_set_end || 858ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org offset_chain_rule_set >= length) { 859ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 860ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 861ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!ParseChainRuleSetTable(data + offset_chain_rule_set, 862ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org length - offset_chain_rule_set, 863ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org num_glyphs, num_lookups)) { 864ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 865ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 866ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 867ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 868ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return true; 869ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org} 870ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 871ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.orgbool ParseChainClassRuleSubtable(const uint8_t *data, const size_t length, 872ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t num_glyphs, 873ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t num_lookups) { 874ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org ots::Buffer subtable(data, length); 875ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 876ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org // In this subtable, we don't check the value of classes for now since 877ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org // these could take arbitrary values. 878ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 879ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t backtrack_count = 0; 880ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.ReadU16(&backtrack_count)) { 881ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 882ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 883ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (backtrack_count >= num_glyphs) { 884ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 885ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 886ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.Skip(2 * backtrack_count)) { 887ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 888ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 889ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 890ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t input_count = 0; 891ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.ReadU16(&input_count)) { 892ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 893ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 894ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (input_count == 0 || input_count >= num_glyphs) { 895ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 896ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 897ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.Skip(2 * (input_count - 1))) { 898ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 899ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 900ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 901ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t lookahead_count = 0; 902ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.ReadU16(&lookahead_count)) { 903ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 904ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 905ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (lookahead_count >= num_glyphs) { 906ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 907ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 908ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.Skip(2 * lookahead_count)) { 909ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 910ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 911ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 912ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t lookup_count = 0; 913ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.ReadU16(&lookup_count)) { 914ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 915ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 916ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org for (unsigned i = 0; i < lookup_count; ++i) { 917ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!ParseLookupRecord(&subtable, num_glyphs, num_lookups)) { 918ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 919ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 920ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 921ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 922ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return true; 923ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org} 924ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 925ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.orgbool ParseChainClassSetTable(const uint8_t *data, const size_t length, 926ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t num_glyphs, 927ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t num_lookups) { 928ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org ots::Buffer subtable(data, length); 929ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 930ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t chain_class_rule_count = 0; 931ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.ReadU16(&chain_class_rule_count)) { 932ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 933ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 93426afae8d52d90e194bad9876776d68bc3bb3a1adbashi@chromium.org const unsigned chain_class_rule_end = 93526afae8d52d90e194bad9876776d68bc3bb3a1adbashi@chromium.org 2 * static_cast<unsigned>(chain_class_rule_count) + 2; 936ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (chain_class_rule_end > std::numeric_limits<uint16_t>::max()) { 937ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 938ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 939ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org for (unsigned i = 0; i < chain_class_rule_count; ++i) { 940ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t offset_chain_class_rule = 0; 941ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.ReadU16(&offset_chain_class_rule)) { 942ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 943ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 944ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (offset_chain_class_rule < chain_class_rule_end || 945ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org offset_chain_class_rule >= length) { 946ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 947ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 948ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!ParseChainClassRuleSubtable(data + offset_chain_class_rule, 949ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org length - offset_chain_class_rule, 950ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org num_glyphs, num_lookups)) { 951ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 952ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 953ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 954ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 955ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return true; 956ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org} 957ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 958ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.orgbool ParseChainContextFormat2(const uint8_t *data, const size_t length, 959ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t num_glyphs, 960ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t num_lookups) { 961ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org ots::Buffer subtable(data, length); 962ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 963ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t offset_coverage = 0; 964ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t offset_backtrack_class_def = 0; 965ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t offset_input_class_def = 0; 966ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t offset_lookahead_class_def = 0; 967ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t chain_class_set_count = 0; 968ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org // Skip format field. 969ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.Skip(2) || 970ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org !subtable.ReadU16(&offset_coverage) || 971ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org !subtable.ReadU16(&offset_backtrack_class_def) || 972ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org !subtable.ReadU16(&offset_input_class_def) || 973ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org !subtable.ReadU16(&offset_lookahead_class_def) || 974ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org !subtable.ReadU16(&chain_class_set_count)) { 975ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 976ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 977ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 97826afae8d52d90e194bad9876776d68bc3bb3a1adbashi@chromium.org const unsigned chain_class_set_end = 97926afae8d52d90e194bad9876776d68bc3bb3a1adbashi@chromium.org 2 * static_cast<unsigned>(chain_class_set_count) + 12; 980ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (chain_class_set_end > std::numeric_limits<uint16_t>::max()) { 981ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 982ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 983ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (offset_coverage < chain_class_set_end || offset_coverage >= length) { 984ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 985ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 986ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!ots::ParseCoverageTable(data + offset_coverage, 987ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org length - offset_coverage, num_glyphs)) { 988ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 989ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 990ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 991ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org // Classes for backtrack/lookahead sequences might not be defined. 992ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (offset_backtrack_class_def) { 993ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (offset_backtrack_class_def < chain_class_set_end || 994ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org offset_backtrack_class_def >= length) { 995ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 996ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 997ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!ots::ParseClassDefTable(data + offset_backtrack_class_def, 998ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org length - offset_backtrack_class_def, 999ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org num_glyphs, kMaxClassDefValue)) { 1000ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1001ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1002ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1003ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 1004ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (offset_input_class_def < chain_class_set_end || 1005ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org offset_input_class_def >= length) { 1006ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1007ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1008ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!ots::ParseClassDefTable(data + offset_input_class_def, 1009ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org length - offset_input_class_def, 1010ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org num_glyphs, kMaxClassDefValue)) { 1011ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1012ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1013ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 1014ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (offset_lookahead_class_def) { 1015ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (offset_lookahead_class_def < chain_class_set_end || 1016ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org offset_lookahead_class_def >= length) { 1017ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1018ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1019ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!ots::ParseClassDefTable(data + offset_lookahead_class_def, 1020ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org length - offset_lookahead_class_def, 1021ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org num_glyphs, kMaxClassDefValue)) { 1022ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1023ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1024ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1025ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 1026ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org for (unsigned i = 0; i < chain_class_set_count; ++i) { 1027ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t offset_chain_class_set = 0; 1028ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.ReadU16(&offset_chain_class_set)) { 1029ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1030ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1031ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org // |offset_chain_class_set| could be NULL. 1032ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (offset_chain_class_set) { 1033ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (offset_chain_class_set < chain_class_set_end || 1034ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org offset_chain_class_set >= length) { 1035ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1036ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1037ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!ParseChainClassSetTable(data + offset_chain_class_set, 1038ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org length - offset_chain_class_set, 1039ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org num_glyphs, num_lookups)) { 1040ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1041ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1042ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1043ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1044ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 1045ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return true; 1046ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org} 1047ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 1048ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.orgbool ParseChainContextFormat3(const uint8_t *data, const size_t length, 1049ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t num_glyphs, 1050ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t num_lookups) { 1051ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org ots::Buffer subtable(data, length); 1052ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 1053ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t backtrack_count = 0; 1054ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org // Skip format field. 1055ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.Skip(2) || 1056ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org !subtable.ReadU16(&backtrack_count)) { 1057ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1058ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1059ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 1060ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (backtrack_count >= num_glyphs) { 1061ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1062ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1063ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org std::vector<uint16_t> offsets_backtrack; 1064ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org offsets_backtrack.reserve(backtrack_count); 1065ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org for (unsigned i = 0; i < backtrack_count; ++i) { 1066e2b566a774d999486a3d0388a9995aca63dcf46bbashi@chromium.org uint16_t offset = 0; 1067e2b566a774d999486a3d0388a9995aca63dcf46bbashi@chromium.org if (!subtable.ReadU16(&offset)) { 1068ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1069ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1070e2b566a774d999486a3d0388a9995aca63dcf46bbashi@chromium.org offsets_backtrack.push_back(offset); 1071ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 10726b41020e0a52fbc3a257a1b7652a0fcc92f6f9afbashi@chromium.org if (offsets_backtrack.size() != backtrack_count) { 10736b41020e0a52fbc3a257a1b7652a0fcc92f6f9afbashi@chromium.org return OTS_FAILURE(); 10746b41020e0a52fbc3a257a1b7652a0fcc92f6f9afbashi@chromium.org } 1075ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 1076ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t input_count = 0; 1077ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.ReadU16(&input_count)) { 1078ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1079ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1080ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (input_count >= num_glyphs) { 1081ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1082ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1083ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org std::vector<uint16_t> offsets_input; 1084ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org offsets_input.reserve(input_count); 1085ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org for (unsigned i = 0; i < input_count; ++i) { 1086e2b566a774d999486a3d0388a9995aca63dcf46bbashi@chromium.org uint16_t offset = 0; 1087e2b566a774d999486a3d0388a9995aca63dcf46bbashi@chromium.org if (!subtable.ReadU16(&offset)) { 1088ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1089ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1090e2b566a774d999486a3d0388a9995aca63dcf46bbashi@chromium.org offsets_input.push_back(offset); 1091ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 10926b41020e0a52fbc3a257a1b7652a0fcc92f6f9afbashi@chromium.org if (offsets_input.size() != input_count) { 10936b41020e0a52fbc3a257a1b7652a0fcc92f6f9afbashi@chromium.org return OTS_FAILURE(); 10946b41020e0a52fbc3a257a1b7652a0fcc92f6f9afbashi@chromium.org } 1095ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 1096ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t lookahead_count = 0; 1097ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.ReadU16(&lookahead_count)) { 1098ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1099ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1100ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (lookahead_count >= num_glyphs) { 1101ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1102ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1103ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org std::vector<uint16_t> offsets_lookahead; 1104ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org offsets_lookahead.reserve(lookahead_count); 1105ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org for (unsigned i = 0; i < lookahead_count; ++i) { 1106e2b566a774d999486a3d0388a9995aca63dcf46bbashi@chromium.org uint16_t offset = 0; 1107e2b566a774d999486a3d0388a9995aca63dcf46bbashi@chromium.org if (!subtable.ReadU16(&offset)) { 1108ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1109ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1110e2b566a774d999486a3d0388a9995aca63dcf46bbashi@chromium.org offsets_lookahead.push_back(offset); 1111ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 11126b41020e0a52fbc3a257a1b7652a0fcc92f6f9afbashi@chromium.org if (offsets_lookahead.size() != lookahead_count) { 11136b41020e0a52fbc3a257a1b7652a0fcc92f6f9afbashi@chromium.org return OTS_FAILURE(); 11146b41020e0a52fbc3a257a1b7652a0fcc92f6f9afbashi@chromium.org } 1115ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 1116ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t lookup_count = 0; 1117ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.ReadU16(&lookup_count)) { 1118ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1119ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1120ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org for (unsigned i = 0; i < lookup_count; ++i) { 1121ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!ParseLookupRecord(&subtable, num_glyphs, num_lookups)) { 1122ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1123ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1124ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1125ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 112626afae8d52d90e194bad9876776d68bc3bb3a1adbashi@chromium.org const unsigned lookup_record_end = 112726afae8d52d90e194bad9876776d68bc3bb3a1adbashi@chromium.org 2 * (static_cast<unsigned>(backtrack_count) + 112826afae8d52d90e194bad9876776d68bc3bb3a1adbashi@chromium.org static_cast<unsigned>(input_count) + 112926afae8d52d90e194bad9876776d68bc3bb3a1adbashi@chromium.org static_cast<unsigned>(lookahead_count)) + 113026afae8d52d90e194bad9876776d68bc3bb3a1adbashi@chromium.org 4 * static_cast<unsigned>(lookup_count) + 10; 1131ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (lookup_record_end > std::numeric_limits<uint16_t>::max()) { 1132ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1133ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1134ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org for (unsigned i = 0; i < backtrack_count; ++i) { 1135ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (offsets_backtrack[i] < lookup_record_end || 1136ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org offsets_backtrack[i] >= length) { 1137ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1138ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1139ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!ots::ParseCoverageTable(data + offsets_backtrack[i], 1140ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org length - offsets_backtrack[i], num_glyphs)) { 1141ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1142ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1143ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1144ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org for (unsigned i = 0; i < input_count; ++i) { 1145ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (offsets_input[i] < lookup_record_end || offsets_input[i] >= length) { 1146ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1147ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1148ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!ots::ParseCoverageTable(data + offsets_input[i], 1149ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org length - offsets_input[i], num_glyphs)) { 1150ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1151ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1152ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1153ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org for (unsigned i = 0; i < lookahead_count; ++i) { 1154ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (offsets_lookahead[i] < lookup_record_end || 1155ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org offsets_lookahead[i] >= length) { 1156ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1157ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1158ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!ots::ParseCoverageTable(data + offsets_lookahead[i], 1159ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org length - offsets_lookahead[i], num_glyphs)) { 1160ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1161ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1162ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1163ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 1164ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return true; 1165ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org} 1166ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 116700b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com} // namespace 116800b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com 116900b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.comnamespace ots { 117000b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com 1171ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.orgbool LookupSubtableParser::Parse(const OpenTypeFile *file, const uint8_t *data, 1172ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const size_t length, 1173ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t lookup_type) const { 1174ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org for (unsigned i = 0; i < num_types; ++i) { 1175ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (parsers[i].type == lookup_type && parsers[i].parse) { 1176ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!parsers[i].parse(file, data, length)) { 1177ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1178ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1179ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return true; 1180ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1181ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1182ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1183ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org} 1184ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 118578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com// Parsing ScriptListTable requires number of features so we need to 118678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com// parse FeatureListTable before calling this function. 118778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.combool ParseScriptListTable(const uint8_t *data, const size_t length, 118878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com const uint16_t num_features) { 118978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com Buffer subtable(data, length); 119078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 119178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com uint16_t script_count = 0; 119278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (!subtable.ReadU16(&script_count)) { 119378a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 119478a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 119578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 119626afae8d52d90e194bad9876776d68bc3bb3a1adbashi@chromium.org const unsigned script_record_end = 119726afae8d52d90e194bad9876776d68bc3bb3a1adbashi@chromium.org 6 * static_cast<unsigned>(script_count) + 2; 119878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (script_record_end > std::numeric_limits<uint16_t>::max()) { 119978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 120078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 120178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com std::vector<ScriptRecord> script_list; 120278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com script_list.reserve(script_count); 120378a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com uint32_t last_tag = 0; 120478a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com for (unsigned i = 0; i < script_count; ++i) { 1205e2b566a774d999486a3d0388a9995aca63dcf46bbashi@chromium.org ScriptRecord record; 1206e2b566a774d999486a3d0388a9995aca63dcf46bbashi@chromium.org if (!subtable.ReadU32(&record.tag) || 1207e2b566a774d999486a3d0388a9995aca63dcf46bbashi@chromium.org !subtable.ReadU16(&record.offset)) { 120878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 120978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 121078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com // Script tags should be arranged alphabetically by tag 1211e2b566a774d999486a3d0388a9995aca63dcf46bbashi@chromium.org if (last_tag != 0 && last_tag > record.tag) { 1212a574866c0e4b1539098e64422f59d01c80cea6cfbashi@chromium.org // Several fonts don't arrange tags alphabetically. 1213a574866c0e4b1539098e64422f59d01c80cea6cfbashi@chromium.org // It seems that the order of tags might not be a security issue 1214a574866c0e4b1539098e64422f59d01c80cea6cfbashi@chromium.org // so we just warn it. 1215a574866c0e4b1539098e64422f59d01c80cea6cfbashi@chromium.org OTS_WARNING("tags aren't arranged alphabetically."); 121678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 1217e2b566a774d999486a3d0388a9995aca63dcf46bbashi@chromium.org last_tag = record.tag; 1218e2b566a774d999486a3d0388a9995aca63dcf46bbashi@chromium.org if (record.offset < script_record_end || record.offset >= length) { 121978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 122078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 1221e2b566a774d999486a3d0388a9995aca63dcf46bbashi@chromium.org script_list.push_back(record); 122278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 12236b41020e0a52fbc3a257a1b7652a0fcc92f6f9afbashi@chromium.org if (script_list.size() != script_count) { 12246b41020e0a52fbc3a257a1b7652a0fcc92f6f9afbashi@chromium.org return OTS_FAILURE(); 12256b41020e0a52fbc3a257a1b7652a0fcc92f6f9afbashi@chromium.org } 122678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 122778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com // Check script records. 122878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com for (unsigned i = 0; i < script_count; ++i) { 122978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (!ParseScriptTable(data + script_list[i].offset, 123078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com length - script_list[i].offset, 123178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com script_list[i].tag, num_features)) { 123278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 123378a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 123478a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 123578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 123678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return true; 123778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com} 123878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 123978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com// Parsing FeatureListTable requires number of lookups so we need to parse 124078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com// LookupListTable before calling this function. 124178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.combool ParseFeatureListTable(const uint8_t *data, const size_t length, 124278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com const uint16_t num_lookups, 124378a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com uint16_t* num_features) { 124478a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com Buffer subtable(data, length); 124578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 124678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com uint16_t feature_count = 0; 124778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (!subtable.ReadU16(&feature_count)) { 124878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 124978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 125078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 125178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com std::vector<FeatureRecord> feature_records; 125278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com feature_records.resize(feature_count); 125326afae8d52d90e194bad9876776d68bc3bb3a1adbashi@chromium.org const unsigned feature_record_end = 125426afae8d52d90e194bad9876776d68bc3bb3a1adbashi@chromium.org 6 * static_cast<unsigned>(feature_count) + 2; 125578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (feature_record_end > std::numeric_limits<uint16_t>::max()) { 125678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 125778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 125878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com uint32_t last_tag = 0; 125978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com for (unsigned i = 0; i < feature_count; ++i) { 126078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (!subtable.ReadU32(&feature_records[i].tag) || 126178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com !subtable.ReadU16(&feature_records[i].offset)) { 126278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 126378a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 126478a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com // Feature record array should be arranged alphabetically by tag 126578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (last_tag != 0 && last_tag > feature_records[i].tag) { 1266a574866c0e4b1539098e64422f59d01c80cea6cfbashi@chromium.org // Several fonts don't arrange tags alphabetically. 1267a574866c0e4b1539098e64422f59d01c80cea6cfbashi@chromium.org // It seems that the order of tags might not be a security issue 1268a574866c0e4b1539098e64422f59d01c80cea6cfbashi@chromium.org // so we just warn it. 1269a574866c0e4b1539098e64422f59d01c80cea6cfbashi@chromium.org OTS_WARNING("tags aren't arranged alphabetically."); 127078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 127178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com last_tag = feature_records[i].tag; 127278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (feature_records[i].offset < feature_record_end || 127378a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com feature_records[i].offset >= length) { 127478a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 127578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 127678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 127778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 127878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com for (unsigned i = 0; i < feature_count; ++i) { 127978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (!ParseFeatureTable(data + feature_records[i].offset, 128078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com length - feature_records[i].offset, num_lookups)) { 128178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 128278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 128378a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 128478a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com *num_features = feature_count; 128578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return true; 128678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com} 128778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 128878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com// For parsing GPOS/GSUB tables, this function should be called at first to 128978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com// obtain the number of lookups because parsing FeatureTableList requires 129078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com// the number. 129178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.combool ParseLookupListTable(OpenTypeFile *file, const uint8_t *data, 1292ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const size_t length, 1293ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const LookupSubtableParser* parser, 129478a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com uint16_t *num_lookups) { 129578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com Buffer subtable(data, length); 129678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 129778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (!subtable.ReadU16(num_lookups)) { 129878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 129978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 130078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 130178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com std::vector<uint16_t> lookups; 130278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com lookups.reserve(*num_lookups); 130326afae8d52d90e194bad9876776d68bc3bb3a1adbashi@chromium.org const unsigned lookup_end = 130426afae8d52d90e194bad9876776d68bc3bb3a1adbashi@chromium.org 2 * static_cast<unsigned>(*num_lookups) + 2; 130578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (lookup_end > std::numeric_limits<uint16_t>::max()) { 130678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 130778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 130878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com for (unsigned i = 0; i < *num_lookups; ++i) { 1309e2b566a774d999486a3d0388a9995aca63dcf46bbashi@chromium.org uint16_t offset = 0; 1310e2b566a774d999486a3d0388a9995aca63dcf46bbashi@chromium.org if (!subtable.ReadU16(&offset)) { 131178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 131278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 1313e2b566a774d999486a3d0388a9995aca63dcf46bbashi@chromium.org if (offset < lookup_end || offset >= length) { 131478a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 131578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 1316e2b566a774d999486a3d0388a9995aca63dcf46bbashi@chromium.org lookups.push_back(offset); 131778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 13186b41020e0a52fbc3a257a1b7652a0fcc92f6f9afbashi@chromium.org if (lookups.size() != *num_lookups) { 13196b41020e0a52fbc3a257a1b7652a0fcc92f6f9afbashi@chromium.org return OTS_FAILURE(); 13206b41020e0a52fbc3a257a1b7652a0fcc92f6f9afbashi@chromium.org } 132178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 132278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com for (unsigned i = 0; i < *num_lookups; ++i) { 132378a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (!ParseLookupTable(file, data + lookups[i], length - lookups[i], 1324ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org parser)) { 132578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 132678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 132778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 132878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 132978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return true; 133078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com} 133178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 133200b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.combool ParseClassDefTable(const uint8_t *data, size_t length, 133300b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com const uint16_t num_glyphs, 133400b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com const uint16_t num_classes) { 133500b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com Buffer subtable(data, length); 133600b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com 133700b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com uint16_t format = 0; 133800b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com if (!subtable.ReadU16(&format)) { 133900b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com return OTS_FAILURE(); 134000b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com } 134100b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com if (format == 1) { 134200b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com return ParseClassDefFormat1(data, length, num_glyphs, num_classes); 134300b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com } else if (format == 2) { 134400b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com return ParseClassDefFormat2(data, length, num_glyphs, num_classes); 134500b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com } 134600b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com 134700b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com return OTS_FAILURE(); 134800b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com} 134900b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com 135000b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.combool ParseCoverageTable(const uint8_t *data, size_t length, 1351eea48361b1ffcc1bded0ba25c8f747e634cd8e51ksakamoto@chromium.org const uint16_t num_glyphs, 1352eea48361b1ffcc1bded0ba25c8f747e634cd8e51ksakamoto@chromium.org const uint16_t expected_num_glyphs) { 135300b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com Buffer subtable(data, length); 135400b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com 135500b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com uint16_t format = 0; 135600b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com if (!subtable.ReadU16(&format)) { 135700b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com return OTS_FAILURE(); 135800b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com } 135900b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com if (format == 1) { 1360eea48361b1ffcc1bded0ba25c8f747e634cd8e51ksakamoto@chromium.org return ParseCoverageFormat1(data, length, num_glyphs, expected_num_glyphs); 136100b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com } else if (format == 2) { 1362eea48361b1ffcc1bded0ba25c8f747e634cd8e51ksakamoto@chromium.org return ParseCoverageFormat2(data, length, num_glyphs, expected_num_glyphs); 136300b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com } 136400b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com 136500b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com return OTS_FAILURE(); 136600b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com} 136700b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com 136878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.combool ParseDeviceTable(const uint8_t *data, size_t length) { 136978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com Buffer subtable(data, length); 137078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 137178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com uint16_t start_size = 0; 137278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com uint16_t end_size = 0; 137378a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com uint16_t delta_format = 0; 137478a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (!subtable.ReadU16(&start_size) || 137578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com !subtable.ReadU16(&end_size) || 137678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com !subtable.ReadU16(&delta_format)) { 137778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 137878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 137978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (start_size > end_size) { 138078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com OTS_WARNING("bad size range: %u > %u", start_size, end_size); 138178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 138278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 138378a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (delta_format == 0 || delta_format > kMaxDeltaFormatType) { 138478a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com OTS_WARNING("bad delta format: %u", delta_format); 138578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 138678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 138778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com // The number of delta values per uint16. The device table should contain 138878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com // at least |num_units| * 2 bytes compressed data. 138978a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com const unsigned num_units = (end_size - start_size) / 139078a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com (1 << (4 - delta_format)) + 1; 139178a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com // Just skip |num_units| * 2 bytes since the compressed data could take 139278a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com // arbitrary values. 139378a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com if (!subtable.Skip(num_units * 2)) { 139478a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return OTS_FAILURE(); 139578a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com } 139678a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com return true; 139778a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com} 139878a8baafff49244c7f9427ad72115ff1ad28e310bashi@google.com 1399ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.orgbool ParseContextSubtable(const uint8_t *data, const size_t length, 1400ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t num_glyphs, 1401ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t num_lookups) { 1402ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org Buffer subtable(data, length); 1403ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 1404ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t format = 0; 1405ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.ReadU16(&format)) { 1406ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1407ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1408ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 1409ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (format == 1) { 1410ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!ParseContextFormat1(data, length, num_glyphs, num_lookups)) { 1411ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1412ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1413ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } else if (format == 2) { 1414ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!ParseContextFormat2(data, length, num_glyphs, num_lookups)) { 1415ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1416ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1417ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } else if (format == 3) { 1418ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!ParseContextFormat3(data, length, num_glyphs, num_lookups)) { 1419ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1420ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1421ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } else { 1422ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1423ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1424ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 1425ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return true; 1426ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org} 1427ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 1428ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.orgbool ParseChainingContextSubtable(const uint8_t *data, const size_t length, 1429ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t num_glyphs, 1430ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint16_t num_lookups) { 1431ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org Buffer subtable(data, length); 1432ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 1433ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t format = 0; 1434ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.ReadU16(&format)) { 1435ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1436ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1437ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 1438ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (format == 1) { 1439ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!ParseChainContextFormat1(data, length, num_glyphs, num_lookups)) { 1440ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1441ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1442ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } else if (format == 2) { 1443ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!ParseChainContextFormat2(data, length, num_glyphs, num_lookups)) { 1444ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1445ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1446ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } else if (format == 3) { 1447ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!ParseChainContextFormat3(data, length, num_glyphs, num_lookups)) { 1448ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1449ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1450ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } else { 1451ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1452ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1453ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 1454ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return true; 1455ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org} 1456ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 1457ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.orgbool ParseExtensionSubtable(const OpenTypeFile *file, 1458ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const uint8_t *data, const size_t length, 1459ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const LookupSubtableParser* parser) { 1460ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org Buffer subtable(data, length); 1461ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 1462ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t format = 0; 1463ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint16_t lookup_type = 0; 1464ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org uint32_t offset_extension = 0; 1465ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!subtable.ReadU16(&format) || 1466ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org !subtable.ReadU16(&lookup_type) || 1467ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org !subtable.ReadU32(&offset_extension)) { 1468ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1469ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1470ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 1471ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (format != 1) { 1472ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1473ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1474ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org // |lookup_type| should be other than |parser->extension_type|. 1475ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (lookup_type < 1 || lookup_type > parser->num_types || 1476ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org lookup_type == parser->extension_type) { 1477ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1478ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1479ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 1480ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org const unsigned format_end = static_cast<unsigned>(8); 1481ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (offset_extension < format_end || 1482ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org offset_extension >= length) { 1483ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1484ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1485ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 1486ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org // Parse the extension subtable of |lookup_type|. 1487ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org if (!parser->Parse(file, data + offset_extension, length - offset_extension, 1488ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org lookup_type)) { 1489ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return OTS_FAILURE(); 1490ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org } 1491ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 1492ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org return true; 1493ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org} 1494ced7112cb41d09cd344bbe4b20459049d6039491bashi@chromium.org 149500b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com} // namespace ots 149600b790a7ad0d65b066a61760f58e7dbfc055cd2dbashi@google.com 1497