Bug 1384862 - Update WOFF2 code to latest upstream. r=sylvestre

This commit is contained in:
Jonathan Kew 2017-07-27 10:33:47 +02:00
Родитель 42e6712830
Коммит 92d0aff08b
15 изменённых файлов: 121 добавлений и 121 удалений

Просмотреть файл

@ -11,12 +11,8 @@ The in-tree copy is updated by running
sh update.sh
from within the modules/woff2 directory.
Current version: [commit 63b8fb6d0d797f04e77ee825fd8fcf7ea6205aac].
Current version: [commit e580ebc30a54becf69a75f6e6d6008536ae0c0b4].
redefine-unique_ptr.patch redefines the class std::unique_ptr to workaround a
build issue with missing C++11 features.
See https://bugzilla.mozilla.org/show_bug.cgi?id=1227058
brotli-0.6.0-api-change.patch adjusts the WOFF2 code to match Brotli API
changes in the 0.6.0 release. (Will be superseded by next WOFF2 update.)
See https://bugzilla.mozilla.org/show_bug.cgi?id=1340910

Просмотреть файл

@ -1,43 +0,0 @@
diff --git a/modules/woff2/src/woff2_dec.cc b/modules/woff2/src/woff2_dec.cc
--- a/modules/woff2/src/woff2_dec.cc
+++ b/modules/woff2/src/woff2_dec.cc
@@ -31,17 +31,17 @@
namespace std
{
using mozilla::DefaultDelete;
using mozilla::UniquePtr;
#define default_delete DefaultDelete
#define unique_ptr UniquePtr
}
-#include "./decode.h"
+#include "brotli/decode.h"
#include "./buffer.h"
#include "./port.h"
#include "./round.h"
#include "./store_bytes.h"
#include "./table_tags.h"
#include "./variable_length.h"
#include "./woff2_common.h"
@@ -746,18 +746,18 @@ bool ReconstructTransformedHmtx(const ui
}
return true;
}
bool Woff2Uncompress(uint8_t* dst_buf, size_t dst_size,
const uint8_t* src_buf, size_t src_size) {
size_t uncompressed_size = dst_size;
- int ok = BrotliDecompressBuffer(src_size, src_buf,
- &uncompressed_size, dst_buf);
+ int ok = BrotliDecoderDecompress(src_size, src_buf,
+ &uncompressed_size, dst_buf);
if (PREDICT_FALSE(!ok || uncompressed_size != dst_size)) {
return FONT_COMPRESSION_FAILURE();
}
return true;
}
bool ReadTableDirectory(Buffer* file, std::vector<Table>* tables,
size_t num_tables) {

Просмотреть файл

@ -19,7 +19,7 @@ diff --git a/modules/woff2/src/woff2_dec.cc b/modules/woff2/src/woff2_dec.cc
+ #define unique_ptr UniquePtr
+}
+
#include "./decode.h"
#include "./brotli/decode.h"
#include "./buffer.h"
#include "./port.h"
#include "./round.h"

Просмотреть файл

@ -65,8 +65,8 @@ inline bool Failure(const char *f, int l, const char *fn) {
// -----------------------------------------------------------------------------
class Buffer {
public:
Buffer(const uint8_t *buffer, size_t len)
: buffer_(buffer),
Buffer(const uint8_t *data, size_t len)
: buffer_(data),
length_(len),
offset_(0) { }
@ -74,7 +74,7 @@ class Buffer {
return Read(NULL, n_bytes);
}
bool Read(uint8_t *buffer, size_t n_bytes) {
bool Read(uint8_t *data, size_t n_bytes) {
if (n_bytes > 1024 * 1024 * 1024) {
return FONT_COMPRESSION_FAILURE();
}
@ -82,8 +82,8 @@ class Buffer {
(offset_ > length_ - n_bytes)) {
return FONT_COMPRESSION_FAILURE();
}
if (buffer) {
std::memcpy(buffer, buffer_ + offset_, n_bytes);
if (data) {
std::memcpy(data, buffer_ + offset_, n_bytes);
}
offset_ += n_bytes;
return true;

Просмотреть файл

@ -0,0 +1,13 @@
#include <stddef.h>
#include <stdint.h>
#include "woff2_dec.h"
// Entry point for LibFuzzer.
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
std::string buf;
woff2::WOFF2StringOut out(&buf);
out.SetMaxSize(30 * 1024 * 1024);
woff2::ConvertWOFF2ToTTF(data, size, &out);
return 0;
}

Просмотреть файл

@ -0,0 +1,12 @@
#include <string>
#include "woff2_dec.h"
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t data_size) {
// Decode using newer entry pattern.
// Same pattern as woff2_decompress.
std::string output(std::min(woff2::ComputeWOFF2FinalSize(data, data_size),
woff2::kDefaultMaxSize), 0);
woff2::WOFF2StringOut out(&output);
woff2::ConvertWOFF2ToTTF(data, data_size, &out);
return 0;
}

Просмотреть файл

@ -105,6 +105,12 @@ bool ReadTrueTypeFont(Buffer* file, const uint8_t* data, size_t len,
last_offset = i.first + i.second;
}
// Sanity check key tables
const Font::Table* head_table = font->FindTable(kHeadTableTag);
if (head_table != NULL && head_table->length < 52) {
return FONT_COMPRESSION_FAILURE();
}
return true;
}
@ -325,8 +331,11 @@ int NumGlyphs(const Font& font) {
return 0;
}
int index_fmt = IndexFormat(font);
int num_glyphs = (loca_table->length / (index_fmt == 0 ? 2 : 4)) - 1;
return num_glyphs;
int loca_record_size = (index_fmt == 0 ? 2 : 4);
if (loca_table->length < loca_record_size) {
return 0;
}
return (loca_table->length / loca_record_size) - 1;
}
int IndexFormat(const Font& font) {

Просмотреть файл

@ -118,25 +118,27 @@ bool ReadGlyph(const uint8_t* data, size_t len, Glyph* glyph) {
// Read the run-length coded flags.
std::vector<std::vector<uint8_t> > flags(num_contours);
uint8_t flag = 0;
uint8_t flag_repeat = 0;
for (int i = 0; i < num_contours; ++i) {
flags[i].resize(glyph->contours[i].size());
for (size_t j = 0; j < glyph->contours[i].size(); ++j) {
if (flag_repeat == 0) {
if (!buffer.ReadU8(&flag)) {
return FONT_COMPRESSION_FAILURE();
}
if (flag & kFLAG_REPEAT) {
if (!buffer.ReadU8(&flag_repeat)) {
{
uint8_t flag = 0;
uint8_t flag_repeat = 0;
for (int i = 0; i < num_contours; ++i) {
flags[i].resize(glyph->contours[i].size());
for (size_t j = 0; j < glyph->contours[i].size(); ++j) {
if (flag_repeat == 0) {
if (!buffer.ReadU8(&flag)) {
return FONT_COMPRESSION_FAILURE();
}
if (flag & kFLAG_REPEAT) {
if (!buffer.ReadU8(&flag_repeat)) {
return FONT_COMPRESSION_FAILURE();
}
}
} else {
flag_repeat--;
}
} else {
flag_repeat--;
flags[i][j] = flag;
glyph->contours[i][j].on_curve = flag & kFLAG_ONCURVE;
}
flags[i][j] = flag;
glyph->contours[i][j].on_curve = flag & kFLAG_ONCURVE;
}
}

Просмотреть файл

@ -52,7 +52,7 @@ bool WriteNormalizedLoca(int index_fmt, int num_glyphs, Font* font) {
loca_table->buffer.resize(Round4(num_glyphs + 1) * glyph_sz);
loca_table->length = (num_glyphs + 1) * glyph_sz;
uint8_t* glyf_dst = &glyf_table->buffer[0];
uint8_t* glyf_dst = num_glyphs ? &glyf_table->buffer[0] : NULL;
uint8_t* loca_dst = &loca_table->buffer[0];
uint32_t glyf_offset = 0;
size_t loca_offset = 0;
@ -78,16 +78,13 @@ bool WriteNormalizedLoca(int index_fmt, int num_glyphs, Font* font) {
}
glyf_offset += glyf_dst_size;
}
if (glyf_offset == 0) {
return false;
}
StoreLoca(index_fmt, glyf_offset, &loca_offset, loca_dst);
glyf_table->buffer.resize(glyf_offset);
glyf_table->data = &glyf_table->buffer[0];
glyf_table->data = glyf_offset ? &glyf_table->buffer[0] : NULL;
glyf_table->length = glyf_offset;
loca_table->data = &loca_table->buffer[0];
loca_table->data = loca_offset ? &loca_table->buffer[0] : NULL;
return true;
}

Просмотреть файл

@ -60,4 +60,15 @@ inline int Log2Floor(uint32 n) {
#define PREDICT_TRUE(x) (x)
#endif
#if (defined(__ARM_ARCH) && (__ARM_ARCH == 7)) || \
(defined(M_ARM) && (M_ARM == 7)) || \
defined(__aarch64__) || defined(__ARM64_ARCH_8__) || defined(__i386) || \
defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)
#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
#define WOFF_LITTLE_ENDIAN
#elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
#define WOFF_BIG_ENDIAN
#endif /* endianness */
#endif /* CPU whitelist */
#endif // WOFF2_PORT_H_

Просмотреть файл

@ -22,6 +22,8 @@
#include <stddef.h>
#include <string.h>
#include "./port.h"
namespace woff2 {
inline size_t StoreU32(uint8_t* dst, size_t offset, uint32_t x) {
@ -33,12 +35,11 @@ inline size_t StoreU32(uint8_t* dst, size_t offset, uint32_t x) {
}
inline size_t Store16(uint8_t* dst, size_t offset, int x) {
#if (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
uint16_t v = ((x & 0xFF) << 8) | ((x & 0xFF00) >> 8);
memcpy(dst + offset, &v, 2);
#elif (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
uint16_t v = static_cast<uint16_t>(x);
memcpy(dst + offset, &v, 2);
#if defined(WOFF_LITTLE_ENDIAN)
*reinterpret_cast<uint16_t*>(dst + offset) =
((x & 0xFF) << 8) | ((x & 0xFF00) >> 8);
#elif defined(WOFF_BIG_ENDIAN)
*reinterpret_cast<uint16_t*>(dst + offset) = static_cast<uint16_t>(x);
#else
dst[offset] = x >> 8;
dst[offset + 1] = x;
@ -54,14 +55,12 @@ inline void StoreU32(uint32_t val, size_t* offset, uint8_t* dst) {
}
inline void Store16(int val, size_t* offset, uint8_t* dst) {
#if (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
uint16_t v = ((val & 0xFF) << 8) | ((val & 0xFF00) >> 8);
memcpy(dst + *offset, &v, 2);
#if defined(WOFF_LITTLE_ENDIAN)
*reinterpret_cast<uint16_t*>(dst + *offset) =
((val & 0xFF) << 8) | ((val & 0xFF00) >> 8);
*offset += 2;
#elif (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
uint16_t v = static_cast<uint16_t>(val);
memcpy(dst + *offset, &v, 2);
#elif defined(WOFF_BIG_ENDIAN)
*reinterpret_cast<uint16_t*>(dst + *offset) = static_cast<uint16_t>(val);
*offset += 2;
#else
dst[(*offset)++] = val >> 8;

Просмотреть файл

@ -49,8 +49,8 @@ void Write255UShort(std::vector<uint8_t>* out, int value) {
void Store255UShort(int val, size_t* offset, uint8_t* dst) {
std::vector<uint8_t> packed;
Write255UShort(&packed, val);
for (uint8_t val : packed) {
dst[(*offset)++] = val;
for (uint8_t packed_byte : packed) {
dst[(*offset)++] = packed_byte;
}
}

Просмотреть файл

@ -18,6 +18,8 @@
#include "./woff2_common.h"
#include "./port.h"
namespace woff2 {
@ -25,13 +27,12 @@ uint32_t ComputeULongSum(const uint8_t* buf, size_t size) {
uint32_t checksum = 0;
size_t aligned_size = size & ~3;
for (size_t i = 0; i < aligned_size; i += 4) {
uint32_t v;
memcpy(&v, buf + i, 4);
#if (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
#if defined(WOFF_LITTLE_ENDIAN)
uint32_t v = *reinterpret_cast<const uint32_t*>(buf + i);
checksum += (((v & 0xFF) << 24) | ((v & 0xFF00) << 8) |
((v & 0xFF0000) >> 8) | ((v & 0xFF000000) >> 24));
#elif (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
checksum += v;
#elif defined(WOFF_BIG_ENDIAN)
checksum += *reinterpret_cast<const uint32_t*>(buf + i);
#else
checksum += (buf[i] << 24) | (buf[i + 1] << 16) |
(buf[i + 2] << 8) | buf[i + 3];

Просмотреть файл

@ -36,7 +36,7 @@ namespace std
#define unique_ptr UniquePtr
}
#include "brotli/decode.h"
#include "./brotli/decode.h"
#include "./buffer.h"
#include "./port.h"
#include "./round.h"
@ -751,9 +751,10 @@ bool ReconstructTransformedHmtx(const uint8_t* transformed_buf,
bool Woff2Uncompress(uint8_t* dst_buf, size_t dst_size,
const uint8_t* src_buf, size_t src_size) {
size_t uncompressed_size = dst_size;
int ok = BrotliDecoderDecompress(src_size, src_buf,
&uncompressed_size, dst_buf);
if (PREDICT_FALSE(!ok || uncompressed_size != dst_size)) {
BrotliDecoderResult result = BrotliDecoderDecompress(
src_size, src_buf, &uncompressed_size, dst_buf);
if (PREDICT_FALSE(result != BROTLI_DECODER_RESULT_SUCCESS ||
uncompressed_size != dst_size)) {
return FONT_COMPRESSION_FAILURE();
}
return true;
@ -1307,6 +1308,9 @@ bool ConvertWOFF2ToTTF(const uint8_t* data, size_t length,
const uint8_t* src_buf = data + hdr.compressed_offset;
std::vector<uint8_t> uncompressed_buf(hdr.uncompressed_size);
if (PREDICT_FALSE(hdr.uncompressed_size < 1)) {
return FONT_COMPRESSION_FAILURE();
}
if (PREDICT_FALSE(!Woff2Uncompress(&uncompressed_buf[0],
hdr.uncompressed_size, src_buf,
hdr.compressed_length))) {

Просмотреть файл

@ -23,7 +23,7 @@
#include <string>
#include <vector>
#include "./compressor.h"
#include "./brotli/encode.h"
#include "./buffer.h"
#include "./font.h"
#include "./normalize.h"
@ -34,7 +34,6 @@
#include "./variable_length.h"
#include "./woff2_common.h"
namespace woff2 {
namespace {
@ -47,16 +46,11 @@ using std::vector;
const size_t kWoff2HeaderSize = 48;
const size_t kWoff2EntrySize = 20;
bool Compress(const uint8_t* data, const size_t len,
uint8_t* result, uint32_t* result_len,
brotli::BrotliParams::Mode mode, int quality) {
bool Compress(const uint8_t* data, const size_t len, uint8_t* result,
uint32_t* result_len, BrotliEncoderMode mode, int quality) {
size_t compressed_len = *result_len;
brotli::BrotliParams params;
params.mode = mode;
params.quality = quality;
if (brotli::BrotliCompressBuffer(params, len, data, &compressed_len, result)
== 0) {
if (BrotliEncoderCompress(quality, BROTLI_DEFAULT_WINDOW, mode, len, data,
&compressed_len, result) == 0) {
return false;
}
*result_len = compressed_len;
@ -67,14 +61,14 @@ bool Woff2Compress(const uint8_t* data, const size_t len,
uint8_t* result, uint32_t* result_len,
int quality) {
return Compress(data, len, result, result_len,
brotli::BrotliParams::MODE_FONT, quality);
BROTLI_MODE_FONT, quality);
}
bool TextCompress(const uint8_t* data, const size_t len,
uint8_t* result, uint32_t* result_len,
int quality) {
return Compress(data, len, result, result_len,
brotli::BrotliParams::MODE_TEXT, quality);
BROTLI_MODE_TEXT, quality);
}
int KnownTableIndex(uint32_t tag) {
@ -111,7 +105,8 @@ size_t TableEntrySize(const Table& table) {
size_t ComputeWoff2Length(const FontCollection& font_collection,
const std::vector<Table>& tables,
std::map<uint32_t, uint16_t> index_by_offset,
std::map<std::pair<uint32_t, uint32_t>, uint16_t>
index_by_tag_offset,
size_t compressed_data_length,
size_t extended_metadata_length) {
size_t size = kWoff2HeaderSize;
@ -134,7 +129,8 @@ size_t ComputeWoff2Length(const FontCollection& font_collection,
// no collection entry for xform table
if (table.tag & 0x80808080) continue;
uint16_t table_index = index_by_offset[table.offset];
std::pair<uint32_t, uint32_t> tag_offset(table.tag, table.offset);
uint16_t table_index = index_by_tag_offset[tag_offset];
size += Size255UShort(table_index); // 255UInt16 index entry
}
}
@ -326,7 +322,7 @@ bool ConvertTTFToWOFF2(const uint8_t *data, size_t length,
}
std::vector<Table> tables;
std::map<uint32_t, uint16_t> index_by_offset;
std::map<std::pair<uint32_t, uint32_t>, uint16_t> index_by_tag_offset;
for (const auto& font : font_collection.fonts) {
@ -336,8 +332,9 @@ bool ConvertTTFToWOFF2(const uint8_t *data, size_t length,
continue;
}
if (index_by_offset.find(src_table.offset) == index_by_offset.end()) {
index_by_offset[src_table.offset] = tables.size();
std::pair<uint32_t, uint32_t> tag_offset(src_table.tag, src_table.offset);
if (index_by_tag_offset.find(tag_offset) == index_by_tag_offset.end()) {
index_by_tag_offset[tag_offset] = tables.size();
} else {
return false;
}
@ -362,7 +359,8 @@ bool ConvertTTFToWOFF2(const uint8_t *data, size_t length,
}
size_t woff2_length = ComputeWoff2Length(font_collection, tables,
index_by_offset, total_compressed_length, compressed_metadata_buf_length);
index_by_tag_offset, total_compressed_length,
compressed_metadata_buf_length);
if (woff2_length > *result_length) {
#ifdef FONT_COMPRESSION_BIN
fprintf(stderr, "Result allocation was too small (%zd vs %zd bytes).\n",
@ -435,14 +433,15 @@ bool ConvertTTFToWOFF2(const uint8_t *data, size_t length,
table.IsReused() ? table.reuse_of->offset : table.offset;
uint32_t table_length =
table.IsReused() ? table.reuse_of->length : table.length;
if (index_by_offset.find(table_offset) == index_by_offset.end()) {
std::pair<uint32_t, uint32_t> tag_offset(table.tag, table_offset);
if (index_by_tag_offset.find(tag_offset) == index_by_tag_offset.end()) {
#ifdef FONT_COMPRESSION_BIN
fprintf(stderr, "Missing table index for offset 0x%08x\n",
table_offset);
#endif
return FONT_COMPRESSION_FAILURE();
}
uint16_t index = index_by_offset[table_offset];
uint16_t index = index_by_tag_offset[tag_offset];
Store255UShort(index, &offset, result);
}