Index: third_party/woff2/src/woff2_dec.cc |
diff --git a/third_party/woff2/src/woff2_dec.cc b/third_party/woff2/src/woff2_dec.cc |
index 1e63caa3a3e41789cb6b838fc506ef9156df8aec..7a00f8a718425a19c506a6e95cf6b504f39b5188 100644 |
--- a/third_party/woff2/src/woff2_dec.cc |
+++ b/third_party/woff2/src/woff2_dec.cc |
@@ -70,6 +70,10 @@ const size_t kCompositeGlyphBegin = 10; |
// Largest glyph ever observed was 72k bytes |
const size_t kDefaultGlyphBuf = 5120; |
+// Over 14k test fonts the max compression ratio seen to date was ~20. |
+// >100 suggests you wrote a bad uncompressed size. |
+const float kMaxPlausibleCompressionRatio = 100.0; |
+ |
// metadata for a TTC font entry |
struct TtcFont { |
uint32_t flavor; |
@@ -478,7 +482,7 @@ bool ReconstructGlyf(const uint8_t* data, Table* glyf_table, |
} |
} |
- size_t size_needed = 2 + composite_size + instruction_size; |
+ size_t size_needed = 12 + composite_size + instruction_size; |
if (PREDICT_FALSE(glyph_buf_size < size_needed)) { |
glyph_buf.reset(new uint8_t[size_needed]); |
glyph_buf_size = size_needed; |
@@ -672,6 +676,11 @@ bool ReconstructTransformedHmtx(const uint8_t* transformed_buf, |
assert(x_mins.size() == num_glyphs); |
+ // num_glyphs 0 is OK if there is no 'glyf' but cannot then xform 'hmtx'. |
+ if (PREDICT_FALSE(num_hmetrics > num_glyphs)) { |
+ return FONT_COMPRESSION_FAILURE(); |
+ } |
+ |
for (uint16_t i = 0; i < num_hmetrics; i++) { |
uint16_t advance_width; |
if (PREDICT_FALSE(!hmtx_buff_in.ReadU16(&advance_width))) { |
@@ -1270,6 +1279,14 @@ bool ConvertWOFF2ToTTF(const uint8_t* data, size_t length, |
return FONT_COMPRESSION_FAILURE(); |
} |
+ const float compression_ratio = (float) hdr.uncompressed_size / length; |
+ if (compression_ratio > kMaxPlausibleCompressionRatio) { |
+#ifdef FONT_COMPRESSION_BIN |
+ fprintf(stderr, "Implausible compression ratio %.01f\n", compression_ratio); |
+#endif |
+ return FONT_COMPRESSION_FAILURE(); |
+ } |
+ |
const uint8_t* src_buf = data + hdr.compressed_offset; |
std::vector<uint8_t> uncompressed_buf(hdr.uncompressed_size); |
if (PREDICT_FALSE(!Woff2Uncompress(&uncompressed_buf[0], |