Bug 699420 - Update OTS to r74; r=jfkthame

This commit is contained in:
Masatoshi Kimura 2011-11-04 01:26:56 +00:00
parent 2e4e1bd781
commit 4951063a0d
15 changed files with 246 additions and 259 deletions

View File

@ -1,10 +1,8 @@
This is the Sanitiser for OpenType project, from http://code.google.com/p/ots/.
Current revision: r62
Current revision: r74
Applied local patches:
ots-fix-vc10.patch - workaround for VS10 STL wrappers (bug 602558)
ots-fix-gcc46.patch - fix os2.cc compile error for GCC 4.6 (bug 628252)
ots-fix-sparc64.patch - fix alignment error on sparc64 (bug 643137)

View File

@ -22,6 +22,7 @@ typedef unsigned __int64 uint64_t;
#include <algorithm> // for std::min
#include <cassert>
#include <cstddef>
#include <cstring>
namespace ots {

View File

@ -1,18 +0,0 @@
diff --git a/gfx/ots/src/os2.cc b/gfx/ots/src/os2.cc
--- a/gfx/ots/src/os2.cc
+++ b/gfx/ots/src/os2.cc
@@ -1,12 +1,14 @@
// Copyright (c) 2009 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.
+#include <cstddef>
+
#include "os2.h"
#include "head.h"
// OS/2 - OS/2 and Windows Metrics
// http://www.microsoft.com/opentype/otspec/os2.htm
namespace ots {

View File

@ -189,13 +189,15 @@ bool ParseDictDataBcd(
if ((nibble & 0xf) == 0xf) {
// TODO(yusukes): would be better to store actual double value,
// rather than the dummy integer.
operands->push_back(std::make_pair(0, DICT_OPERAND_REAL));
operands->push_back(std::make_pair(static_cast<uint32_t>(0),
DICT_OPERAND_REAL));
return true;
}
return OTS_FAILURE();
}
if ((nibble & 0x0f) == 0x0f) {
operands->push_back(std::make_pair(0, DICT_OPERAND_REAL));
operands->push_back(std::make_pair(static_cast<uint32_t>(0),
DICT_OPERAND_REAL));
return true;
}
@ -264,7 +266,8 @@ bool ParseDictDataNumber(
!table->ReadU8(&b2)) {
return OTS_FAILURE();
}
operands->push_back(std::make_pair((b1 << 8) + b2, DICT_OPERAND_INTEGER));
operands->push_back(std::make_pair(
static_cast<uint32_t>((b1 << 8) + b2), DICT_OPERAND_INTEGER));
return true;
case 29: // longint
@ -275,7 +278,8 @@ bool ParseDictDataNumber(
return OTS_FAILURE();
}
operands->push_back(std::make_pair(
(b1 << 24) + (b2 << 16) + (b3 << 8) + b4, DICT_OPERAND_INTEGER));
static_cast<uint32_t>((b1 << 24) + (b2 << 16) + (b3 << 8) + b4),
DICT_OPERAND_INTEGER));
return true;
case 30: // binary coded decimal
@ -317,7 +321,8 @@ bool ParseDictDataReadNext(
if (op == 12) {
return ParseDictDataEscapedOperator(table, operands);
}
operands->push_back(std::make_pair(op, DICT_OPERATOR));
operands->push_back(std::make_pair(
static_cast<uint32_t>(op), DICT_OPERATOR));
return true;
} else if (op <= 27 || op == 31 || op == 255) {
// reserved area.

View File

@ -4,6 +4,7 @@
#include "cmap.h"
#include <algorithm>
#include <set>
#include <utility>
#include <vector>
@ -694,9 +695,10 @@ bool ots_cmap_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
continue;
}
overlap_checker.push_back(
std::make_pair(subtable_headers[i].offset, 1 /* start */));
std::make_pair(subtable_headers[i].offset,
static_cast<uint8_t>(1) /* start */));
overlap_checker.push_back(
std::make_pair(end_byte, 0 /* end */));
std::make_pair(end_byte, static_cast<uint8_t>(0) /* end */));
}
std::sort(overlap_checker.begin(), overlap_checker.end());
int overlap_count = 0;

View File

@ -42,7 +42,8 @@ bool ParseAttachListTable(ots::OpenTypeFile *file, const uint8_t *data,
!subtable.ReadU16(&glyph_count)) {
return OTS_FAILURE();
}
const unsigned attach_points_end = static_cast<unsigned>(4) + 2*glyph_count;
const unsigned attach_points_end =
2 * static_cast<unsigned>(glyph_count) + 4;
if (attach_points_end > std::numeric_limits<uint16_t>::max()) {
return OTS_FAILURE();
}
@ -110,7 +111,8 @@ bool ParseLigCaretListTable(ots::OpenTypeFile *file, const uint8_t *data,
!subtable.ReadU16(&lig_glyph_count)) {
return OTS_FAILURE();
}
const unsigned lig_glyphs_end = static_cast<unsigned>(4) + 2*lig_glyph_count;
const unsigned lig_glyphs_end =
2 * static_cast<unsigned>(lig_glyph_count) + 4;
if (lig_glyphs_end > std::numeric_limits<uint16_t>::max()) {
return OTS_FAILURE();
}
@ -155,7 +157,7 @@ bool ParseLigCaretListTable(ots::OpenTypeFile *file, const uint8_t *data,
std::vector<uint16_t> caret_values;
caret_values.resize(caret_count);
uint16_t last_offset_caret = 0;
unsigned caret_values_end = static_cast<unsigned>(2) + 2*caret_count;
unsigned caret_values_end = 2 * static_cast<unsigned>(caret_count) + 2;
for (unsigned j = 0; j < caret_count; ++j) {
if (!subtable.ReadU16(&caret_values[j])) {
return OTS_FAILURE();
@ -215,7 +217,7 @@ bool ParseMarkGlyphSetsDefTable(ots::OpenTypeFile *file, const uint8_t *data,
return OTS_FAILURE();
}
const unsigned mark_sets_end = static_cast<unsigned>(4) + 2*mark_set_count;
const unsigned mark_sets_end = 2 * static_cast<unsigned>(mark_set_count) + 4;
if (mark_sets_end > std::numeric_limits<uint16_t>::max()) {
return OTS_FAILURE();
}
@ -288,11 +290,9 @@ bool ots_gdef_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
}
}
const unsigned gdef_header_end = static_cast<unsigned>(8) +
gdef->version_2 ? static_cast<unsigned>(2) : static_cast<unsigned>(0);
if (gdef_header_end > std::numeric_limits<uint16_t>::max()) {
return OTS_FAILURE();
}
unsigned gdef_header_end = 8;
if (gdef->version_2)
gdef_header_end += 2;
// Parse subtables
if (offset_glyph_class_def) {

View File

@ -111,13 +111,16 @@ bool ParseSimpleGlyph(ots::OpenTypeFile *file, const uint8_t *data,
if (ots::g_transcode_hints) {
glyf->iov.push_back(std::make_pair(
data + gly_offset, gly_header_length + bytecode_length));
data + gly_offset,
static_cast<size_t>(gly_header_length + bytecode_length)));
} else {
// enqueue two vectors: the glyph data up to the bytecode length, then
// a pointer to a static uint16_t 0 to overwrite the length.
glyf->iov.push_back(std::make_pair(
data + gly_offset, gly_header_length - 2));
glyf->iov.push_back(std::make_pair((const uint8_t*) "\x00\x00", 2));
data + gly_offset,
static_cast<size_t>(gly_header_length - 2)));
glyf->iov.push_back(std::make_pair((const uint8_t*) "\x00\x00",
static_cast<size_t>(2)));
}
if (!table->Skip(bytecode_length)) {
@ -153,7 +156,7 @@ bool ParseSimpleGlyph(ots::OpenTypeFile *file, const uint8_t *data,
glyf->iov.push_back(std::make_pair(
data + gly_offset + gly_header_length + bytecode_length,
flags_count_physical + xy_coordinates_length));
static_cast<size_t>(flags_count_physical + xy_coordinates_length)));
*new_size
= gly_header_length + flags_count_physical + xy_coordinates_length;
@ -247,7 +250,8 @@ bool ots_glyf_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
}
} else {
// it's a composite glyph without any bytecode. Enqueue the whole thing
glyf->iov.push_back(std::make_pair(data + gly_offset, gly_length));
glyf->iov.push_back(std::make_pair(data + gly_offset,
static_cast<size_t>(gly_length)));
new_size = gly_length;
}
@ -258,7 +262,8 @@ bool ots_glyf_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
const unsigned padding = (4 - (new_size & 3)) % 4;
if (padding) {
glyf->iov.push_back(std::make_pair(
reinterpret_cast<const uint8_t*>("\x00\x00\x00\x00"), padding));
reinterpret_cast<const uint8_t*>("\x00\x00\x00\x00"),
static_cast<size_t>(padding)));
new_size += padding;
}
current_offset += new_size;

View File

@ -171,7 +171,7 @@ bool ParseMarkArrayTable(const uint8_t *data, const size_t length,
}
// MarkRecord consists of 4-bytes.
const unsigned mark_records_end = static_cast<unsigned>(2) + mark_count * 4;
const unsigned mark_records_end = 4 * static_cast<unsigned>(mark_count) + 2;
if (mark_records_end > std::numeric_limits<uint16_t>::max()) {
return OTS_FAILURE();
}
@ -289,8 +289,7 @@ bool ParsePairPosFormat1(const uint8_t *data, const size_t length,
return OTS_FAILURE();
}
const unsigned pair_pos_end = static_cast<unsigned>(10) +
pair_set_count * 2;
const unsigned pair_pos_end = 2 * static_cast<unsigned>(pair_set_count) + 10;
if (pair_pos_end > std::numeric_limits<uint16_t>::max()) {
return OTS_FAILURE();
}
@ -432,8 +431,8 @@ bool ParseCursiveAttachment(const ots::OpenTypeFile *file, const uint8_t *data,
}
// Check entry exit records.
const unsigned entry_exit_records_end = static_cast<unsigned>(6) +
entry_exit_count * 2;
const unsigned entry_exit_records_end =
2 * static_cast<unsigned>(entry_exit_count) + 6;
if (entry_exit_records_end > std::numeric_limits<uint16_t>::max()) {
return OTS_FAILURE();
}
@ -488,8 +487,8 @@ bool ParseAnchorArrayTable(const uint8_t *data, const size_t length,
return OTS_FAILURE();
}
const unsigned anchor_array_end = static_cast<unsigned>(2) +
record_count * class_count * 2;
const unsigned anchor_array_end = 2 * static_cast<unsigned>(record_count) *
static_cast<unsigned>(class_count) + 2;
if (anchor_array_end > std::numeric_limits<uint16_t>::max()) {
return OTS_FAILURE();
}

View File

