зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1074223 - Update OTS to pick up fixes for upstream issues 35, 37. Current rev: c24a839b1c66c4de09e58fabaacb82bf3bd692a4. r=jdaggett
This commit is contained in:
Родитель
a400b8717e
Коммит
b2782ecfb8
|
@ -2,10 +2,11 @@ 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: 5c25bdac8f02080f49fa416ea997ed77e3be0d30
|
||||
Current revision: c24a839b1c66c4de09e58fabaacb82bf3bd692a4
|
||||
|
||||
Upstream files included: LICENSE, src/, include/
|
||||
|
||||
Additional files: README.mozilla, src/moz.build
|
||||
|
||||
Additional patch: ots-visibility.patch (bug 711079).
|
||||
Additional patch: ots-brotli-path.patch (bug 1064737).
|
||||
|
|
|
@ -227,7 +227,10 @@ class OTS_API OTSContext {
|
|||
bool Process(OTSStream *output, const uint8_t *input, size_t length);
|
||||
|
||||
// This function will be called when OTS is reporting an error.
|
||||
virtual void Message(const char *format, ...) MSGFUNC_FMT_ATTR {}
|
||||
// level: the severity of the generated message:
|
||||
// 0: error messages in case OTS fails to sanitize the font.
|
||||
// 1: warning messages about issue OTS fixed in the sanitized font.
|
||||
virtual void Message(int level, const char *format, ...) MSGFUNC_FMT_ATTR {}
|
||||
|
||||
// This function will be called when OTS needs to decide what to do for a
|
||||
// font table.
|
||||
|
@ -236,6 +239,9 @@ class OTS_API OTSContext {
|
|||
virtual TableAction GetTableAction(uint32_t tag) { return ots::TABLE_ACTION_DEFAULT; }
|
||||
};
|
||||
|
||||
// For backward compatibility - remove once Chrome switches over to the new API.
|
||||
bool Process(OTSStream *output, const uint8_t *input, size_t length);
|
||||
|
||||
// Force to disable debug output even when the library is compiled with
|
||||
// -DOTS_DEBUG.
|
||||
void DisableDebugOutput();
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
diff --git a/gfx/ots/src/woff2.cc b/gfx/ots/src/woff2.cc
|
||||
--- a/gfx/ots/src/woff2.cc
|
||||
+++ b/gfx/ots/src/woff2.cc
|
||||
@@ -6,17 +6,17 @@
|
||||
// Condensed file format.
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <vector>
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
-#include "third_party/brotli/src/brotli/dec/decode.h"
|
||||
+#include "decode.h"
|
||||
|
||||
#include "opentype-sanitiser.h"
|
||||
#include "ots-memory-stream.h"
|
||||
#include "ots.h"
|
||||
#include "woff2.h"
|
||||
|
||||
namespace {
|
||||
|
|
@ -37,7 +37,7 @@ diff --git a/gfx/ots/include/opentype-sanitiser.h b/gfx/ots/include/opentype-san
|
|||
typedef unsigned short uint16_t;
|
||||
typedef int int32_t;
|
||||
typedef unsigned int uint32_t;
|
||||
@@ -187,17 +187,17 @@ class OTSStream {
|
||||
@@ -187,17 +207,17 @@ class OTSStream {
|
||||
|
||||
enum TableAction {
|
||||
TABLE_ACTION_DEFAULT, // Use OTS's default action for that table
|
||||
|
@ -56,3 +56,18 @@ diff --git a/gfx/ots/include/opentype-sanitiser.h b/gfx/ots/include/opentype-san
|
|||
// output: a pointer to an object implementing the OTSStream interface. The
|
||||
// sanitisied output will be written to this. In the even of a failure,
|
||||
// partial output may have been written.
|
||||
@@ -222,13 +242,13 @@ class OTSContext {
|
||||
// For backward compatibility - remove once Chrome switches over to the new API.
|
||||
bool Process(OTSStream *output, const uint8_t *input, size_t length);
|
||||
|
||||
// Force to disable debug output even when the library is compiled with
|
||||
// -DOTS_DEBUG.
|
||||
void DisableDebugOutput();
|
||||
|
||||
// Enable WOFF2 support(experimental).
|
||||
-void EnableWOFF2();
|
||||
+void OTS_API EnableWOFF2();
|
||||
|
||||
} // namespace ots
|
||||
|
||||
#endif // OPENTYPE_SANITISER_H_
|
||||
|
|
|
@ -462,7 +462,7 @@ bool ParsePrivateDictData(
|
|||
}
|
||||
|
||||
bool ParseDictData(const uint8_t *data, size_t table_length,
|
||||
const ots::CFFIndex &index, size_t glyphs,
|
||||
const ots::CFFIndex &index, uint16_t glyphs,
|
||||
size_t sid_max, DICT_DATA_TYPE type,
|
||||
ots::OpenTypeCFF *out_cff) {
|
||||
for (unsigned i = 1; i < index.offsets.size(); ++i) {
|
||||
|
@ -476,7 +476,7 @@ bool ParseDictData(const uint8_t *data, size_t table_length,
|
|||
|
||||
FONT_FORMAT font_format = FORMAT_UNKNOWN;
|
||||
bool have_ros = false;
|
||||
size_t charstring_glyphs = 0;
|
||||
uint16_t charstring_glyphs = 0;
|
||||
size_t charset_offset = 0;
|
||||
|
||||
while (table.offset() < dict_length) {
|
||||
|
@ -700,7 +700,7 @@ bool ParseDictData(const uint8_t *data, size_t table_length,
|
|||
return OTS_FAILURE();
|
||||
}
|
||||
if (format == 0) {
|
||||
for (size_t j = 0; j < glyphs; ++j) {
|
||||
for (uint16_t j = 0; j < glyphs; ++j) {
|
||||
uint8_t fd_index = 0;
|
||||
if (!cff_table.ReadU8(&fd_index)) {
|
||||
return OTS_FAILURE();
|
||||
|
@ -844,7 +844,7 @@ bool ParseDictData(const uint8_t *data, size_t table_length,
|
|||
}
|
||||
switch (format) {
|
||||
case 0:
|
||||
for (unsigned j = 1 /* .notdef is omitted */; j < glyphs; ++j) {
|
||||
for (uint16_t j = 1 /* .notdef is omitted */; j < glyphs; ++j) {
|
||||
uint16_t sid = 0;
|
||||
if (!cff_table.ReadU16(&sid)) {
|
||||
return OTS_FAILURE();
|
||||
|
@ -967,7 +967,7 @@ bool ots_cff_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
|
|||
return OTS_FAILURE();
|
||||
}
|
||||
|
||||
const size_t num_glyphs = file->maxp->num_glyphs;
|
||||
const uint16_t num_glyphs = file->maxp->num_glyphs;
|
||||
const size_t sid_max = string_index.count + kNStdString;
|
||||
// string_index.count == 0 is allowed.
|
||||
|
||||
|
@ -996,7 +996,8 @@ bool ots_cff_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
|
|||
|
||||
// Check if all charstrings (font hinting code for each glyph) are valid.
|
||||
for (size_t i = 0; i < file->cff->char_strings_array.size(); ++i) {
|
||||
if (!ValidateType2CharStringIndex(*(file->cff->char_strings_array.at(i)),
|
||||
if (!ValidateType2CharStringIndex(file,
|
||||
*(file->cff->char_strings_array.at(i)),
|
||||
global_subrs_index,
|
||||
file->cff->fd_select,
|
||||
file->cff->local_subrs_per_font,
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#define TABLE_NAME "CFF"
|
||||
|
||||
namespace {
|
||||
|
||||
// Type 2 Charstring Implementation Limits. See Appendix. B in Adobe Technical
|
||||
|
@ -28,7 +30,8 @@ const size_t kMaxSubrNesting = 10;
|
|||
// will fail with the dummy value.
|
||||
const int32_t dummy_result = INT_MAX;
|
||||
|
||||
bool ExecuteType2CharString(size_t call_depth,
|
||||
bool ExecuteType2CharString(ots::OpenTypeFile *file,
|
||||
size_t call_depth,
|
||||
const ots::CFFIndex& global_subrs_index,
|
||||
const ots::CFFIndex& local_subrs_index,
|
||||
ots::Buffer *cff_table,
|
||||
|
@ -222,7 +225,8 @@ bool ReadNextNumberFromType2CharString(ots::Buffer *char_string,
|
|||
// succeeds. If the |op| is kCallSubr or kCallGSubr, the function recursively
|
||||
// calls ExecuteType2CharString() function. The arguments other than |op| and
|
||||
// |argument_stack| are passed for that reason.
|
||||
bool ExecuteType2CharStringOperator(int32_t op,
|
||||
bool ExecuteType2CharStringOperator(ots::OpenTypeFile *file,
|
||||
int32_t op,
|
||||
size_t call_depth,
|
||||
const ots::CFFIndex& global_subrs_index,
|
||||
const ots::CFFIndex& local_subrs_index,
|
||||
|
@ -286,7 +290,8 @@ bool ExecuteType2CharStringOperator(int32_t op,
|
|||
}
|
||||
ots::Buffer char_string_to_jump(cff_table->buffer() + offset, length);
|
||||
|
||||
return ExecuteType2CharString(call_depth + 1,
|
||||
return ExecuteType2CharString(file,
|
||||
call_depth + 1,
|
||||
global_subrs_index,
|
||||
local_subrs_index,
|
||||
cff_table,
|
||||
|
@ -708,8 +713,7 @@ bool ExecuteType2CharStringOperator(int32_t op,
|
|||
return true;
|
||||
}
|
||||
|
||||
//OTS_WARNING("Undefined operator: %d (0x%x)", op, op);
|
||||
return OTS_FAILURE();
|
||||
return OTS_FAILURE_MSG("Undefined operator: %d (0x%x)", op, op);
|
||||
}
|
||||
|
||||
// Executes |char_string| and updates |argument_stack|.
|
||||
|
@ -725,7 +729,8 @@ bool ExecuteType2CharStringOperator(int32_t op,
|
|||
// in_out_found_width: true is set if |char_string| contains 'width' byte (which
|
||||
// is 0 or 1 byte.)
|
||||
// in_out_num_stems: total number of hstems and vstems processed so far.
|
||||
bool ExecuteType2CharString(size_t call_depth,
|
||||
bool ExecuteType2CharString(ots::OpenTypeFile *file,
|
||||
size_t call_depth,
|
||||
const ots::CFFIndex& global_subrs_index,
|
||||
const ots::CFFIndex& local_subrs_index,
|
||||
ots::Buffer *cff_table,
|
||||
|
@ -774,7 +779,8 @@ bool ExecuteType2CharString(size_t call_depth,
|
|||
}
|
||||
|
||||
// An operator is found. Execute it.
|
||||
if (!ExecuteType2CharStringOperator(operator_or_operand,
|
||||
if (!ExecuteType2CharStringOperator(file,
|
||||
operator_or_operand,
|
||||
call_depth,
|
||||
global_subrs_index,
|
||||
local_subrs_index,
|
||||
|
@ -839,18 +845,21 @@ bool SelectLocalSubr(const std::map<uint16_t, uint8_t> &fd_select,
|
|||
namespace ots {
|
||||
|
||||
bool ValidateType2CharStringIndex(
|
||||
ots::OpenTypeFile *file,
|
||||
const CFFIndex& char_strings_index,
|
||||
const CFFIndex& global_subrs_index,
|
||||
const std::map<uint16_t, uint8_t> &fd_select,
|
||||
const std::vector<CFFIndex *> &local_subrs_per_font,
|
||||
const CFFIndex *local_subrs,
|
||||
Buffer* cff_table) {
|
||||
if (char_strings_index.offsets.size() == 0) {
|
||||
const uint16_t num_offsets =
|
||||
static_cast<uint16_t>(char_strings_index.offsets.size());
|
||||
if (num_offsets != char_strings_index.offsets.size() || num_offsets == 0) {
|
||||
return OTS_FAILURE(); // no charstring.
|
||||
}
|
||||
|
||||
// For each glyph, validate the corresponding charstring.
|
||||
for (unsigned i = 1; i < char_strings_index.offsets.size(); ++i) {
|
||||
for (uint16_t i = 1; i < num_offsets; ++i) {
|
||||
// Prepare a Buffer object, |char_string|, which contains the charstring
|
||||
// for the |i|-th glyph.
|
||||
const size_t length =
|
||||
|
@ -866,7 +875,7 @@ bool ValidateType2CharStringIndex(
|
|||
Buffer char_string(cff_table->buffer() + offset, length);
|
||||
|
||||
// Get a local subrs for the glyph.
|
||||
const unsigned glyph_index = i - 1; // index in the map is 0-origin.
|
||||
const uint16_t glyph_index = i - 1; // index in the map is 0-origin.
|
||||
const CFFIndex *local_subrs_to_use = NULL;
|
||||
if (!SelectLocalSubr(fd_select,
|
||||
local_subrs_per_font,
|
||||
|
@ -886,7 +895,8 @@ bool ValidateType2CharStringIndex(
|
|||
bool found_endchar = false;
|
||||
bool found_width = false;
|
||||
size_t num_stems = 0;
|
||||
if (!ExecuteType2CharString(0 /* initial call_depth is zero */,
|
||||
if (!ExecuteType2CharString(file,
|
||||
0 /* initial call_depth is zero */,
|
||||
global_subrs_index, *local_subrs_to_use,
|
||||
cff_table, &char_string, &argument_stack,
|
||||
&found_endchar, &found_width, &num_stems)) {
|
||||
|
@ -900,3 +910,5 @@ bool ValidateType2CharStringIndex(
|
|||
}
|
||||
|
||||
} // namespace ots
|
||||
|
||||
#undef TABLE_NAME
|
||||
|
|
|
@ -35,6 +35,7 @@ namespace ots {
|
|||
// cff_table: A buffer which contains actual byte code of charstring, global
|
||||
// subroutines and local subroutines.
|
||||
bool ValidateType2CharStringIndex(
|
||||
OpenTypeFile *file,
|
||||
const CFFIndex &char_strings_index,
|
||||
const CFFIndex &global_subrs_index,
|
||||
const std::map<uint16_t, uint8_t> &fd_select,
|
||||
|
|
|
@ -218,7 +218,7 @@ bool ParseFormat4(ots::OpenTypeFile *file, int platform, int encoding,
|
|||
// glyphs and that we don't access anything out-of-bounds.
|
||||
for (unsigned i = 0; i < segcount; ++i) {
|
||||
for (unsigned cp = ranges[i].start_range; cp <= ranges[i].end_range; ++cp) {
|
||||
const uint16_t code_point = cp;
|
||||
const uint16_t code_point = static_cast<uint16_t>(cp);
|
||||
if (ranges[i].id_range_offset == 0) {
|
||||
// this is explictly allowed to overflow in the spec
|
||||
const uint16_t glyph = code_point + ranges[i].id_delta;
|
||||
|
@ -866,13 +866,13 @@ bool ots_cmap_serialise(OTSStream *out, OpenTypeFile *file) {
|
|||
const bool have_314 = (!have_304) && file->cmap->subtable_3_1_4_data;
|
||||
const bool have_31012 = file->cmap->subtable_3_10_12.size() != 0;
|
||||
const bool have_31013 = file->cmap->subtable_3_10_13.size() != 0;
|
||||
const unsigned num_subtables = static_cast<unsigned>(have_034) +
|
||||
static_cast<unsigned>(have_0514) +
|
||||
static_cast<unsigned>(have_100) +
|
||||
static_cast<unsigned>(have_304) +
|
||||
static_cast<unsigned>(have_314) +
|
||||
static_cast<unsigned>(have_31012) +
|
||||
static_cast<unsigned>(have_31013);
|
||||
const uint16_t num_subtables = static_cast<uint16_t>(have_034) +
|
||||
static_cast<uint16_t>(have_0514) +
|
||||
static_cast<uint16_t>(have_100) +
|
||||
static_cast<uint16_t>(have_304) +
|
||||
static_cast<uint16_t>(have_314) +
|
||||
static_cast<uint16_t>(have_31012) +
|
||||
static_cast<uint16_t>(have_31013);
|
||||
const off_t table_start = out->Tell();
|
||||
|
||||
// Some fonts don't have 3-0-4 MS Symbol nor 3-1-4 Unicode BMP tables
|
||||
|
@ -1006,8 +1006,8 @@ bool ots_cmap_serialise(OTSStream *out, OpenTypeFile *file) {
|
|||
= file->cmap->subtable_3_10_13;
|
||||
const unsigned num_groups = groups.size();
|
||||
if (!out->WriteU16(13) ||
|
||||
!out->WriteU32(0) ||
|
||||
!out->WriteU32(num_groups * 12 + 14) ||
|
||||
!out->WriteU16(0) ||
|
||||
!out->WriteU32(num_groups * 12 + 16) ||
|
||||
!out->WriteU32(0) ||
|
||||
!out->WriteU32(num_groups)) {
|
||||
return OTS_FAILURE();
|
||||
|
|
|
@ -87,12 +87,14 @@ bool ots_gasp_should_serialise(OpenTypeFile *file) {
|
|||
bool ots_gasp_serialise(OTSStream *out, OpenTypeFile *file) {
|
||||
const OpenTypeGASP *gasp = file->gasp;
|
||||
|
||||
if (!out->WriteU16(gasp->version) ||
|
||||
!out->WriteU16(gasp->gasp_ranges.size())) {
|
||||
const uint16_t num_ranges = static_cast<uint16_t>(gasp->gasp_ranges.size());
|
||||
if (num_ranges != gasp->gasp_ranges.size() ||
|
||||
!out->WriteU16(gasp->version) ||
|
||||
!out->WriteU16(num_ranges)) {
|
||||
return OTS_FAILURE_MSG("failed to write gasp header");
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < gasp->gasp_ranges.size(); ++i) {
|
||||
for (uint16_t i = 0; i < num_ranges; ++i) {
|
||||
if (!out->WriteU16(gasp->gasp_ranges[i].first) ||
|
||||
!out->WriteU16(gasp->gasp_ranges[i].second)) {
|
||||
return OTS_FAILURE_MSG("Failed to write gasp subtable %d", i);
|
||||
|
|
|
@ -107,13 +107,16 @@ bool ots_hdmx_should_serialise(OpenTypeFile *file) {
|
|||
bool ots_hdmx_serialise(OTSStream *out, OpenTypeFile *file) {
|
||||
OpenTypeHDMX * const hdmx = file->hdmx;
|
||||
|
||||
if (!out->WriteU16(hdmx->version) ||
|
||||
!out->WriteS16(hdmx->records.size()) ||
|
||||
const int16_t num_recs = static_cast<int16_t>(hdmx->records.size());
|
||||
if (hdmx->records.size() >
|
||||
static_cast<size_t>(std::numeric_limits<int16_t>::max()) ||
|
||||
!out->WriteU16(hdmx->version) ||
|
||||
!out->WriteS16(num_recs) ||
|
||||
!out->WriteS32(hdmx->size_device_record)) {
|
||||
return OTS_FAILURE_MSG("Failed to write hdmx header");
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < hdmx->records.size(); ++i) {
|
||||
for (int16_t i = 0; i < num_recs; ++i) {
|
||||
const OpenTypeHDMXDeviceRecord& rec = hdmx->records[i];
|
||||
if (!out->Write(&rec.pixel_size, 1) ||
|
||||
!out->Write(&rec.max_width, 1) ||
|
||||
|
|
|
@ -113,8 +113,8 @@ bool ots_kern_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
|
|||
if (subtable.entry_selector != max_pow2) {
|
||||
return OTS_FAILURE_MSG("Bad subtable %d entry selector %d", i, subtable.entry_selector);
|
||||
}
|
||||
const uint32_t expected_range_shift
|
||||
= kFormat0PairSize * num_pairs - subtable.search_range;
|
||||
const uint16_t expected_range_shift =
|
||||
kFormat0PairSize * num_pairs - subtable.search_range;
|
||||
if (subtable.range_shift != expected_range_shift) {
|
||||
OTS_WARNING("bad range shift");
|
||||
subtable.range_shift = expected_range_shift;
|
||||
|
@ -161,17 +161,21 @@ bool ots_kern_should_serialise(OpenTypeFile *file) {
|
|||
bool ots_kern_serialise(OTSStream *out, OpenTypeFile *file) {
|
||||
const OpenTypeKERN *kern = file->kern;
|
||||
|
||||
if (!out->WriteU16(kern->version) ||
|
||||
!out->WriteU16(kern->subtables.size())) {
|
||||
const uint16_t num_subtables = static_cast<uint16_t>(kern->subtables.size());
|
||||
if (num_subtables != kern->subtables.size() ||
|
||||
!out->WriteU16(kern->version) ||
|
||||
!out->WriteU16(num_subtables)) {
|
||||
return OTS_FAILURE_MSG("Can't write kern table header");
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < kern->subtables.size(); ++i) {
|
||||
const uint16_t length = 14 + (6 * kern->subtables[i].pairs.size());
|
||||
if (!out->WriteU16(kern->subtables[i].version) ||
|
||||
!out->WriteU16(length) ||
|
||||
for (uint16_t i = 0; i < num_subtables; ++i) {
|
||||
const size_t length = 14 + (6 * kern->subtables[i].pairs.size());
|
||||
if (length > std::numeric_limits<uint16_t>::max() ||
|
||||
!out->WriteU16(kern->subtables[i].version) ||
|
||||
!out->WriteU16(static_cast<uint16_t>(length)) ||
|
||||
!out->WriteU16(kern->subtables[i].coverage) ||
|
||||
!out->WriteU16(kern->subtables[i].pairs.size()) ||
|
||||
!out->WriteU16(
|
||||
static_cast<uint16_t>(kern->subtables[i].pairs.size())) ||
|
||||
!out->WriteU16(kern->subtables[i].search_range) ||
|
||||
!out->WriteU16(kern->subtables[i].entry_selector) ||
|
||||
!out->WriteU16(kern->subtables[i].range_shift)) {
|
||||
|
|
|
@ -78,7 +78,9 @@ bool ots_loca_serialise(OTSStream *out, OpenTypeFile *file) {
|
|||
|
||||
if (head->index_to_loc_format == 0) {
|
||||
for (unsigned i = 0; i < loca->offsets.size(); ++i) {
|
||||
if (!out->WriteU16(loca->offsets[i] >> 1)) {
|
||||
const uint16_t offset = static_cast<uint16_t>(loca->offsets[i] >> 1);
|
||||
if ((offset != (loca->offsets[i] >> 1)) ||
|
||||
!out->WriteU16(offset)) {
|
||||
return OTS_FAILURE_MSG("Failed to write glyph offset for glyph %d", i);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,11 +67,13 @@ bool ots_ltsh_should_serialise(OpenTypeFile *file) {
|
|||
bool ots_ltsh_serialise(OTSStream *out, OpenTypeFile *file) {
|
||||
const OpenTypeLTSH *ltsh = file->ltsh;
|
||||
|
||||
if (!out->WriteU16(ltsh->version) ||
|
||||
!out->WriteU16(ltsh->ypels.size())) {
|
||||
const uint16_t num_ypels = static_cast<uint16_t>(ltsh->ypels.size());
|
||||
if (num_ypels != ltsh->ypels.size() ||
|
||||
!out->WriteU16(ltsh->version) ||
|
||||
!out->WriteU16(num_ypels)) {
|
||||
return OTS_FAILURE_MSG("Failed to write pels size");
|
||||
}
|
||||
for (unsigned i = 0; i < ltsh->ypels.size(); ++i) {
|
||||
for (uint16_t i = 0; i < num_ypels; ++i) {
|
||||
if (!out->Write(&(ltsh->ypels[i]), 1)) {
|
||||
return OTS_FAILURE_MSG("Failed to write pixel size for glyph %d", i);
|
||||
}
|
||||
|
|
|
@ -126,6 +126,8 @@ bool ParseMetricsTable(const ots::OpenTypeFile *file,
|
|||
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.
|
||||
|
@ -138,6 +140,7 @@ bool ParseMetricsTable(const ots::OpenTypeFile *file,
|
|||
OTS_WARNING("bad sb: %d < %d", sb, header->min_sb1);
|
||||
sb = header->min_sb1;
|
||||
}
|
||||
#endif
|
||||
|
||||
metrics->entries.push_back(std::make_pair(adv, sb));
|
||||
}
|
||||
|
@ -150,12 +153,15 @@ bool ParseMetricsTable(const ots::OpenTypeFile *file,
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -200,7 +200,7 @@ bool ots_name_parse(OpenTypeFile* file, const uint8_t* data, size_t length) {
|
|||
// 4 - full name
|
||||
// 5 - version
|
||||
// 6 - postscript name
|
||||
static const unsigned kStdNameCount = 7;
|
||||
static const uint16_t kStdNameCount = 7;
|
||||
static const char* kStdNames[kStdNameCount] = {
|
||||
NULL,
|
||||
"OTS derived font",
|
||||
|
@ -237,7 +237,7 @@ bool ots_name_parse(OpenTypeFile* file, const uint8_t* data, size_t length) {
|
|||
}
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < kStdNameCount; ++i) {
|
||||
for (uint16_t i = 0; i < kStdNameCount; ++i) {
|
||||
if (kStdNames[i] == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
@ -271,8 +271,8 @@ bool ots_name_should_serialise(OpenTypeFile* file) {
|
|||
bool ots_name_serialise(OTSStream* out, OpenTypeFile* file) {
|
||||
const OpenTypeNAME* name = file->name;
|
||||
|
||||
uint16_t name_count = name->names.size();
|
||||
uint16_t lang_tag_count = name->lang_tags.size();
|
||||
uint16_t name_count = static_cast<uint16_t>(name->names.size());
|
||||
uint16_t lang_tag_count = static_cast<uint16_t>(name->lang_tags.size());
|
||||
uint16_t format = 0;
|
||||
size_t string_offset = 6 + name_count * 12;
|
||||
|
||||
|
@ -286,7 +286,7 @@ bool ots_name_serialise(OTSStream* out, OpenTypeFile* file) {
|
|||
}
|
||||
if (!out->WriteU16(format) ||
|
||||
!out->WriteU16(name_count) ||
|
||||
!out->WriteU16(string_offset)) {
|
||||
!out->WriteU16(static_cast<uint16_t>(string_offset))) {
|
||||
return OTS_FAILURE_MSG("Failed to write name header");
|
||||
}
|
||||
|
||||
|
@ -294,12 +294,14 @@ bool ots_name_serialise(OTSStream* out, OpenTypeFile* file) {
|
|||
for (std::vector<NameRecord>::const_iterator name_iter = name->names.begin();
|
||||
name_iter != name->names.end(); name_iter++) {
|
||||
const NameRecord& rec = *name_iter;
|
||||
if (!out->WriteU16(rec.platform_id) ||
|
||||
if (string_data.size() + rec.text.size() >
|
||||
std::numeric_limits<uint16_t>::max() ||
|
||||
!out->WriteU16(rec.platform_id) ||
|
||||
!out->WriteU16(rec.encoding_id) ||
|
||||
!out->WriteU16(rec.language_id) ||
|
||||
!out->WriteU16(rec.name_id) ||
|
||||
!out->WriteU16(rec.text.size()) ||
|
||||
!out->WriteU16(string_data.size()) ) {
|
||||
!out->WriteU16(static_cast<uint16_t>(rec.text.size())) ||
|
||||
!out->WriteU16(static_cast<uint16_t>(string_data.size())) ) {
|
||||
return OTS_FAILURE_MSG("Faile to write name entry");
|
||||
}
|
||||
string_data.append(rec.text);
|
||||
|
@ -312,8 +314,10 @@ bool ots_name_serialise(OTSStream* out, OpenTypeFile* file) {
|
|||
for (std::vector<std::string>::const_iterator tag_iter =
|
||||
name->lang_tags.begin();
|
||||
tag_iter != name->lang_tags.end(); tag_iter++) {
|
||||
if (!out->WriteU16(tag_iter->size()) ||
|
||||
!out->WriteU16(string_data.size())) {
|
||||
if (string_data.size() + tag_iter->size() >
|
||||
std::numeric_limits<uint16_t>::max() ||
|
||||
!out->WriteU16(static_cast<uint16_t>(tag_iter->size())) ||
|
||||
!out->WriteU16(static_cast<uint16_t>(string_data.size()))) {
|
||||
return OTS_FAILURE_MSG("Failed to write string");
|
||||
}
|
||||
string_data.append(*tag_iter);
|
||||
|
|
|
@ -211,8 +211,8 @@ bool ProcessTTF(ots::OpenTypeFile *header,
|
|||
// range_shift is NumTables x 16-searchRange. We know that 16*num_tables
|
||||
// doesn't over flow because we range checked it above. Also, we know that
|
||||
// it's > header->search_range by construction of search_range.
|
||||
const uint32_t expected_range_shift
|
||||
= 16 * header->num_tables - header->search_range;
|
||||
const uint16_t expected_range_shift =
|
||||
16 * header->num_tables - header->search_range;
|
||||
if (header->range_shift != expected_range_shift) {
|
||||
OTS_FAILURE_MSG_HDR("bad range shift");
|
||||
header->range_shift = expected_range_shift; // the same as above.
|
||||
|
@ -611,7 +611,7 @@ bool ProcessGeneric(ots::OpenTypeFile *header, uint32_t signature,
|
|||
}
|
||||
}
|
||||
|
||||
unsigned num_output_tables = 0;
|
||||
uint16_t num_output_tables = 0;
|
||||
for (unsigned i = 0; ; ++i) {
|
||||
if (table_parsers[i].parse == NULL) {
|
||||
break;
|
||||
|
@ -630,7 +630,7 @@ bool ProcessGeneric(ots::OpenTypeFile *header, uint32_t signature,
|
|||
}
|
||||
}
|
||||
|
||||
unsigned max_pow2 = 0;
|
||||
uint16_t max_pow2 = 0;
|
||||
while (1u << (max_pow2 + 1) <= num_output_tables) {
|
||||
max_pow2++;
|
||||
}
|
||||
|
@ -831,6 +831,12 @@ bool OTSContext::Process(OTSStream *output,
|
|||
return result;
|
||||
}
|
||||
|
||||
// For backward compatibility
|
||||
bool Process(OTSStream *output, const uint8_t *data, size_t length) {
|
||||
static OTSContext context;
|
||||
return context.Process(output, data, length);
|
||||
}
|
||||
|
||||
#if !defined(_MSC_VER) && defined(OTS_DEBUG)
|
||||
bool Failure(const char *f, int l, const char *fn) {
|
||||
if (g_debug_output) {
|
||||
|
|
|
@ -34,28 +34,31 @@ bool Failure(const char *f, int l, const char *fn);
|
|||
// its result (indicating a failure).
|
||||
|
||||
#if defined(_MSC_VER) || !defined(OTS_DEBUG)
|
||||
#define OTS_MESSAGE_(otf_,...) \
|
||||
(otf_)->context->Message(__VA_ARGS__)
|
||||
#define OTS_MESSAGE_(level,otf_,...) \
|
||||
(otf_)->context->Message(level,__VA_ARGS__)
|
||||
#else
|
||||
#define OTS_MESSAGE_(otf_,...) \
|
||||
#define OTS_MESSAGE_(level,otf_,...) \
|
||||
OTS_FAILURE(), \
|
||||
(otf_)->context->Message(__VA_ARGS__)
|
||||
(otf_)->context->Message(level,__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
// Generate a simple message
|
||||
#define OTS_FAILURE_MSG_(otf_,...) \
|
||||
(OTS_MESSAGE_(otf_,__VA_ARGS__), false)
|
||||
(OTS_MESSAGE_(0,otf_,__VA_ARGS__), false)
|
||||
|
||||
#define OTS_WARNING_MSG_(otf_,...) \
|
||||
OTS_MESSAGE_(1,otf_,__VA_ARGS__)
|
||||
|
||||
// Generate a message with an associated table tag
|
||||
#define OTS_FAILURE_MSG_TAG_(otf_,msg_,tag_) \
|
||||
(OTS_MESSAGE_(otf_,"%4.4s: %s", tag_, msg_), false)
|
||||
(OTS_MESSAGE_(0,otf_,"%4.4s: %s", tag_, msg_), false)
|
||||
|
||||
// Convenience macro for use in files that only handle a single table tag,
|
||||
// Convenience macros for use in files that only handle a single table tag,
|
||||
// defined as TABLE_NAME at the top of the file; the 'file' variable is
|
||||
// expected to be the current OpenTypeFile pointer.
|
||||
#define OTS_FAILURE_MSG(...) OTS_FAILURE_MSG_(file, TABLE_NAME ": " __VA_ARGS__)
|
||||
|
||||
#define OTS_WARNING OTS_FAILURE_MSG
|
||||
#define OTS_WARNING(...) OTS_WARNING_MSG_(file, TABLE_NAME ": " __VA_ARGS__)
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Buffer helper class
|
||||
|
|
|
@ -148,11 +148,14 @@ bool ots_post_serialise(OTSStream *out, OpenTypeFile *file) {
|
|||
return true; // v1.0 and v3.0 does not have glyph names.
|
||||
}
|
||||
|
||||
if (!out->WriteU16(post->glyph_name_index.size())) {
|
||||
const uint16_t num_indexes =
|
||||
static_cast<uint16_t>(post->glyph_name_index.size());
|
||||
if (num_indexes != post->glyph_name_index.size() ||
|
||||
!out->WriteU16(num_indexes)) {
|
||||
return OTS_FAILURE_MSG("Failed to write number of indices");
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < post->glyph_name_index.size(); ++i) {
|
||||
for (uint16_t i = 0; i < num_indexes; ++i) {
|
||||
if (!out->WriteU16(post->glyph_name_index[i])) {
|
||||
return OTS_FAILURE_MSG("Failed to write name index %d", i);
|
||||
}
|
||||
|
@ -161,8 +164,9 @@ bool ots_post_serialise(OTSStream *out, OpenTypeFile *file) {
|
|||
// Now we just have to write out the strings in the correct order
|
||||
for (unsigned i = 0; i < post->names.size(); ++i) {
|
||||
const std::string& s = post->names[i];
|
||||
const uint8_t string_length = s.size();
|
||||
if (!out->Write(&string_length, 1)) {
|
||||
const uint8_t string_length = static_cast<uint8_t>(s.size());
|
||||
if (string_length != s.size() ||
|
||||
!out->Write(&string_length, 1)) {
|
||||
return OTS_FAILURE_MSG("Failed to write string %d", i);
|
||||
}
|
||||
// Some ttf fonts (e.g., frank.ttf on Windows Vista) have zero-length name.
|
||||
|
|
|
@ -75,15 +75,17 @@ bool ots_vorg_should_serialise(OpenTypeFile *file) {
|
|||
|
||||
bool ots_vorg_serialise(OTSStream *out, OpenTypeFile *file) {
|
||||
OpenTypeVORG * const vorg = file->vorg;
|
||||
|
||||
if (!out->WriteU16(vorg->major_version) ||
|
||||
|
||||
const uint16_t num_metrics = static_cast<uint16_t>(vorg->metrics.size());
|
||||
if (num_metrics != vorg->metrics.size() ||
|
||||
!out->WriteU16(vorg->major_version) ||
|
||||
!out->WriteU16(vorg->minor_version) ||
|
||||
!out->WriteS16(vorg->default_vert_origin_y) ||
|
||||
!out->WriteU16(vorg->metrics.size())) {
|
||||
!out->WriteU16(num_metrics)) {
|
||||
return OTS_FAILURE_MSG("Failed to write table header");
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < vorg->metrics.size(); ++i) {
|
||||
for (uint16_t i = 0; i < num_metrics; ++i) {
|
||||
const OpenTypeVORGMetrics& rec = vorg->metrics[i];
|
||||
if (!out->WriteU16(rec.glyph_index) ||
|
||||
!out->WriteS16(rec.vert_origin_y)) {
|
||||
|
|
|
@ -21,12 +21,12 @@
|
|||
namespace {
|
||||
|
||||
// simple glyph flags
|
||||
const int kGlyfOnCurve = 1 << 0;
|
||||
const int kGlyfXShort = 1 << 1;
|
||||
const int kGlyfYShort = 1 << 2;
|
||||
const int kGlyfRepeat = 1 << 3;
|
||||
const int kGlyfThisXIsSame = 1 << 4;
|
||||
const int kGlyfThisYIsSame = 1 << 5;
|
||||
const uint8_t kGlyfOnCurve = 1 << 0;
|
||||
const uint8_t kGlyfXShort = 1 << 1;
|
||||
const uint8_t kGlyfYShort = 1 << 2;
|
||||
const uint8_t kGlyfRepeat = 1 << 3;
|
||||
const uint8_t kGlyfThisXIsSame = 1 << 4;
|
||||
const uint8_t kGlyfThisYIsSame = 1 << 5;
|
||||
|
||||
// composite glyph flags
|
||||
const int FLAG_ARG_1_AND_2_ARE_WORDS = 1 << 0;
|
||||
|
@ -122,8 +122,8 @@ const uint32_t kKnownTags[] = {
|
|||
};
|
||||
|
||||
struct Point {
|
||||
int x;
|
||||
int y;
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
bool on_curve;
|
||||
};
|
||||
|
||||
|
@ -149,11 +149,11 @@ struct Table {
|
|||
};
|
||||
|
||||
// Based on section 6.1.1 of MicroType Express draft spec
|
||||
bool Read255UShort(ots::Buffer* buf, unsigned int* value) {
|
||||
static const int kWordCode = 253;
|
||||
static const int kOneMoreByteCode2 = 254;
|
||||
static const int kOneMoreByteCode1 = 255;
|
||||
static const int kLowestUCode = 253;
|
||||
bool Read255UShort(ots::Buffer* buf, uint16_t* value) {
|
||||
static const uint8_t kWordCode = 253;
|
||||
static const uint8_t kOneMoreByteCode2 = 254;
|
||||
static const uint8_t kOneMoreByteCode1 = 255;
|
||||
static const uint8_t kLowestUCode = 253;
|
||||
uint8_t code = 0;
|
||||
if (!buf->ReadU8(&code)) {
|
||||
return OTS_FAILURE();
|
||||
|
@ -211,15 +211,15 @@ bool ReadBase128(ots::Buffer* buf, uint32_t* value) {
|
|||
// and use it across the code.
|
||||
size_t StoreU32(uint8_t* dst, size_t offset, uint32_t x) {
|
||||
dst[offset] = x >> 24;
|
||||
dst[offset + 1] = x >> 16;
|
||||
dst[offset + 2] = x >> 8;
|
||||
dst[offset + 3] = x;
|
||||
dst[offset + 1] = (x >> 16) & 0xff;
|
||||
dst[offset + 2] = (x >> 8) & 0xff;
|
||||
dst[offset + 3] = x & 0xff;
|
||||
return offset + 4;
|
||||
}
|
||||
|
||||
size_t Store16(uint8_t* dst, size_t offset, int x) {
|
||||
size_t StoreU16(uint8_t* dst, size_t offset, uint16_t x) {
|
||||
dst[offset] = x >> 8;
|
||||
dst[offset + 1] = x;
|
||||
dst[offset + 1] = x & 0xff;
|
||||
return offset + 2;
|
||||
}
|
||||
|
||||
|
@ -290,8 +290,8 @@ bool TripletDecode(const uint8_t* flags_in, const uint8_t* in, size_t in_size,
|
|||
y += dy;
|
||||
result->push_back(Point());
|
||||
Point& back = result->back();
|
||||
back.x = x;
|
||||
back.y = y;
|
||||
back.x = static_cast<int16_t>(x);
|
||||
back.y = static_cast<int16_t>(y);
|
||||
back.on_curve = on_curve;
|
||||
}
|
||||
*in_bytes_consumed = triplet_index;
|
||||
|
@ -307,8 +307,8 @@ bool StorePoints(const std::vector<Point>& points,
|
|||
// comment and/or an assert would be good.
|
||||
unsigned int flag_offset = kEndPtsOfContoursOffset + 2 * n_contours + 2 +
|
||||
instruction_length;
|
||||
int last_flag = -1;
|
||||
int repeat_count = 0;
|
||||
uint8_t last_flag = 0xff;
|
||||
uint8_t repeat_count = 0;
|
||||
int last_x = 0;
|
||||
int last_y = 0;
|
||||
unsigned int x_bytes = 0;
|
||||
|
@ -316,7 +316,7 @@ bool StorePoints(const std::vector<Point>& points,
|
|||
|
||||
for (size_t i = 0; i < points.size(); ++i) {
|
||||
const Point& point = points.at(i);
|
||||
int flag = point.on_curve ? kGlyfOnCurve : 0;
|
||||
uint8_t flag = point.on_curve ? kGlyfOnCurve : 0;
|
||||
int dx = point.x - last_x;
|
||||
int dy = point.y - last_y;
|
||||
if (dx == 0) {
|
||||
|
@ -379,19 +379,19 @@ bool StorePoints(const std::vector<Point>& points,
|
|||
if (dx == 0) {
|
||||
// pass
|
||||
} else if (dx > -256 && dx < 256) {
|
||||
dst[x_offset++] = std::abs(dx);
|
||||
dst[x_offset++] = static_cast<uint8_t>(std::abs(dx));
|
||||
} else {
|
||||
// will always fit for valid input, but overflow is harmless
|
||||
x_offset = Store16(dst, x_offset, dx);
|
||||
x_offset = StoreU16(dst, x_offset, static_cast<uint16_t>(dx));
|
||||
}
|
||||
last_x += dx;
|
||||
int dy = points.at(i).y - last_y;
|
||||
if (dy == 0) {
|
||||
// pass
|
||||
} else if (dy > -256 && dy < 256) {
|
||||
dst[y_offset++] = std::abs(dy);
|
||||
dst[y_offset++] = static_cast<uint8_t>(std::abs(dy));
|
||||
} else {
|
||||
y_offset = Store16(dst, y_offset, dy);
|
||||
y_offset = StoreU16(dst, y_offset, static_cast<uint16_t>(dy));
|
||||
}
|
||||
last_y += dy;
|
||||
}
|
||||
|
@ -402,24 +402,24 @@ bool StorePoints(const std::vector<Point>& points,
|
|||
// Compute the bounding box of the coordinates, and store into a glyf buffer.
|
||||
// A precondition is that there are at least 10 bytes available.
|
||||
void ComputeBbox(const std::vector<Point>& points, uint8_t* dst) {
|
||||
int x_min = 0;
|
||||
int y_min = 0;
|
||||
int x_max = 0;
|
||||
int y_max = 0;
|
||||
int16_t x_min = 0;
|
||||
int16_t y_min = 0;
|
||||
int16_t x_max = 0;
|
||||
int16_t y_max = 0;
|
||||
|
||||
for (size_t i = 0; i < points.size(); ++i) {
|
||||
int x = points.at(i).x;
|
||||
int y = points.at(i).y;
|
||||
int16_t x = points.at(i).x;
|
||||
int16_t y = points.at(i).y;
|
||||
if (i == 0 || x < x_min) x_min = x;
|
||||
if (i == 0 || x > x_max) x_max = x;
|
||||
if (i == 0 || y < y_min) y_min = y;
|
||||
if (i == 0 || y > y_max) y_max = y;
|
||||
}
|
||||
size_t offset = 2;
|
||||
offset = Store16(dst, offset, x_min);
|
||||
offset = Store16(dst, offset, y_min);
|
||||
offset = Store16(dst, offset, x_max);
|
||||
offset = Store16(dst, offset, y_max);
|
||||
offset = StoreU16(dst, offset, x_min);
|
||||
offset = StoreU16(dst, offset, y_min);
|
||||
offset = StoreU16(dst, offset, x_max);
|
||||
offset = StoreU16(dst, offset, y_max);
|
||||
}
|
||||
|
||||
// Process entire bbox stream. This is done as a separate pass to allow for
|
||||
|
@ -486,7 +486,7 @@ bool ProcessComposite(ots::Buffer* composite_stream, uint8_t* dst,
|
|||
if (composite_glyph_size + kCompositeGlyphBegin > dst_size) {
|
||||
return OTS_FAILURE();
|
||||
}
|
||||
Store16(dst, 0, 0xffff); // nContours = -1 for composite glyph
|
||||
StoreU16(dst, 0, 0xffff); // nContours = -1 for composite glyph
|
||||
std::memcpy(dst + kCompositeGlyphBegin,
|
||||
composite_stream->buffer() + start_offset,
|
||||
composite_glyph_size);
|
||||
|
@ -513,7 +513,7 @@ bool StoreLoca(const std::vector<uint32_t>& loca_values, int index_format,
|
|||
if (index_format) {
|
||||
offset = StoreU32(dst, offset, value);
|
||||
} else {
|
||||
offset = Store16(dst, offset, value >> 1);
|
||||
offset = StoreU16(dst, offset, static_cast<uint16_t>(value >> 1));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -564,7 +564,7 @@ bool ReconstructGlyf(const uint8_t* data, size_t data_size,
|
|||
|
||||
std::vector<uint32_t> loca_values;
|
||||
loca_values.reserve(num_glyphs + 1);
|
||||
std::vector<unsigned int> n_points_vec;
|
||||
std::vector<uint16_t> n_points_vec;
|
||||
std::vector<Point> points;
|
||||
uint32_t loca_offset = 0;
|
||||
for (unsigned int i = 0; i < num_glyphs; ++i) {
|
||||
|
@ -578,7 +578,7 @@ bool ReconstructGlyf(const uint8_t* data, size_t data_size,
|
|||
if (n_contours == 0xffff) {
|
||||
// composite glyph
|
||||
bool have_instructions = false;
|
||||
unsigned int instruction_size = 0;
|
||||
uint16_t instruction_size = 0;
|
||||
if (!ProcessComposite(&composite_stream, glyf_dst, glyf_dst_size,
|
||||
&glyph_size, &have_instructions)) {
|
||||
return OTS_FAILURE();
|
||||
|
@ -588,10 +588,10 @@ bool ReconstructGlyf(const uint8_t* data, size_t data_size,
|
|||
return OTS_FAILURE();
|
||||
}
|
||||
// No integer overflow here (instruction_size < 2^16).
|
||||
if (instruction_size + 2 > glyf_dst_size - glyph_size) {
|
||||
if (instruction_size + 2U > glyf_dst_size - glyph_size) {
|
||||
return OTS_FAILURE();
|
||||
}
|
||||
Store16(glyf_dst, glyph_size, instruction_size);
|
||||
StoreU16(glyf_dst, glyph_size, instruction_size);
|
||||
if (!instruction_stream.Read(glyf_dst + glyph_size + 2,
|
||||
instruction_size)) {
|
||||
return OTS_FAILURE();
|
||||
|
@ -602,9 +602,9 @@ bool ReconstructGlyf(const uint8_t* data, size_t data_size,
|
|||
// simple glyph
|
||||
n_points_vec.clear();
|
||||
points.clear();
|
||||
unsigned int total_n_points = 0;
|
||||
unsigned int n_points_contour;
|
||||
for (unsigned int j = 0; j < n_contours; ++j) {
|
||||
uint32_t total_n_points = 0;
|
||||
uint16_t n_points_contour;
|
||||
for (uint32_t j = 0; j < n_contours; ++j) {
|
||||
if (!Read255UShort(&n_points_stream, &n_points_contour)) {
|
||||
return OTS_FAILURE();
|
||||
}
|
||||
|
@ -614,7 +614,7 @@ bool ReconstructGlyf(const uint8_t* data, size_t data_size,
|
|||
}
|
||||
total_n_points += n_points_contour;
|
||||
}
|
||||
unsigned int flag_size = total_n_points;
|
||||
uint32_t flag_size = total_n_points;
|
||||
if (flag_size > flag_stream.length() - flag_stream.offset()) {
|
||||
return OTS_FAILURE();
|
||||
}
|
||||
|
@ -632,7 +632,7 @@ bool ReconstructGlyf(const uint8_t* data, size_t data_size,
|
|||
if (glyf_dst_size < header_and_endpts_contours_size) {
|
||||
return OTS_FAILURE();
|
||||
}
|
||||
Store16(glyf_dst, 0, n_contours);
|
||||
StoreU16(glyf_dst, 0, n_contours);
|
||||
ComputeBbox(points, glyf_dst);
|
||||
size_t endpts_offset = kEndPtsOfContoursOffset;
|
||||
int end_point = -1;
|
||||
|
@ -641,7 +641,7 @@ bool ReconstructGlyf(const uint8_t* data, size_t data_size,
|
|||
if (end_point >= 65536) {
|
||||
return OTS_FAILURE();
|
||||
}
|
||||
endpts_offset = Store16(glyf_dst, endpts_offset, end_point);
|
||||
endpts_offset = StoreU16(glyf_dst, endpts_offset, static_cast<uint16_t>(end_point));
|
||||
}
|
||||
if (!flag_stream.Skip(flag_size)) {
|
||||
return OTS_FAILURE();
|
||||
|
@ -649,17 +649,17 @@ bool ReconstructGlyf(const uint8_t* data, size_t data_size,
|
|||
if (!glyph_stream.Skip(triplet_bytes_consumed)) {
|
||||
return OTS_FAILURE();
|
||||
}
|
||||
unsigned int instruction_size;
|
||||
uint16_t instruction_size;
|
||||
if (!Read255UShort(&glyph_stream, &instruction_size)) {
|
||||
return OTS_FAILURE();
|
||||
}
|
||||
// No integer overflow here (instruction_size < 2^16).
|
||||
if (glyf_dst_size - header_and_endpts_contours_size <
|
||||
instruction_size + 2) {
|
||||
instruction_size + 2U) {
|
||||
return OTS_FAILURE();
|
||||
}
|
||||
uint8_t* instruction_dst = glyf_dst + header_and_endpts_contours_size;
|
||||
Store16(instruction_dst, 0, instruction_size);
|
||||
StoreU16(instruction_dst, 0, instruction_size);
|
||||
if (!instruction_stream.Read(instruction_dst + 2, instruction_size)) {
|
||||
return OTS_FAILURE();
|
||||
}
|
||||
|
@ -915,14 +915,14 @@ bool ConvertWOFF2ToTTF(uint8_t* result, size_t result_length,
|
|||
uint64_t uncompressed_sum = 0;
|
||||
for (uint16_t i = 0; i < num_tables; ++i) {
|
||||
Table* table = &tables.at(i);
|
||||
table->src_offset = src_offset;
|
||||
table->src_offset = static_cast<uint32_t>(src_offset);
|
||||
table->src_length = (i == 0 ? compressed_length : 0);
|
||||
src_offset += table->src_length;
|
||||
if (src_offset > std::numeric_limits<uint32_t>::max()) {
|
||||
return OTS_FAILURE();
|
||||
}
|
||||
src_offset = ots::Round4(src_offset);
|
||||
table->dst_offset = dst_offset;
|
||||
table->dst_offset = static_cast<uint32_t>(dst_offset);
|
||||
dst_offset += table->dst_length;
|
||||
if (dst_offset > std::numeric_limits<uint32_t>::max()) {
|
||||
return OTS_FAILURE();
|
||||
|
@ -951,15 +951,15 @@ bool ConvertWOFF2ToTTF(uint8_t* result, size_t result_length,
|
|||
// Start building the font
|
||||
size_t offset = 0;
|
||||
offset = StoreU32(result, offset, flavor);
|
||||
offset = Store16(result, offset, num_tables);
|
||||
unsigned max_pow2 = 0;
|
||||
offset = StoreU16(result, offset, num_tables);
|
||||
uint8_t max_pow2 = 0;
|
||||
while (1u << (max_pow2 + 1) <= num_tables) {
|
||||
max_pow2++;
|
||||
}
|
||||
const uint16_t output_search_range = (1u << max_pow2) << 4;
|
||||
offset = Store16(result, offset, output_search_range);
|
||||
offset = Store16(result, offset, max_pow2);
|
||||
offset = Store16(result, offset, (num_tables << 4) - output_search_range);
|
||||
offset = StoreU16(result, offset, output_search_range);
|
||||
offset = StoreU16(result, offset, max_pow2);
|
||||
offset = StoreU16(result, offset, (num_tables << 4) - output_search_range);
|
||||
for (uint16_t i = 0; i < num_tables; ++i) {
|
||||
const Table* table = &tables.at(i);
|
||||
offset = StoreU32(result, offset, table->tag);
|
||||
|
@ -1001,8 +1001,9 @@ bool ConvertWOFF2ToTTF(uint8_t* result, size_t result_length,
|
|||
if (total_size > 30 * 1024 * 1024) {
|
||||
return OTS_FAILURE();
|
||||
}
|
||||
uncompressed_buf.resize(total_size);
|
||||
if (!Woff2Uncompress(&uncompressed_buf[0], total_size,
|
||||
const size_t total_size_size_t = static_cast<size_t>(total_size);
|
||||
uncompressed_buf.resize(total_size_size_t);
|
||||
if (!Woff2Uncompress(&uncompressed_buf[0], total_size_size_t,
|
||||
src_buf, compressed_length, compression_type)) {
|
||||
return OTS_FAILURE();
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ cp $1/LICENSE .
|
|||
|
||||
echo "Updating src..."
|
||||
cd src
|
||||
ls --ignore moz.build | xargs rm -rf
|
||||
ls | fgrep -v moz.build | xargs rm -rf
|
||||
cp -r $1/src/* .
|
||||
cd ..
|
||||
|
||||
|
@ -22,7 +22,10 @@ cp -r $1/include .
|
|||
|
||||
echo "Updating README.mozilla..."
|
||||
REVISION=`cd $1; git log | head -1 | sed "s/commit //"`
|
||||
sed "s/\(Current revision: \).*/\1$REVISION/" -i README.mozilla
|
||||
sed -e "s/\(Current revision: \).*/\1$REVISION/" -i "" README.mozilla
|
||||
|
||||
echo "Applying ots-visibility.patch..."
|
||||
patch -p3 < ots-visibility.patch
|
||||
|
||||
echo "Applying ots-brotli-path.patch..."
|
||||
patch -p3 < ots-brotli-path.patch
|
||||
|
|
|
@ -194,7 +194,8 @@ public:
|
|||
return ots::TABLE_ACTION_DEFAULT;
|
||||
}
|
||||
|
||||
virtual void Message(const char* format, ...) MSGFUNC_FMT_ATTR MOZ_OVERRIDE {
|
||||
virtual void Message(int level, const char* format,
|
||||
...) MSGFUNC_FMT_ATTR MOZ_OVERRIDE {
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче