Merge pull request #78 from garretrieger/master
Various crash fixes for encoder and decoder, mostly found by fuzzing.
This commit is contained in:
+5
-2
@@ -331,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) {
|
||||
|
||||
+3
-6
@@ -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;
|
||||
}
|
||||
|
||||
+11
@@ -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_
|
||||
|
||||
+6
-4
@@ -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,10 +35,10 @@ 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__))
|
||||
#if defined(WOFF_LITTLE_ENDIAN)
|
||||
*reinterpret_cast<uint16_t*>(dst + offset) =
|
||||
((x & 0xFF) << 8) | ((x & 0xFF00) >> 8);
|
||||
#elif (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
|
||||
#elif defined(WOFF_BIG_ENDIAN)
|
||||
*reinterpret_cast<uint16_t*>(dst + offset) = static_cast<uint16_t>(x);
|
||||
#else
|
||||
dst[offset] = x >> 8;
|
||||
@@ -53,11 +55,11 @@ 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__))
|
||||
#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__))
|
||||
#elif defined(WOFF_BIG_ENDIAN)
|
||||
*reinterpret_cast<uint16_t*>(dst + *offset) = static_cast<uint16_t>(val);
|
||||
*offset += 2;
|
||||
#else
|
||||
|
||||
+4
-2
@@ -18,6 +18,8 @@
|
||||
|
||||
#include "./woff2_common.h"
|
||||
|
||||
#include "./port.h"
|
||||
|
||||
namespace woff2 {
|
||||
|
||||
|
||||
@@ -25,11 +27,11 @@ 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) {
|
||||
#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__))
|
||||
#elif defined(WOFF_BIG_ENDIAN)
|
||||
checksum += *reinterpret_cast<const uint32_t*>(buf + i);
|
||||
#else
|
||||
checksum += (buf[i] << 24) | (buf[i + 1] << 16) |
|
||||
|
||||
@@ -1299,6 +1299,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))) {
|
||||
|
||||
+13
-9
@@ -34,7 +34,6 @@
|
||||
#include "./variable_length.h"
|
||||
#include "./woff2_common.h"
|
||||
|
||||
|
||||
namespace woff2 {
|
||||
|
||||
namespace {
|
||||
@@ -106,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;
|
||||
@@ -129,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
|
||||
}
|
||||
}
|
||||
@@ -321,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) {
|
||||
|
||||
@@ -331,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;
|
||||
}
|
||||
@@ -357,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",
|
||||
@@ -430,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);
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user