From 208c8f854e902a1264f86b0be9f9622e4c0fcfe3 Mon Sep 17 00:00:00 2001 From: Khaled Hosny Date: Sun, 28 Jun 2015 22:08:29 +0200 Subject: [PATCH] Kill kWoff2FlagsContinueStream There is only a single data stream for all the compressed tables, but the code was originally written for separately compressed tables then retrofitted, so this is an attempt to streamline it a bit. --- src/woff2_common.h | 1 - src/woff2_dec.cc | 79 ++++++++++++++-------------------------------- src/woff2_enc.cc | 1 - 3 files changed, 24 insertions(+), 57 deletions(-) diff --git a/src/woff2_common.h b/src/woff2_common.h index e6cfdf2..1d3d03d 100644 --- a/src/woff2_common.h +++ b/src/woff2_common.h @@ -26,7 +26,6 @@ namespace woff2 { static const uint32_t kWoff2Signature = 0x774f4632; // "wOF2" -const unsigned int kWoff2FlagsContinueStream = 1 << 4; const unsigned int kWoff2FlagsTransform = 1 << 5; // TrueType Collection ID string: 'ttcf' diff --git a/src/woff2_dec.cc b/src/woff2_dec.cc index 606f030..62d18d1 100644 --- a/src/woff2_dec.cc +++ b/src/woff2_dec.cc @@ -701,9 +701,6 @@ bool ReadTableDirectory(Buffer* file, std::vector* tables, return FONT_COMPRESSION_FAILURE(); } uint32_t flags = 0; - if (i > 0) { - flags |= kWoff2FlagsContinueStream; - } // Always transform the glyf and loca tables if (tag == kGlyfTableTag || tag == kLocaTableTag) { flags |= kWoff2FlagsTransform; @@ -921,36 +918,22 @@ bool ConvertWOFF2ToTTF(uint8_t* result, size_t result_length, return FONT_COMPRESSION_FAILURE(); } - uint64_t src_offset = file.offset(); + uint64_t compressed_offset = file.offset(); + if (PREDICT_FALSE(compressed_offset > std::numeric_limits::max())) { + return FONT_COMPRESSION_FAILURE(); + } + uint64_t src_offset = Round4(compressed_offset + compressed_length); uint64_t dst_offset = first_table_offset; - uint64_t uncompressed_sum = 0; for (uint16_t i = 0; i < num_tables; ++i) { Table* table = &tables[i]; - table->src_offset = src_offset; - table->src_length = (i == 0 ? compressed_length : 0); - src_offset += table->src_length; - if (PREDICT_FALSE(src_offset > std::numeric_limits::max())) { - return FONT_COMPRESSION_FAILURE(); - } - src_offset = Round4(src_offset); table->dst_offset = dst_offset; dst_offset += table->dst_length; if (PREDICT_FALSE(dst_offset > std::numeric_limits::max())) { return FONT_COMPRESSION_FAILURE(); } dst_offset = Round4(dst_offset); - - uncompressed_sum += table->src_length; - if (PREDICT_FALSE( - uncompressed_sum > std::numeric_limits::max())) { - return FONT_COMPRESSION_FAILURE(); - } - } - // Enforce same 30M limit on uncompressed tables as OTS - if (PREDICT_FALSE(uncompressed_sum > 30 * 1024 * 1024)) { - return FONT_COMPRESSION_FAILURE(); } if (PREDICT_FALSE(src_offset > length || dst_offset != result_length)) { fprintf(stderr, "offset fail; src_offset %" PRIu64 " length %lu " @@ -1044,38 +1027,26 @@ bool ConvertWOFF2ToTTF(uint8_t* result, size_t result_length, } std::vector uncompressed_buf; - bool continue_valid = false; const uint8_t* transform_buf = NULL; + uint64_t total_size = 0; + for (uint16_t i = 0; i < num_tables; ++i) { + total_size += tables[i].transform_length; + if (PREDICT_FALSE(total_size > std::numeric_limits::max())) { + return FONT_COMPRESSION_FAILURE(); + } + } + uncompressed_buf.resize(total_size); + const uint8_t* src_buf = data + compressed_offset; + if (PREDICT_FALSE(!Woff2Uncompress(&uncompressed_buf[0], total_size, + src_buf, compressed_length))) { + return FONT_COMPRESSION_FAILURE(); + } + transform_buf = &uncompressed_buf[0]; + for (uint16_t i = 0; i < num_tables; ++i) { const Table* table = &tables[i]; uint32_t flags = table->flags; - const uint8_t* src_buf = data + table->src_offset; size_t transform_length = table->transform_length; - if ((flags & kWoff2FlagsContinueStream) != 0) { - if (PREDICT_FALSE(!continue_valid)) { - return FONT_COMPRESSION_FAILURE(); - } - } else if ((flags & kWoff2FlagsContinueStream) == 0) { - uint64_t total_size = transform_length; - for (uint16_t j = i + 1; j < num_tables; ++j) { - if ((tables[j].flags & kWoff2FlagsContinueStream) == 0) { - break; - } - total_size += tables[j].transform_length; - if (PREDICT_FALSE(total_size > std::numeric_limits::max())) { - return FONT_COMPRESSION_FAILURE(); - } - } - uncompressed_buf.resize(total_size); - if (PREDICT_FALSE(!Woff2Uncompress(&uncompressed_buf[0], total_size, - src_buf, compressed_length))) { - return FONT_COMPRESSION_FAILURE(); - } - transform_buf = &uncompressed_buf[0]; - continue_valid = true; - } else { - return FONT_COMPRESSION_FAILURE(); - } if ((flags & kWoff2FlagsTransform) == 0) { if (PREDICT_FALSE(transform_length != table->dst_length)) { @@ -1107,12 +1078,10 @@ bool ConvertWOFF2ToTTF(uint8_t* result, size_t result_length, } } } - if (continue_valid) { - transform_buf += transform_length; - if (PREDICT_FALSE( - transform_buf > &uncompressed_buf[0] + uncompressed_buf.size())) { - return FONT_COMPRESSION_FAILURE(); - } + transform_buf += transform_length; + if (PREDICT_FALSE( + transform_buf > &uncompressed_buf[0] + uncompressed_buf.size())) { + return FONT_COMPRESSION_FAILURE(); } } diff --git a/src/woff2_enc.cc b/src/woff2_enc.cc index e672ac3..131428e 100644 --- a/src/woff2_enc.cc +++ b/src/woff2_enc.cc @@ -340,7 +340,6 @@ bool ConvertTTFToWOFF2(const uint8_t *data, size_t length, } else { table.dst_length = 0; table.dst_data = NULL; - table.flags |= kWoff2FlagsContinueStream; } tables.push_back(table); }