@ -392,24 +392,6 @@ bool ParseLigatureSubstitution(const ots::OpenTypeFile *file,
return true;
}
bool ParseSubstLookupRecord(ots::Buffer *subtable, const uint16_t num_glyphs,
const uint16_t num_lookups) {
uint16_t sequence_index = 0;
uint16_t lookup_list_index = 0;
if (!subtable->ReadU16(&sequence_index) ||
!subtable->ReadU16(&lookup_list_index)) {
return OTS_FAILURE();
}
if (sequence_index >= num_glyphs) {
return OTS_FAILURE();
}
if (lookup_list_index >= num_lookups) {
return OTS_FAILURE();
}
return true;
}
// Lookup Type 5:
// Contextual Substitution Subtable
bool ParseContextSubstitution(const ots::OpenTypeFile *file,

View File

@ -97,8 +97,8 @@ bool ParseScriptTable(const uint8_t *data, const size_t length,
return OTS_FAILURE();
}
const unsigned lang_sys_record_end = static_cast<unsigned>(4) +
lang_sys_count * 6;
const unsigned lang_sys_record_end =
6 * static_cast<unsigned>(lang_sys_count) + 4;
if (lang_sys_record_end > std::numeric_limits<uint16_t>::max()) {
return OTS_FAILURE();
}
@ -146,8 +146,8 @@ bool ParseFeatureTable(const uint8_t *data, const size_t length,
return OTS_FAILURE();
}
const unsigned feature_table_end = static_cast<unsigned>(4) +
num_lookups * 2;
const unsigned feature_table_end =
2 * static_cast<unsigned>(num_lookups) + 4;
if (feature_table_end > std::numeric_limits<uint16_t>::max()) {
return OTS_FAILURE();
}
@ -210,9 +210,8 @@ bool ParseLookupTable(ots::OpenTypeFile *file, const uint8_t *data,
subtables.reserve(subtable_count);
// If the |kUseMarkFilteringSetBit| of |lookup_flag| is set,
// extra 2 bytes will follow after subtable offset array.
const unsigned lookup_table_end =
static_cast<unsigned>(use_mark_filtering_set ? 8 : 6) +
subtable_count * 2;
const unsigned lookup_table_end = 2 * static_cast<unsigned>(subtable_count) +
(use_mark_filtering_set ? 8 : 6);
if (lookup_table_end > std::numeric_limits<uint16_t>::max()) {
return OTS_FAILURE();
}
@ -471,8 +470,7 @@ bool ParseRuleSetTable(const uint8_t *data, const size_t length,
if (!subtable.ReadU16(&rule_count)) {
return OTS_FAILURE();
}
const unsigned rule_end = static_cast<unsigned>(2) +
rule_count * 2;
const unsigned rule_end = 2 * static_cast<unsigned>(rule_count) + 2;
if (rule_end > std::numeric_limits<uint16_t>::max()) {
return OTS_FAILURE();
}
@ -578,8 +576,8 @@ bool ParseClassSetTable(const uint8_t *data, const size_t length,
if (!subtable.ReadU16(&class_rule_count)) {
return OTS_FAILURE();
}
const unsigned class_rule_end = static_cast<unsigned>(2) +
class_rule_count * 2;
const unsigned class_rule_end =
2 * static_cast<unsigned>(class_rule_count) + 2;
if (class_rule_end > std::numeric_limits<uint16_t>::max()) {
return OTS_FAILURE();
}
@ -617,8 +615,7 @@ bool ParseContextFormat2(const uint8_t *data, const size_t length,
return OTS_FAILURE();
}
const unsigned class_set_end = static_cast<unsigned>(8) +
class_set_cnt * 2;
const unsigned class_set_end = 2 * static_cast<unsigned>(class_set_cnt) + 8;
if (class_set_end > std::numeric_limits<uint16_t>::max()) {
return OTS_FAILURE();
}
@ -676,8 +673,8 @@ bool ParseContextFormat3(const uint8_t *data, const size_t length,
if (glyph_count >= num_glyphs) {
return OTS_FAILURE();
}
const unsigned lookup_record_end = static_cast<unsigned>(6) +
glyph_count * 2 + lookup_count * 4;
const unsigned lookup_record_end = 2 * static_cast<unsigned>(glyph_count) +
4 * static_cast<unsigned>(lookup_count) + 6;
if (lookup_record_end > std::numeric_limits<uint16_t>::max()) {
return OTS_FAILURE();
}
@ -784,8 +781,8 @@ bool ParseChainRuleSetTable(const uint8_t *data, const size_t length,
if (!subtable.ReadU16(&chain_rule_count)) {
return OTS_FAILURE();
}
const unsigned chain_rule_end = static_cast<unsigned>(2) +
chain_rule_count * 2;
const unsigned chain_rule_end =
2 * static_cast<unsigned>(chain_rule_count) + 2;
if (chain_rule_end > std::numeric_limits<uint16_t>::max()) {
return OTS_FAILURE();
}
@ -821,8 +818,8 @@ bool ParseChainContextFormat1(const uint8_t *data, const size_t length,
return OTS_FAILURE();
}
const unsigned chain_rule_set_end = static_cast<unsigned>(6) +
chain_rule_set_count * 2;
const unsigned chain_rule_set_end =
2 * static_cast<unsigned>(chain_rule_set_count) + 6;
if (chain_rule_set_end > std::numeric_limits<uint16_t>::max()) {
return OTS_FAILURE();
}
@ -916,8 +913,8 @@ bool ParseChainClassSetTable(const uint8_t *data, const size_t length,
if (!subtable.ReadU16(&chain_class_rule_count)) {
return OTS_FAILURE();
}
const unsigned chain_class_rule_end = static_cast<unsigned>(2) +
chain_class_rule_count * 2;
const unsigned chain_class_rule_end =
2 * static_cast<unsigned>(chain_class_rule_count) + 2;
if (chain_class_rule_end > std::numeric_limits<uint16_t>::max()) {
return OTS_FAILURE();
}
@ -960,8 +957,8 @@ bool ParseChainContextFormat2(const uint8_t *data, const size_t length,
return OTS_FAILURE();
}
const unsigned chain_class_set_end = static_cast<unsigned>(12) +
chain_class_set_count * 2;
const unsigned chain_class_set_end =
2 * static_cast<unsigned>(chain_class_set_count) + 12;
if (chain_class_set_end > std::numeric_limits<uint16_t>::max()) {
return OTS_FAILURE();
}
@ -1108,8 +1105,11 @@ bool ParseChainContextFormat3(const uint8_t *data, const size_t length,
}
}
const unsigned lookup_record_end = static_cast<unsigned>(10) +
(backtrack_count + input_count + lookahead_count) * 2 + lookup_count * 4;
const unsigned lookup_record_end =
2 * (static_cast<unsigned>(backtrack_count) +
static_cast<unsigned>(input_count) +
static_cast<unsigned>(lookahead_count)) +
4 * static_cast<unsigned>(lookup_count) + 10;
if (lookup_record_end > std::numeric_limits<uint16_t>::max()) {
return OTS_FAILURE();
}
@ -1175,8 +1175,8 @@ bool ParseScriptListTable(const uint8_t *data, const size_t length,
return OTS_FAILURE();
}
const unsigned script_record_end = static_cast<unsigned>(2) +
script_count * 6;
const unsigned script_record_end =
6 * static_cast<unsigned>(script_count) + 2;
if (script_record_end > std::numeric_limits<uint16_t>::max()) {
return OTS_FAILURE();
}
@ -1232,8 +1232,8 @@ bool ParseFeatureListTable(const uint8_t *data, const size_t length,
std::vector<FeatureRecord> feature_records;
feature_records.resize(feature_count);
const unsigned feature_record_end = static_cast<unsigned>(2) +
feature_count * 6;
const unsigned feature_record_end =
6 * static_cast<unsigned>(feature_count) + 2;
if (feature_record_end > std::numeric_limits<uint16_t>::max()) {
return OTS_FAILURE();
}
@ -1282,8 +1282,8 @@ bool ParseLookupListTable(OpenTypeFile *file, const uint8_t *data,
std::vector<uint16_t> lookups;
lookups.reserve(*num_lookups);
const unsigned lookup_end = static_cast<unsigned>(2) +
(*num_lookups) * 2;
const unsigned lookup_end =
2 * static_cast<unsigned>(*num_lookups) + 2;
if (lookup_end > std::numeric_limits<uint16_t>::max()) {
return OTS_FAILURE();
}

View File

@ -1,4 +1,4 @@
// Copyright (c) 2011 Mozilla Foundation. All rights reserved.
// Copyright (c) 2011 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.
@ -12,173 +12,179 @@
// name - Naming Table
// http://www.microsoft.com/opentype/otspec/name.htm
namespace { // misc local helper functions
namespace {
inline bool
valid_in_ps_name(char c) {
bool ValidInPsName(char c) {
return (c > 0x20 && c < 0x7f && !std::strchr("[](){}<>/%", c));
}
inline bool
check_ps_name_ascii(std::string& name) {
for (unsigned int i = 0; i < name.size(); ++i) {
if (!valid_in_ps_name(name[i])) {
bool CheckPsNameAscii(const std::string& name) {
for (unsigned i = 0; i < name.size(); ++i) {
if (!ValidInPsName(name[i])) {
return false;
}
}
return true;
}
inline bool
check_ps_name_utf16_be(std::string& name) {
for (unsigned int i = 0; i < name.size(); i += 2) {
bool CheckPsNameUtf16Be(const std::string& name) {
if ((name.size() & 1) != 0)
return false;
for (unsigned i = 0; i < name.size(); i += 2) {
if (name[i] != 0) {
return false;
}
if (!valid_in_ps_name(name[i+1])) {
if (!ValidInPsName(name[i+1])) {
return false;
}
}
return true;
}
void
assign_to_utf16_be_from_ascii(std::string& target, const std::string& source) {
target.resize(source.size() * 2);
for (unsigned int i = 0, j = 0; i < source.size(); i++) {
target[j++] = '\0';
target[j++] = source[i];
void AssignToUtf16BeFromAscii(std::string* target,
const std::string& source) {
target->resize(source.size() * 2);
for (unsigned i = 0, j = 0; i < source.size(); i++) {
(*target)[j++] = '\0';
(*target)[j++] = source[i];
}
}
} // end anonymous namespace
} // namespace
namespace ots {
bool ots_name_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
bool ots_name_parse(OpenTypeFile* file, const uint8_t* data, size_t length) {
Buffer table(data, length);
OpenTypeNAME *name = new OpenTypeNAME;
OpenTypeNAME* name = new OpenTypeNAME;
file->name = name;
uint16_t format;
uint16_t format = 0;
if (!table.ReadU16(&format) || format > 1) {
return OTS_FAILURE();
}
uint16_t count;
uint16_t count = 0;
if (!table.ReadU16(&count)) {
return OTS_FAILURE();
}
uint16_t stringOffset;
if (!table.ReadU16(&stringOffset) || stringOffset > length) {
uint16_t string_offset = 0;
if (!table.ReadU16(&string_offset) || string_offset > length) {
return OTS_FAILURE();
}
const char* stringBase = (const char*)data + stringOffset;
const char* string_base = reinterpret_cast<const char*>(data) +
string_offset;
NameRecord prevRec;
bool sortRequired = false;
NameRecord prev_record;
bool sort_required = false;
// Read all the names, discarding any with invalid IDs,
// and any where the offset/length would be outside the table.
// A stricter alternative would be to reject the font if there
// are invalid name records, but it's not clear that is necessary.
for (unsigned int i = 0; i < count; ++i) {
for (unsigned i = 0; i < count; ++i) {
NameRecord rec;
uint16_t nameLength, nameOffset;
if (!table.ReadU16(&rec.platformID) ||
!table.ReadU16(&rec.encodingID) ||
!table.ReadU16(&rec.languageID) ||
!table.ReadU16(&rec.nameID) ||
!table.ReadU16(&nameLength) ||
!table.ReadU16(&nameOffset)) {
uint16_t name_length, name_offset;
if (!table.ReadU16(&rec.platform_id) ||
!table.ReadU16(&rec.encoding_id) ||
!table.ReadU16(&rec.language_id) ||
!table.ReadU16(&rec.name_id) ||
!table.ReadU16(&name_length) ||
!table.ReadU16(&name_offset)) {
return OTS_FAILURE();
}
// check platform & encoding, discard names with unknown values
switch (rec.platformID) {
case 0: // Unicode
if (rec.encodingID > 6) {
switch (rec.platform_id) {
case 0: // Unicode
if (rec.encoding_id > 6) {
continue;
}
break;
case 1: // Macintosh
if (rec.encoding_id > 32) {
continue;
}
break;
case 2: // ISO
if (rec.encoding_id > 2) {
continue;
}
break;
case 3: // Windows: IDs 7 to 9 are "reserved"
if (rec.encoding_id > 6 && rec.encoding_id != 10) {
continue;
}
break;
case 4: // Custom (OTF Windows NT compatibility)
if (rec.encoding_id > 255) {
continue;
}
break;
default: // unknown platform
continue;
}
break;
case 1: // Macintosh
if (rec.encodingID > 32) {
continue;
}
break;
case 2: // ISO
if (rec.encodingID > 2) {
continue;
}
break;
case 3: // Windows: IDs 7 to 9 are "reserved"
if (rec.encodingID > 6 && rec.encodingID != 10) {
continue;
}
break;
case 4: // Custom (OTF Windows NT compatibility)
if (rec.encodingID > 255) {
continue;
}
break;
default: // unknown platform
continue;
}
if (size_t(stringOffset) + nameOffset + nameLength > length) {
const unsigned name_end = static_cast<unsigned>(string_offset) +
name_offset + name_length;
if (name_end > length) {
continue;
}
rec.text.resize(nameLength);
rec.text.assign(stringBase + nameOffset, nameLength);
rec.text.resize(name_length);
rec.text.assign(string_base + name_offset, name_length);
if (rec.nameID == 6) {
if (rec.name_id == 6) {
// PostScript name: check that it is valid, if not then discard it
if (rec.platformID == 1) {
if (rec.platform_id == 1) {
if (file->cff && !file->cff->name.empty()) {
rec.text = file->cff->name;
} else if (!check_ps_name_ascii(rec.text)) {
} else if (!CheckPsNameAscii(rec.text)) {
continue;
}
} else if (rec.platformID == 0 || rec.platformID == 3) {
} else if (rec.platform_id == 0 || rec.platform_id == 3) {
if (file->cff && !file->cff->name.empty()) {
assign_to_utf16_be_from_ascii(rec.text, file->cff->name);
} else if (!check_ps_name_utf16_be(rec.text)) {
AssignToUtf16BeFromAscii(&rec.text, file->cff->name);
} else if (!CheckPsNameUtf16Be(rec.text)) {
continue;
}
}
}
if (i > 0) {
if (!(prevRec < rec)) {
sortRequired = true;
}
if ((i > 0) && !(prev_record < rec)) {
OTS_WARNING("name records are not sorted.");
sort_required = true;
}
name->names.push_back(rec);
prevRec = rec;
prev_record = rec;
}
if (format == 1) {
// extended name table format with language tags
uint16_t langTagCount;
if (!table.ReadU16(&langTagCount)) {
uint16_t lang_tag_count;
if (!table.ReadU16(&lang_tag_count)) {
return OTS_FAILURE();
}
for (unsigned int i = 0; i < langTagCount; ++i) {
uint16_t tagLength, tagOffset;
if (!table.ReadU16(&tagLength) || !table.ReadU16(&tagOffset)) {
for (unsigned i = 0; i < lang_tag_count; ++i) {
uint16_t tag_length = 0;
uint16_t tag_offset = 0;
if (!table.ReadU16(&tag_length) || !table.ReadU16(&tag_offset)) {
return OTS_FAILURE();
}
if (size_t(stringOffset) + tagOffset + tagLength > length) {
const unsigned tag_end = static_cast<unsigned>(string_offset) +
tag_offset + tag_length;
if (tag_end > length) {
return OTS_FAILURE();
}
std::string tag(stringBase + tagOffset, tagLength);
name->langTags.push_back(tag);
std::string tag(string_base + tag_offset, tag_length);
name->lang_tags.push_back(tag);
}
}
if (table.offset() > stringOffset) {
if (table.offset() > string_offset) {
// the string storage apparently overlapped the name/tag records;
// consider this font to be badly broken
return OTS_FAILURE();
@ -192,8 +198,8 @@ bool ots_name_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
// 4 - full name
// 5 - version
// 6 - postscript name
const unsigned int kStdNameCount = 7;
const char* kStdNames[kStdNameCount] = {
static const unsigned kStdNameCount = 7;
static const char* kStdNames[kStdNameCount] = {
NULL,
"OTS derived font",
"Unspecified",
@ -211,112 +217,115 @@ bool ots_name_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
// scan the names to check whether the required "standard" ones are present;
// if not, we'll add our fixed versions here
bool macName[kStdNameCount] = { 0 };
bool winName[kStdNameCount] = { 0 };
for (std::vector<NameRecord>::iterator nameIter = name->names.begin();
nameIter != name->names.end(); nameIter++) {
uint16_t id = nameIter->nameID;
bool mac_name[kStdNameCount] = { 0 };
bool win_name[kStdNameCount] = { 0 };
for (std::vector<NameRecord>::iterator name_iter = name->names.begin();
name_iter != name->names.end(); name_iter++) {
const uint16_t id = name_iter->name_id;
if (id >= kStdNameCount || kStdNames[id] == NULL) {
continue;
}
if (nameIter->platformID == 1) {
macName[id] = true;
if (name_iter->platform_id == 1) {
mac_name[id] = true;
continue;
}
if (nameIter->platformID == 3) {
winName[id] = true;
if (name_iter->platform_id == 3) {
win_name[id] = true;
continue;
}
}
for (unsigned int i = 0; i < kStdNameCount; ++i) {
for (unsigned i = 0; i < kStdNameCount; ++i) {
if (kStdNames[i] == NULL) {
continue;
}
if (!macName[i]) {
NameRecord rec(1, 0, 0, i);
if (!mac_name[i]) {
NameRecord rec(1 /* platform_id */, 0 /* encoding_id */,
0 /* language_id */ , i /* name_id */);
rec.text.assign(kStdNames[i]);
name->names.push_back(rec);
sortRequired = true;
sort_required = true;
}
if (!winName[i]) {
NameRecord rec(3, 1, 1033, i);
assign_to_utf16_be_from_ascii(rec.text, std::string(kStdNames[i]));
if (!win_name[i]) {
NameRecord rec(3 /* platform_id */, 1 /* encoding_id */,
1033 /* language_id */ , i /* name_id */);
AssignToUtf16BeFromAscii(&rec.text, std::string(kStdNames[i]));
name->names.push_back(rec);
sortRequired = true;
sort_required = true;
}
}
if (sortRequired) {
if (sort_required) {
std::sort(name->names.begin(), name->names.end());
}
return true;
}
bool ots_name_should_serialise(OpenTypeFile *file) {
bool ots_name_should_serialise(OpenTypeFile* file) {
return file->name != NULL;
}
bool ots_name_serialise(OTSStream *out, OpenTypeFile *file) {
const OpenTypeNAME *name = file->name;
bool ots_name_serialise(OTSStream* out, OpenTypeFile* file) {
const OpenTypeNAME* name = file->name;
uint16_t nameCount = name->names.size();
uint16_t langTagCount = name->langTags.size();
uint16_t name_count = name->names.size();
uint16_t lang_tag_count = name->lang_tags.size();
uint16_t format = 0;
size_t stringOffset = 6 + nameCount * 12;
size_t string_offset = 6 + name_count * 12;
if (name->langTags.size() > 0) {
if (name->lang_tags.size() > 0) {
// lang tags require a format-1 name table
format = 1;
stringOffset = 8 + nameCount * 12 + langTagCount * 4;
string_offset += 2 + lang_tag_count * 4;
}
if (stringOffset > 0xffff) {
if (string_offset > 0xffff) {
return OTS_FAILURE();
}
if (!out->WriteU16(format) ||
!out->WriteU16(nameCount) ||
!out->WriteU16(stringOffset)) {
!out->WriteU16(name_count) ||
!out->WriteU16(string_offset)) {
return OTS_FAILURE();
}
std::string stringData;
for (std::vector<NameRecord>::const_iterator nameIter = name->names.begin();
nameIter != name->names.end(); nameIter++) {
const NameRecord& rec = *nameIter;
if (!out->WriteU16(rec.platformID) ||
!out->WriteU16(rec.encodingID) ||
!out->WriteU16(rec.languageID) ||
!out->WriteU16(rec.nameID) ||
std::string string_data;
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) ||
!out->WriteU16(rec.encoding_id) ||
!out->WriteU16(rec.language_id) ||
!out->WriteU16(rec.name_id) ||
!out->WriteU16(rec.text.size()) ||
!out->WriteU16(stringData.size()) ) {
!out->WriteU16(string_data.size()) ) {
return OTS_FAILURE();
}
stringData.append(rec.text);
string_data.append(rec.text);
}
if (format == 1) {
if (!out->WriteU16(langTagCount)) {
if (!out->WriteU16(lang_tag_count)) {
return OTS_FAILURE();
}
for (std::vector<std::string>::const_iterator tagIter = name->langTags.begin();
tagIter != name->langTags.end(); tagIter++) {
if (!out->WriteU16(tagIter->size()) ||
!out->WriteU16(stringData.size())) {
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())) {
return OTS_FAILURE();
}
stringData.append(*tagIter);
string_data.append(*tag_iter);
}
}
if (!out->Write(stringData.data(), stringData.size())) {
if (!out->Write(string_data.data(), string_data.size())) {
return OTS_FAILURE();
}
return true;
}
void ots_name_free(OpenTypeFile *file) {
void ots_name_free(OpenTypeFile* file) {
delete file->name;
}

View File

@ -1,4 +1,4 @@
// Copyright (c) 2011 Mozilla Foundation. All rights reserved.
// Copyright (c) 2011 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.
@ -6,43 +6,46 @@
#define OTS_NAME_H_
#include <new>
#include <string>
#include <utility>
#include <vector>
#include <string>
#include "ots.h"
namespace ots {
struct NameRecord {
NameRecord()
{ }
NameRecord() {
}
NameRecord(uint16_t p, uint16_t e, uint16_t l, uint16_t n)
: platformID(p), encodingID(e), languageID(l), nameID(n)
{ }
NameRecord(uint16_t platform_id, uint16_t encoding_id,
uint16_t language_id, uint16_t name_id)
: platform_id(platform_id),
encoding_id(encoding_id),
language_id(language_id),
name_id(name_id) {
}
uint16_t platformID;
uint16_t encodingID;
uint16_t languageID;
uint16_t nameID;
uint16_t platform_id;
uint16_t encoding_id;
uint16_t language_id;
uint16_t name_id;
std::string text;
bool operator<(const NameRecord& rhs) const {
if (platformID < rhs.platformID) return true;
if (platformID > rhs.platformID) return false;
if (encodingID < rhs.encodingID) return true;
if (encodingID > rhs.encodingID) return false;
if (languageID < rhs.languageID) return true;
if (languageID > rhs.languageID) return false;
if (nameID < rhs.nameID) return true;
return false;
if (platform_id < rhs.platform_id) return true;
if (platform_id > rhs.platform_id) return false;
if (encoding_id < rhs.encoding_id) return true;
if (encoding_id > rhs.encoding_id) return false;
if (language_id < rhs.language_id) return true;
if (language_id > rhs.language_id) return false;
return name_id < rhs.name_id;
}
};
struct OpenTypeNAME {
std::vector<NameRecord> names;
std::vector<std::string> langTags;
std::vector<NameRecord> names;
std::vector<std::string> lang_tags;
};
} // namespace ots

View File

@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <cstddef>
#include "os2.h"
#include "head.h"

View File

@ -392,9 +392,10 @@ bool ProcessGeneric(ots::OpenTypeFile *header, ots::OTSStream *output,
std::vector<std::pair<uint32_t, uint8_t> > overlap_checker;
for (unsigned i = 0; i < header->num_tables; ++i) {
overlap_checker.push_back(
std::make_pair(tables[i].offset, 1 /* start */));
std::make_pair(tables[i].offset, static_cast<uint8_t>(1) /* start */));
overlap_checker.push_back(
std::make_pair(tables[i].offset + tables[i].length, 0 /* end */));
std::make_pair(tables[i].offset + tables[i].length,
static_cast<uint8_t>(0) /* end */));
}
std::sort(overlap_checker.begin(), overlap_checker.end());
int overlap_count = 0;

View File

@ -5,7 +5,9 @@
#ifndef OTS_H_
#define OTS_H_
#include <stddef.h>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>