diff options
author | wolfbeast <mcwerewolf@wolfbeast.com> | 2019-11-14 10:07:01 +0100 |
---|---|---|
committer | wolfbeast <mcwerewolf@wolfbeast.com> | 2019-11-14 10:07:01 +0100 |
commit | 0f8691a48869932cd3de5195f5211c25e4691b21 (patch) | |
tree | 829675d64c457be0b447dfbcf9534cc22f83d392 /gfx/ots/src/mvar.cc | |
parent | 36975f3865948f3faa959fe386e58b22783bd379 (diff) | |
download | UXP-0f8691a48869932cd3de5195f5211c25e4691b21.tar UXP-0f8691a48869932cd3de5195f5211c25e4691b21.tar.gz UXP-0f8691a48869932cd3de5195f5211c25e4691b21.tar.lz UXP-0f8691a48869932cd3de5195f5211c25e4691b21.tar.xz UXP-0f8691a48869932cd3de5195f5211c25e4691b21.zip |
Issue #1288 - Part 4: Update the OpenType Sanitizer component to 8.0.0
Diffstat (limited to 'gfx/ots/src/mvar.cc')
-rw-r--r-- | gfx/ots/src/mvar.cc | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/gfx/ots/src/mvar.cc b/gfx/ots/src/mvar.cc new file mode 100644 index 000000000..d021203d3 --- /dev/null +++ b/gfx/ots/src/mvar.cc @@ -0,0 +1,105 @@ +// Copyright (c) 2018 The OTS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "mvar.h" + +#include "variations.h" + +namespace ots { + +// ----------------------------------------------------------------------------- +// OpenTypeMVAR +// ----------------------------------------------------------------------------- + +bool OpenTypeMVAR::Parse(const uint8_t* data, size_t length) { + Buffer table(data, length); + + uint16_t majorVersion; + uint16_t minorVersion; + uint16_t reserved; + uint16_t valueRecordSize; + uint16_t valueRecordCount; + uint16_t itemVariationStoreOffset; + + if (!table.ReadU16(&majorVersion) || + !table.ReadU16(&minorVersion) || + !table.ReadU16(&reserved) || + !table.ReadU16(&valueRecordSize) || + !table.ReadU16(&valueRecordCount) || + !table.ReadU16(&itemVariationStoreOffset)) { + return DropVariations("Failed to read table header"); + } + + if (majorVersion != 1) { + return DropVariations("Unknown table version"); + } + + if (reserved != 0) { + Warning("Expected reserved=0"); + } + + // The spec says that valueRecordSize "must be greater than zero", + // but we don't enforce this in the case where valueRecordCount + // is zero. + // The minimum size for a valueRecord to be valid is 8, for the + // three fields currently defined in the record (see below). + if (valueRecordSize < 8) { + if (valueRecordCount != 0) { + return DropVariations("Value record size too small"); + } + } + + if (valueRecordCount == 0) { + if (itemVariationStoreOffset != 0) { + // The spec says "if valueRecordCount is zero, set to zero", + // but having a variation store even when record count is zero + // should be harmless -- it just won't be useful for anything. + // But we don't need to reject altogether. + Warning("Unexpected item variation store"); + } + } else { + if (itemVariationStoreOffset < table.offset() || itemVariationStoreOffset > length) { + return DropVariations("Invalid item variation store offset"); + } + if (!ParseItemVariationStore(GetFont(), data + itemVariationStoreOffset, + length - itemVariationStoreOffset)) { + return DropVariations("Failed to parse item variation store"); + } + } + + uint32_t prevTag = 0; + size_t offset = table.offset(); + for (unsigned i = 0; i < valueRecordCount; i++) { + uint32_t tag; + uint16_t deltaSetOuterIndex, deltaSetInnerIndex; + if (!table.ReadU32(&tag) || + !table.ReadU16(&deltaSetOuterIndex) || + !table.ReadU16(&deltaSetInnerIndex)) { + return DropVariations("Failed to read value record"); + } + if (tag <= prevTag) { + return DropVariations("Invalid or out-of-order value tag"); + } + prevTag = tag; + // Adjust offset in case additional fields have been added to the + // valueRecord by a new minor version (allowed by spec). + offset += valueRecordSize; + table.set_offset(offset); + } + + this->m_data = data; + this->m_length = length; + + return true; +} + +bool OpenTypeMVAR::Serialize(OTSStream* out) { + if (!out->Write(this->m_data, this->m_length)) { + return Error("Failed to write MVAR table"); + } + + return true; +} + +} // namespace ots |