Bug 1227058 - Update OTS to version 5.0.0. r=jfkthame

This commit is contained in:
Frédéric Wang 2016-01-26 14:08:00 +01:00
parent da4406c427
commit cb0a6d879c
13 changed files with 36 additions and 1160 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/. Our reference repository is https://github.com/khaledhosny/ots/.
Current revision: e8039a2b0f1a8ac1d2b21c088d1cbf0cd53cfe94 Current revision: 99a3b7ff8fb241e0f68a25a41726cc3421d1f9bf
Upstream files included: LICENSE, src/, include/ Upstream files included: LICENSE, src/, include/

View File

@ -203,7 +203,7 @@ class OTS_API OTSContext {
// This function will be called when OTS needs to decide what to do for a // This function will be called when OTS needs to decide what to do for a
// font table. // font table.
// tag: table tag as a platform-native unsigned integer // tag: table tag formed with OTS_TAG() macro
virtual TableAction GetTableAction(uint32_t tag) { return ots::TABLE_ACTION_DEFAULT; } virtual TableAction GetTableAction(uint32_t tag) { return ots::TABLE_ACTION_DEFAULT; }
}; };

View File

@ -36,10 +36,6 @@ struct Subtable314Range {
uint32_t id_range_offset_offset; uint32_t id_range_offset_offset;
}; };
// The maximum number of groups in format 12, 13 or 14 subtables.
// Note: 0xFFFF is the maximum number of glyphs in a single font file.
const unsigned kMaxCMAPGroups = 0xFFFF;
// Glyph array size for the Mac Roman (format 0) table. // Glyph array size for the Mac Roman (format 0) table.
const size_t kFormat0ArraySize = 256; const size_t kFormat0ArraySize = 256;
@ -286,7 +282,7 @@ bool Parse31012(ots::Font *font,
if (!subtable.ReadU32(&num_groups)) { if (!subtable.ReadU32(&num_groups)) {
return OTS_FAILURE_MSG("can't read number of format 12 subtable groups"); return OTS_FAILURE_MSG("can't read number of format 12 subtable groups");
} }
if (num_groups == 0 || num_groups > kMaxCMAPGroups) { if (num_groups == 0 || subtable.remaining() < num_groups * 12) {
return OTS_FAILURE_MSG("Bad format 12 subtable group count %d", num_groups); return OTS_FAILURE_MSG("Bad format 12 subtable group count %d", num_groups);
} }
@ -308,21 +304,6 @@ bool Parse31012(ots::Font *font,
groups[i].start_range, groups[i].end_range, groups[i].start_glyph_id); groups[i].start_range, groups[i].end_range, groups[i].start_glyph_id);
} }
// [0xD800, 0xDFFF] are surrogate code points.
if (groups[i].start_range >= 0xD800 &&
groups[i].start_range <= 0xDFFF) {
return OTS_FAILURE_MSG("format 12 subtable out of range group startCharCode (0x%4X)", groups[i].start_range);
}
if (groups[i].end_range >= 0xD800 &&
groups[i].end_range <= 0xDFFF) {
return OTS_FAILURE_MSG("format 12 subtable out of range group endCharCode (0x%4X)", groups[i].end_range);
}
if (groups[i].start_range < 0xD800 &&
groups[i].end_range > 0xDFFF) {
return OTS_FAILURE_MSG("bad format 12 subtable group startCharCode (0x%4X) or endCharCode (0x%4X)",
groups[i].start_range, groups[i].end_range);
}
// We assert that the glyph value is within range. Because of the range // We assert that the glyph value is within range. Because of the range
// limits, above, we don't need to worry about overflow. // limits, above, we don't need to worry about overflow.
if (groups[i].end_range < groups[i].start_range) { if (groups[i].end_range < groups[i].start_range) {
@ -375,7 +356,7 @@ bool Parse31013(ots::Font *font,
// We limit the number of groups in the same way as in 3.10.12 tables. See // We limit the number of groups in the same way as in 3.10.12 tables. See
// the comment there in // the comment there in
if (num_groups == 0 || num_groups > kMaxCMAPGroups) { if (num_groups == 0 || subtable.remaining() < num_groups * 12) {
return OTS_FAILURE_MSG("Bad format 13 subtable group count %d", num_groups); return OTS_FAILURE_MSG("Bad format 13 subtable group count %d", num_groups);
} }
@ -483,7 +464,7 @@ bool Parse0514(ots::Font *font,
if (!subtable.ReadU32(&num_ranges)) { if (!subtable.ReadU32(&num_ranges)) {
return OTS_FAILURE_MSG("Can't read number of ranges in record %d", i); return OTS_FAILURE_MSG("Can't read number of ranges in record %d", i);
} }
if (num_ranges == 0 || num_ranges > kMaxCMAPGroups) { if (num_ranges == 0 || subtable.remaining() < num_ranges * 4) {
return OTS_FAILURE_MSG("Bad number of ranges (%d) in record %d", num_ranges, i); return OTS_FAILURE_MSG("Bad number of ranges (%d) in record %d", num_ranges, i);
} }
@ -517,7 +498,7 @@ bool Parse0514(ots::Font *font,
if (!subtable.ReadU32(&num_mappings)) { if (!subtable.ReadU32(&num_mappings)) {
return OTS_FAILURE_MSG("Can't read number of mappings in variation selector record %d", i); return OTS_FAILURE_MSG("Can't read number of mappings in variation selector record %d", i);
} }
if (num_mappings == 0) { if (num_mappings == 0 || subtable.remaining() < num_mappings * 5) {
return OTS_FAILURE_MSG("Bad number of mappings (%d) in variation selector record %d", num_mappings, i); return OTS_FAILURE_MSG("Bad number of mappings (%d) in variation selector record %d", num_mappings, i);
} }

View File

@ -195,16 +195,21 @@ bool ParseLookupTable(ots::Font *font, const uint8_t *data,
// Check lookup flags. // Check lookup flags.
if ((lookup_flag & kGdefRequiredFlags) && if ((lookup_flag & kGdefRequiredFlags) &&
(!font->gdef || !font->gdef->has_glyph_class_def)) { (!font->gdef || !font->gdef->has_glyph_class_def)) {
return OTS_FAILURE_MSG("Bad lookup flags %d", lookup_flag); return OTS_FAILURE_MSG("Lookup flags require GDEF table, "
"but none was found: %d", lookup_flag);
} }
if ((lookup_flag & kMarkAttachmentTypeMask) && if ((lookup_flag & kMarkAttachmentTypeMask) &&
(!font->gdef || !font->gdef->has_mark_attachment_class_def)) { (!font->gdef || !font->gdef->has_mark_attachment_class_def)) {
return OTS_FAILURE_MSG("lookup flag asks for mark attachment that is bad %d", lookup_flag); return OTS_FAILURE_MSG("Lookup flags ask for mark attachment, "
"but there is no GDEF table or it has no "
"mark attachment classes: %d", lookup_flag);
} }
bool use_mark_filtering_set = false; bool use_mark_filtering_set = false;
if (lookup_flag & kUseMarkFilteringSetBit) { if (lookup_flag & kUseMarkFilteringSetBit) {
if (!font->gdef || !font->gdef->has_mark_glyph_sets_def) { if (!font->gdef || !font->gdef->has_mark_glyph_sets_def) {
return OTS_FAILURE_MSG("lookup flag asks for mark filtering that is bad %d", lookup_flag); return OTS_FAILURE_MSG("Lookup flags ask for mark filtering, "
"but there is no GDEF table or it has no "
"mark filtering sets: %d", lookup_flag);
} }
use_mark_filtering_set = true; use_mark_filtering_set = true;
} }

View File

@ -125,23 +125,6 @@ bool ParseMetricsTable(const ots::Font *font,
if (!table->ReadU16(&adv) || !table->ReadS16(&sb)) { if (!table->ReadU16(&adv) || !table->ReadS16(&sb)) {
return OTS_FAILURE_MSG("Failed to read metric %d", i); return OTS_FAILURE_MSG("Failed to read metric %d", i);
} }
// This check is bogus, see https://github.com/khaledhosny/ots/issues/36
#if 0
// Since so many fonts don't have proper value on |adv| and |sb|,
// we should not call ots_failure() here. For example, about 20% of fonts
// in http://www.princexml.com/fonts/ (200+ fonts) fails these tests.
if (adv > header->adv_width_max) {
OTS_WARNING("bad adv: %u > %u", adv, header->adv_width_max);
adv = header->adv_width_max;
}
if (sb < header->min_sb1) {
OTS_WARNING("bad sb: %d < %d", sb, header->min_sb1);
sb = header->min_sb1;
}
#endif
metrics->entries.push_back(std::make_pair(adv, sb)); metrics->entries.push_back(std::make_pair(adv, sb));
} }
@ -152,17 +135,6 @@ bool ParseMetricsTable(const ots::Font *font,
// Some Japanese fonts (e.g., mona.ttf) fail this test. // Some Japanese fonts (e.g., mona.ttf) fail this test.
return OTS_FAILURE_MSG("Failed to read side bearing %d", i + num_metrics); return OTS_FAILURE_MSG("Failed to read side bearing %d", i + num_metrics);
} }
// This check is bogus, see https://github.com/khaledhosny/ots/issues/36
#if 0
if (sb < header->min_sb1) {
// The same as above. Three fonts in http://www.fontsquirrel.com/fontface
// (e.g., Notice2Std.otf) have weird lsb values.
OTS_WARNING("bad lsb: %d < %d", sb, header->min_sb1);
sb = header->min_sb1;
}
#endif
metrics->sbs.push_back(sb); metrics->sbs.push_back(sb);
} }

View File

@ -44,7 +44,6 @@ UNIFIED_SOURCES += [
'prep.cc', 'prep.cc',
'vhea.cc', 'vhea.cc',
'vmtx.cc', 'vmtx.cc',
'woff2.cc',
] ]
# We allow warnings for third-party code that can be updated from upstream. # We allow warnings for third-party code that can be updated from upstream.
@ -57,4 +56,5 @@ DEFINES['PACKAGE_BUGREPORT'] = '"http://bugzilla.mozilla.org/"'
USE_LIBS += [ USE_LIBS += [
'brotli', 'brotli',
'woff2',
] ]

View File

@ -14,7 +14,7 @@
#include <map> #include <map>
#include <vector> #include <vector>
#include "woff2.h" #include "woff2_dec.h"
// The OpenType Font File // The OpenType Font File
// http://www.microsoft.com/typography/otspec/cmap.htm // http://www.microsoft.com/typography/otspec/cmap.htm
@ -464,9 +464,11 @@ bool ProcessWOFF(ots::OpenTypeFile *header,
} }
bool ProcessWOFF2(ots::OpenTypeFile *header, bool ProcessWOFF2(ots::OpenTypeFile *header,
ots::Font *font, ots::OTSStream *output,
ots::OTSStream *output, const uint8_t *data, size_t length) { const uint8_t *data,
size_t decompressed_size = ots::ComputeWOFF2FinalSize(data, length); size_t length,
uint32_t index) {
size_t decompressed_size = woff2::ComputeWOFF2FinalSize(data, length);
if (decompressed_size == 0) { if (decompressed_size == 0) {
return OTS_FAILURE_MSG_HDR("Size of decompressed WOFF 2.0 is set to 0"); return OTS_FAILURE_MSG_HDR("Size of decompressed WOFF 2.0 is set to 0");
@ -477,11 +479,17 @@ bool ProcessWOFF2(ots::OpenTypeFile *header,
} }
std::vector<uint8_t> decompressed_buffer(decompressed_size); std::vector<uint8_t> decompressed_buffer(decompressed_size);
if (!ots::ConvertWOFF2ToSFNT(font, &decompressed_buffer[0], decompressed_size, if (!woff2::ConvertWOFF2ToTTF(&decompressed_buffer[0], decompressed_size,
data, length)) { data, length)) {
return OTS_FAILURE_MSG_HDR("Failed to convert WOFF 2.0 font to SFNT"); return OTS_FAILURE_MSG_HDR("Failed to convert WOFF 2.0 font to SFNT");
} }
return ProcessTTF(header, font, output, &decompressed_buffer[0], decompressed_size);
if (data[4] == 't' && data[5] == 't' && data[6] == 'c' && data[7] == 'f') {
return ProcessTTC(header, output, &decompressed_buffer[0], decompressed_size, index);
} else {
ots::Font font(header);
return ProcessTTF(header, &font, output, &decompressed_buffer[0], decompressed_size);
}
} }
ots::TableAction GetTableAction(ots::OpenTypeFile *header, uint32_t tag) { ots::TableAction GetTableAction(ots::OpenTypeFile *header, uint32_t tag) {
@ -885,7 +893,7 @@ bool OTSContext::Process(OTSStream *output,
if (data[0] == 'w' && data[1] == 'O' && data[2] == 'F' && data[3] == 'F') { if (data[0] == 'w' && data[1] == 'O' && data[2] == 'F' && data[3] == 'F') {
result = ProcessWOFF(&header, &font, output, data, length); result = ProcessWOFF(&header, &font, output, data, length);
} else if (data[0] == 'w' && data[1] == 'O' && data[2] == 'F' && data[3] == '2') { } else if (data[0] == 'w' && data[1] == 'O' && data[2] == 'F' && data[3] == '2') {
result = ProcessWOFF2(&header, &font, output, data, length); result = ProcessWOFF2(&header, output, data, length, index);
} else if (data[0] == 't' && data[1] == 't' && data[2] == 'c' && data[3] == 'f') { } else if (data[0] == 't' && data[1] == 't' && data[2] == 'c' && data[3] == 'f') {
result = ProcessTTC(&header, output, data, length, index); result = ProcessTTC(&header, output, data, length, index);
} else { } else {

View File

@ -158,6 +158,7 @@ class Buffer {
const uint8_t *buffer() const { return buffer_; } const uint8_t *buffer() const { return buffer_; }
size_t offset() const { return offset_; } size_t offset() const { return offset_; }
size_t length() const { return length_; } size_t length() const { return length_; }
size_t remaining() const { return length_ - offset_; }
void set_offset(size_t newoffset) { offset_ = newoffset; } void set_offset(size_t newoffset) { offset_ = newoffset; }

View File

@ -128,7 +128,7 @@ bool ots_post_serialise(OTSStream *out, Font *font) {
const OpenTypePOST *post = font->post; const OpenTypePOST *post = font->post;
// OpenType with CFF glyphs must have v3 post table. // OpenType with CFF glyphs must have v3 post table.
if (font->post && font->cff && font->post->version != 0x00030000) { if (post && font->cff && post->version != 0x00030000) {
return OTS_FAILURE_MSG("Bad post version %x", post->version); return OTS_FAILURE_MSG("Bad post version %x", post->version);
} }

View File

@ -4,7 +4,6 @@
#include "vhea.h" #include "vhea.h"
#include "gsub.h"
#include "head.h" #include "head.h"
#include "maxp.h" #include "maxp.h"
@ -37,10 +36,7 @@ bool ots_vhea_parse(Font *font, const uint8_t *data, size_t length) {
bool ots_vhea_should_serialise(Font *font) { bool ots_vhea_should_serialise(Font *font) {
// vhea should'nt serialise when vmtx doesn't exist. // vhea should'nt serialise when vmtx doesn't exist.
// Firefox developer pointed out that vhea/vmtx should serialise iff GSUB is return font->vhea != NULL && font->vmtx != NULL;
// preserved. See http://crbug.com/77386
return font->vhea != NULL && font->vmtx != NULL &&
ots_gsub_should_serialise(font);
} }
bool ots_vhea_serialise(OTSStream *out, Font *font) { bool ots_vhea_serialise(OTSStream *out, Font *font) {

View File

@ -4,7 +4,6 @@
#include "vmtx.h" #include "vmtx.h"
#include "gsub.h"
#include "maxp.h" #include "maxp.h"
#include "vhea.h" #include "vhea.h"
@ -33,10 +32,8 @@ bool ots_vmtx_parse(Font *font, const uint8_t *data, size_t length) {
} }
bool ots_vmtx_should_serialise(Font *font) { bool ots_vmtx_should_serialise(Font *font) {
// vmtx should serialise when vhea and GSUB are preserved. // vmtx should serialise when vhea is preserved.
// See the comment in ots_vhea_should_serialise(). return font->vmtx != NULL && font->vhea != NULL;
return font->vmtx != NULL && font->vhea != NULL &&
ots_gsub_should_serialise(font);
} }
bool ots_vmtx_serialise(OTSStream *out, Font *font) { bool ots_vmtx_serialise(OTSStream *out, Font *font) {

File diff suppressed because it is too large Load Diff

View File

@ -1,20 +0,0 @@
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef OTS_WOFF2_H_
#define OTS_WOFF2_H_
namespace ots {
// Compute the size of the final uncompressed font, or 0 on error.
size_t ComputeWOFF2FinalSize(const uint8_t *data, size_t length);
// Decompresses the font into the target buffer. The result_length should
// be the same as determined by ComputeFinalSize(). Returns true on successful
// decompression.
bool ConvertWOFF2ToSFNT(Font *font, uint8_t *result, size_t result_length,
const uint8_t *data, size_t length);
}
#endif // OTS_WOFF2_H_