Support tables with 0 length (which previously failed in multiple places).

This commit is contained in:
Garret Rieger
2017-07-19 17:32:38 -07:00
parent cbea7b962e
commit 12141fdaf2
2 changed files with 16 additions and 15 deletions
+3 -6
View File
@@ -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->buffer.resize(Round4(num_glyphs + 1) * glyph_sz);
loca_table->length = (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]; uint8_t* loca_dst = &loca_table->buffer[0];
uint32_t glyf_offset = 0; uint32_t glyf_offset = 0;
size_t loca_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; glyf_offset += glyf_dst_size;
} }
if (glyf_offset == 0) {
return false;
}
StoreLoca(index_fmt, glyf_offset, &loca_offset, loca_dst); StoreLoca(index_fmt, glyf_offset, &loca_offset, loca_dst);
glyf_table->buffer.resize(glyf_offset); 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; glyf_table->length = glyf_offset;
loca_table->data = &loca_table->buffer[0]; loca_table->data = loca_offset ? &loca_table->buffer[0] : NULL;
return true; return true;
} }
+13 -9
View File
@@ -34,7 +34,6 @@
#include "./variable_length.h" #include "./variable_length.h"
#include "./woff2_common.h" #include "./woff2_common.h"
namespace woff2 { namespace woff2 {
namespace { namespace {
@@ -106,7 +105,8 @@ size_t TableEntrySize(const Table& table) {
size_t ComputeWoff2Length(const FontCollection& font_collection, size_t ComputeWoff2Length(const FontCollection& font_collection,
const std::vector<Table>& tables, 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 compressed_data_length,
size_t extended_metadata_length) { size_t extended_metadata_length) {
size_t size = kWoff2HeaderSize; size_t size = kWoff2HeaderSize;
@@ -129,7 +129,8 @@ size_t ComputeWoff2Length(const FontCollection& font_collection,
// no collection entry for xform table // no collection entry for xform table
if (table.tag & 0x80808080) continue; 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 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::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) { for (const auto& font : font_collection.fonts) {
@@ -331,8 +332,9 @@ bool ConvertTTFToWOFF2(const uint8_t *data, size_t length,
continue; continue;
} }
if (index_by_offset.find(src_table.offset) == index_by_offset.end()) { std::pair<uint32_t, uint32_t> tag_offset(src_table.tag, src_table.offset);
index_by_offset[src_table.offset] = tables.size(); if (index_by_tag_offset.find(tag_offset) == index_by_tag_offset.end()) {
index_by_tag_offset[tag_offset] = tables.size();
} else { } else {
return false; return false;
} }
@@ -357,7 +359,8 @@ bool ConvertTTFToWOFF2(const uint8_t *data, size_t length,
} }
size_t woff2_length = ComputeWoff2Length(font_collection, tables, 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) { if (woff2_length > *result_length) {
#ifdef FONT_COMPRESSION_BIN #ifdef FONT_COMPRESSION_BIN
fprintf(stderr, "Result allocation was too small (%zd vs %zd bytes).\n", 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; table.IsReused() ? table.reuse_of->offset : table.offset;
uint32_t table_length = uint32_t table_length =
table.IsReused() ? table.reuse_of->length : 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 #ifdef FONT_COMPRESSION_BIN
fprintf(stderr, "Missing table index for offset 0x%08x\n", fprintf(stderr, "Missing table index for offset 0x%08x\n",
table_offset); table_offset);
#endif #endif
return FONT_COMPRESSION_FAILURE(); 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); Store255UShort(index, &offset, result);
} }