From 0634e0a7194d23a0855da78bf950ce2cd7366ea4 Mon Sep 17 00:00:00 2001 From: Khaled Hosny Date: Sun, 1 Feb 2015 09:22:50 +0200 Subject: [PATCH 1/3] Don't accept too long totalSfntSize Per the spec (WOFF 2.0 spec just refer to WOFF 1.0 spec here): http://www.w3.org/TR/2012/REC-WOFF-20121213/#conform-totalsize-longword-reject --- src/woff2_dec.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/woff2_dec.cc b/src/woff2_dec.cc index e202672..0e38ea8 100644 --- a/src/woff2_dec.cc +++ b/src/woff2_dec.cc @@ -807,7 +807,7 @@ bool ConvertWOFF2ToTTF(uint8_t* result, size_t result_length, } // We don't care about these fields of the header: // uint16_t reserved - // uint32_t total_sfnt_size + // uint32_t total_sfnt_size, the caller already passes it as result_length if (!file.Skip(6)) { return FONT_COMPRESSION_FAILURE(); } @@ -926,7 +926,7 @@ bool ConvertWOFF2ToTTF(uint8_t* result, size_t result_length, if (uncompressed_sum > 30 * 1024 * 1024) { return FONT_COMPRESSION_FAILURE(); } - if (src_offset > length || dst_offset > result_length) { + if (src_offset > length || dst_offset != result_length) { fprintf(stderr, "offset fail; src_offset %lu length %lu " "dst_offset %lu result_length %lu\n", src_offset, length, dst_offset, result_length); From 3f91c6e58fc477ffa871390539945e52de73a2a3 Mon Sep 17 00:00:00 2001 From: Khaled Hosny Date: Wed, 4 Feb 2015 23:01:03 +0200 Subject: [PATCH 2/3] Check matadata and private blocks offsets & length So that we can reject fonts with extraneous data between blocks, as the spec says we should reject says we should reject such fonts. --- src/woff2_dec.cc | 52 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/src/woff2_dec.cc b/src/woff2_dec.cc index 0e38ea8..36f1b05 100644 --- a/src/woff2_dec.cc +++ b/src/woff2_dec.cc @@ -817,11 +817,33 @@ bool ConvertWOFF2ToTTF(uint8_t* result, size_t result_length, } // We don't care about these fields of the header: // uint16_t major_version, minor_version - // uint32_t meta_offset, meta_length, meta_orig_length - // uint32_t priv_offset, priv_length - if (!file.Skip(24)) { + if (!file.Skip(2 * 2)) { return FONT_COMPRESSION_FAILURE(); } + uint32_t meta_offset; + uint32_t meta_length; + uint32_t meta_length_orig; + if (!file.ReadU32(&meta_offset) || + !file.ReadU32(&meta_length) || + !file.ReadU32(&meta_length_orig)) { + return FONT_COMPRESSION_FAILURE(); + } + if (meta_offset) { + if (meta_offset >= length || length - meta_offset < meta_length) { + return FONT_COMPRESSION_FAILURE(); + } + } + uint32_t priv_offset; + uint32_t priv_length; + if (!file.ReadU32(&priv_offset) || + !file.ReadU32(&priv_length)) { + return FONT_COMPRESSION_FAILURE(); + } + if (priv_offset) { + if (priv_offset >= length || length - priv_offset < priv_length) { + return FONT_COMPRESSION_FAILURE(); + } + } std::vector tables(num_tables); if (!ReadTableDirectory(&file, &tables, num_tables)) { return FONT_COMPRESSION_FAILURE(); @@ -951,6 +973,30 @@ bool ConvertWOFF2ToTTF(uint8_t* result, size_t result_length, std::sort(tables.begin(), tables.end()); } + if (meta_offset) { + if (src_offset != meta_offset) { + return FONT_COMPRESSION_FAILURE(); + } + src_offset = Round4(meta_offset + meta_length); + if (src_offset > std::numeric_limits::max()) { + return FONT_COMPRESSION_FAILURE(); + } + } + + if (priv_offset) { + if (src_offset != priv_offset) { + return FONT_COMPRESSION_FAILURE(); + } + src_offset = Round4(priv_offset + priv_length); + if (src_offset > std::numeric_limits::max()) { + return FONT_COMPRESSION_FAILURE(); + } + } + + if (src_offset != Round4(length)) { + return FONT_COMPRESSION_FAILURE(); + } + // Start building the font size_t offset = 0; size_t offset_table = 0; From 531adab1fe13dc0f45d33c3dca308f84ffc7e7c9 Mon Sep 17 00:00:00 2001 From: Khaled Hosny Date: Mon, 20 Apr 2015 00:21:05 +0200 Subject: [PATCH 3/3] Reject non-zero loca transformLength --- src/woff2_dec.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/woff2_dec.cc b/src/woff2_dec.cc index 36f1b05..7740a5d 100644 --- a/src/woff2_dec.cc +++ b/src/woff2_dec.cc @@ -720,6 +720,9 @@ bool ReadTableDirectory(Buffer* file, std::vector
* tables, if (!ReadBase128(file, &transform_length)) { return FONT_COMPRESSION_FAILURE(); } + if (tag == kLocaTableTag && transform_length) { + return FONT_COMPRESSION_FAILURE(); + } } table->tag = tag; table->flags = flags;