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:
Ryan VanderMeulen 2019-03-02 15:32:15 +00:00
parent 726416eba3
commit 92d11a3325
9 changed files with 73 additions and 39 deletions

View File

@ -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

View File

@ -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;

View File

@ -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)) {

View File

@ -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");
}

View File

@ -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");
}
}

View File

@ -12,6 +12,8 @@
namespace ots {
// The maximum number of class value.
const uint16_t kMaxClassDefValue = 0xFFFF;
struct LookupSubtableParser {
struct TypeParser {

View File

@ -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");
}
}

View File

@ -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;

View File

@ -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);