mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Bug 1531912 - Update OTS to 7.1.9. r=jfkthame
Differential Revision: https://phabricator.services.mozilla.com/D21787 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
726416eba3
commit
92d11a3325
@ -2,7 +2,7 @@ This is the Sanitiser for OpenType project, from http://code.google.com/p/ots/.
|
||||
|
||||
Our reference repository is https://github.com/khaledhosny/ots/.
|
||||
|
||||
Current revision: b2d8733abf5b141f20881b071b68d2dbe73c5baf (7.1.7)
|
||||
Current revision: 3f26ef1579e2f5bc9627bd852952f42986ccf1af (7.1.9)
|
||||
|
||||
Upstream files included: LICENSE, src/, include/, tests/*.cc
|
||||
|
||||
|
@ -21,14 +21,10 @@
|
||||
|
||||
namespace {
|
||||
|
||||
// The maximum class value in class definition tables.
|
||||
const uint16_t kMaxClassDefValue = 0xFFFF;
|
||||
// The maximum class value in the glyph class definision table.
|
||||
const uint16_t kMaxGlyphClassDefValue = 4;
|
||||
// The maximum format number of caret value tables.
|
||||
// We don't support format 3 for now. See the comment in
|
||||
// ParseLigCaretListTable() for the reason.
|
||||
const uint16_t kMaxCaretValueFormat = 2;
|
||||
const uint16_t kMaxCaretValueFormat = 3;
|
||||
|
||||
} // namespace
|
||||
|
||||
@ -169,9 +165,6 @@ bool OpenTypeGDEF::ParseLigCaretListTable(const uint8_t *data, size_t length) {
|
||||
if (!subtable.ReadU16(&caret_format)) {
|
||||
return Error("Can't read caret values table %d in glyph %d", j, i);
|
||||
}
|
||||
// TODO(bashi): We only support caret value format 1 and 2 for now
|
||||
// because there are no fonts which contain caret value format 3
|
||||
// as far as we investigated.
|
||||
if (caret_format == 0 || caret_format > kMaxCaretValueFormat) {
|
||||
return Error("bad caret value format: %u", caret_format);
|
||||
}
|
||||
@ -180,6 +173,24 @@ bool OpenTypeGDEF::ParseLigCaretListTable(const uint8_t *data, size_t length) {
|
||||
if (!subtable.Skip(2)) {
|
||||
return Error("Bad caret value table structure %d in glyph %d", j, i);
|
||||
}
|
||||
if (caret_format == 3) {
|
||||
uint16_t offset_device = 0;
|
||||
if (!subtable.ReadU16(&offset_device)) {
|
||||
return Error("Can't read device offset for caret value %d "
|
||||
"in glyph %d", j, i);
|
||||
}
|
||||
uint16_t absolute_offset = lig_glyphs[i] + caret_value_offsets[j]
|
||||
+ offset_device;
|
||||
if (offset_device == 0 || absolute_offset >= length) {
|
||||
return Error("Bad device offset for caret value %d in glyph %d: %d",
|
||||
j, i, offset_device);
|
||||
}
|
||||
if (!ots::ParseDeviceTable(GetFont(), data + absolute_offset,
|
||||
length - absolute_offset)) {
|
||||
return Error("Bad device table for caret value %d in glyph %d",
|
||||
j, i, offset_device);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -106,8 +106,9 @@ bool OpenTypeGLYF::ParseSimpleGlyph(Buffer &glyph,
|
||||
|
||||
if (this->maxp->version_1 &&
|
||||
this->maxp->max_size_glyf_instructions < bytecode_length) {
|
||||
return Error("Bytecode length is bigger than maxp.maxSizeOfInstructions "
|
||||
"%d: %d", this->maxp->max_size_glyf_instructions, bytecode_length);
|
||||
this->maxp->max_size_glyf_instructions = bytecode_length;
|
||||
Warning("Bytecode length is bigger than maxp.maxSizeOfInstructions %d: %d",
|
||||
this->maxp->max_size_glyf_instructions, bytecode_length);
|
||||
}
|
||||
|
||||
if (!glyph.Skip(bytecode_length)) {
|
||||
@ -202,9 +203,10 @@ bool OpenTypeGLYF::ParseCompositeGlyph(Buffer &glyph) {
|
||||
|
||||
if (this->maxp->version_1 &&
|
||||
this->maxp->max_size_glyf_instructions < bytecode_length) {
|
||||
return Error("Bytecode length is bigger than maxp.maxSizeOfInstructions "
|
||||
"%d: %d",
|
||||
this->maxp->max_size_glyf_instructions, bytecode_length);
|
||||
this->maxp->max_size_glyf_instructions = bytecode_length;
|
||||
Warning("Bytecode length is bigger than maxp.maxSizeOfInstructions "
|
||||
"%d: %d",
|
||||
this->maxp->max_size_glyf_instructions, bytecode_length);
|
||||
}
|
||||
|
||||
if (!glyph.Skip(bytecode_length)) {
|
||||
|
@ -36,8 +36,6 @@ const unsigned kGposHeaderSize_1_0 = 10;
|
||||
const unsigned kGposHeaderSize_1_1 = 14;
|
||||
// The maximum format number for anchor tables.
|
||||
const uint16_t kMaxAnchorFormat = 3;
|
||||
// The maximum number of class value.
|
||||
const uint16_t kMaxClassDefValue = 0xFFFF;
|
||||
|
||||
// Lookup type parsers.
|
||||
bool ParseSingleAdjustment(const ots::Font *font,
|
||||
@ -395,12 +393,12 @@ bool ParsePairPosFormat2(const ots::Font *font,
|
||||
// Check class definition tables.
|
||||
if (!ots::ParseClassDefTable(font, data + offset_class_def1,
|
||||
length - offset_class_def1,
|
||||
num_glyphs, kMaxClassDefValue)) {
|
||||
num_glyphs, ots::kMaxClassDefValue)) {
|
||||
return OTS_FAILURE_MSG("Failed to parse class definition table 1");
|
||||
}
|
||||
if (!ots::ParseClassDefTable(font, data + offset_class_def2,
|
||||
length - offset_class_def2,
|
||||
num_glyphs, kMaxClassDefValue)) {
|
||||
num_glyphs, ots::kMaxClassDefValue)) {
|
||||
return OTS_FAILURE_MSG("Failed to parse class definition table 2");
|
||||
}
|
||||
|
||||
|
@ -30,8 +30,6 @@ const uint16_t kMaxDeltaFormatType = 3;
|
||||
// In variation fonts, Device Tables are replaced by VariationIndex tables,
|
||||
// indicated by this flag in the deltaFormat field.
|
||||
const uint16_t kVariationIndex = 0x8000;
|
||||
// The maximum number of class value.
|
||||
const uint16_t kMaxClassDefValue = 0xFFFF;
|
||||
|
||||
struct ScriptRecord {
|
||||
uint32_t tag;
|
||||
@ -647,7 +645,7 @@ bool ParseContextFormat2(const ots::Font *font,
|
||||
}
|
||||
if (!ots::ParseClassDefTable(font, data + offset_class_def,
|
||||
length - offset_class_def,
|
||||
num_glyphs, kMaxClassDefValue)) {
|
||||
num_glyphs, ots::kMaxClassDefValue)) {
|
||||
return OTS_FAILURE_MSG("Failed to parse class definition table in context format 2");
|
||||
}
|
||||
|
||||
@ -1000,7 +998,7 @@ bool ParseChainContextFormat2(const ots::Font *font,
|
||||
}
|
||||
if (!ots::ParseClassDefTable(font, data + offset_backtrack_class_def,
|
||||
length - offset_backtrack_class_def,
|
||||
num_glyphs, kMaxClassDefValue)) {
|
||||
num_glyphs, ots::kMaxClassDefValue)) {
|
||||
return OTS_FAILURE_MSG("Failed to parse backtrack class defn table in chain context format 2");
|
||||
}
|
||||
}
|
||||
@ -1011,7 +1009,7 @@ bool ParseChainContextFormat2(const ots::Font *font,
|
||||
}
|
||||
if (!ots::ParseClassDefTable(font, data + offset_input_class_def,
|
||||
length - offset_input_class_def,
|
||||
num_glyphs, kMaxClassDefValue)) {
|
||||
num_glyphs, ots::kMaxClassDefValue)) {
|
||||
return OTS_FAILURE_MSG("Failed to parse input class defn in chain context format 2");
|
||||
}
|
||||
|
||||
@ -1022,7 +1020,7 @@ bool ParseChainContextFormat2(const ots::Font *font,
|
||||
}
|
||||
if (!ots::ParseClassDefTable(font, data + offset_lookahead_class_def,
|
||||
length - offset_lookahead_class_def,
|
||||
num_glyphs, kMaxClassDefValue)) {
|
||||
num_glyphs, ots::kMaxClassDefValue)) {
|
||||
return OTS_FAILURE_MSG("Failed to parse lookahead class defn in chain context format 2");
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,8 @@
|
||||
|
||||
namespace ots {
|
||||
|
||||
// The maximum number of class value.
|
||||
const uint16_t kMaxClassDefValue = 0xFFFF;
|
||||
|
||||
struct LookupSubtableParser {
|
||||
struct TypeParser {
|
||||
|
@ -3,6 +3,7 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "stat.h"
|
||||
#include "name.h"
|
||||
|
||||
namespace ots {
|
||||
|
||||
@ -10,6 +11,28 @@ namespace ots {
|
||||
// OpenTypeSTAT
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
bool OpenTypeSTAT::ValidateNameId(uint16_t nameid, bool allowPredefined) {
|
||||
OpenTypeNAME* name = static_cast<OpenTypeNAME*>(
|
||||
GetFont()->GetTypedTable(OTS_TAG_NAME));
|
||||
|
||||
if (!name->IsValidNameId(nameid)) {
|
||||
Drop("Invalid nameID: %d", nameid);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!allowPredefined && nameid < 26) {
|
||||
Warning("nameID out of range: %d", nameid);
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((nameid >= 26 && nameid <= 255) || nameid >= 32768) {
|
||||
Warning("nameID out of range: %d", nameid);
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenTypeSTAT::Parse(const uint8_t* data, size_t length) {
|
||||
Buffer table(data, length);
|
||||
if (!table.ReadU16(&this->majorVersion) ||
|
||||
@ -61,10 +84,8 @@ bool OpenTypeSTAT::Parse(const uint8_t* data, size_t length) {
|
||||
if (!CheckTag(axis.axisTag)) {
|
||||
return Drop("Bad design axis tag");
|
||||
}
|
||||
if (axis.axisNameID <= 255 || axis.axisNameID >= 32768) {
|
||||
Warning("Design axis nameID out of range");
|
||||
// We don't check that the name actually exists -- assume the client can handle
|
||||
// a missing name when it tries to read the table.
|
||||
if (!ValidateNameId(axis.axisNameID, false)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -116,8 +137,8 @@ bool OpenTypeSTAT::Parse(const uint8_t* data, size_t length) {
|
||||
Warning("Unexpected axis value flags");
|
||||
axisValue.format1.flags &= ~0xFFFCu;
|
||||
}
|
||||
if (axisValue.format1.valueNameID <= 255 || axisValue.format1.valueNameID >= 32768) {
|
||||
Warning("Axis value nameID out of range");
|
||||
if (!ValidateNameId(axisValue.format1.valueNameID)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
@ -136,8 +157,8 @@ bool OpenTypeSTAT::Parse(const uint8_t* data, size_t length) {
|
||||
Warning("Unexpected axis value flags");
|
||||
axisValue.format1.flags &= ~0xFFFCu;
|
||||
}
|
||||
if (axisValue.format2.valueNameID <= 255 || axisValue.format2.valueNameID >= 32768) {
|
||||
Warning("Axis value nameID out of range");
|
||||
if (!ValidateNameId(axisValue.format2.valueNameID)) {
|
||||
return true;
|
||||
}
|
||||
if (!(axisValue.format2.rangeMinValue <= axisValue.format2.nominalValue &&
|
||||
axisValue.format2.nominalValue <= axisValue.format2.rangeMaxValue)) {
|
||||
@ -159,8 +180,8 @@ bool OpenTypeSTAT::Parse(const uint8_t* data, size_t length) {
|
||||
Warning("Unexpected axis value flags");
|
||||
axisValue.format3.flags &= ~0xFFFCu;
|
||||
}
|
||||
if (axisValue.format3.valueNameID <= 255 || axisValue.format3.valueNameID >= 32768) {
|
||||
Warning("Axis value nameID out of range");
|
||||
if (!ValidateNameId(axisValue.format3.valueNameID)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
@ -180,8 +201,8 @@ bool OpenTypeSTAT::Parse(const uint8_t* data, size_t length) {
|
||||
Warning("Unexpected axis value flags");
|
||||
axisValue.format4.flags &= ~0xFFFCu;
|
||||
}
|
||||
if (axisValue.format4.valueNameID <= 255 || axisValue.format4.valueNameID >= 32768) {
|
||||
Warning("Axis value nameID out of range");
|
||||
if (!ValidateNameId(axisValue.format4.valueNameID)) {
|
||||
return true;
|
||||
}
|
||||
for (unsigned j = 0; j < axisValue.format4.axisCount; j++) {
|
||||
axisValue.format4.axisValues.emplace_back();
|
||||
@ -309,8 +330,8 @@ bool OpenTypeSTAT::Serialize(OTSStream* out) {
|
||||
return Error("Failed to write axis value");
|
||||
}
|
||||
for (unsigned j = 0; j < value.format4.axisValues.size(); j++) {
|
||||
if (!out->WriteU16(value.format4.axisValues[i].axisIndex) ||
|
||||
!out->WriteS32(value.format4.axisValues[i].value)) {
|
||||
if (!out->WriteU16(value.format4.axisValues[j].axisIndex) ||
|
||||
!out->WriteS32(value.format4.axisValues[j].value)) {
|
||||
return Error("Failed to write axis value");
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,8 @@ class OpenTypeSTAT : public Table {
|
||||
bool Serialize(OTSStream* out);
|
||||
|
||||
private:
|
||||
bool ValidateNameId(uint16_t nameid, bool allowPredefined = true);
|
||||
|
||||
uint16_t majorVersion;
|
||||
uint16_t minorVersion;
|
||||
uint16_t designAxisSize;
|
||||
|
@ -77,7 +77,7 @@ bool EncodeNumber(int num, std::vector<uint8_t> *out_bytes) {
|
||||
out_bytes->push_back(w);
|
||||
return true;
|
||||
}
|
||||
if (num <= -32768 && num >= -32767) {
|
||||
if (num <= -32768 && num >= 32767) {
|
||||
const uint8_t v = (num % 0xff00u) >> 8;
|
||||
const uint8_t w = num % 0xffu;
|
||||
out_bytes->push_back(28);
|
||||
|
Loading…
Reference in New Issue
Block a user