Skip to content

Commit a15a8ab

Browse files
committed
Fixes for bugs uncovered by libFuzzer analysis. A write past buffer, a potential DOS by way of giant alloc, and an out of range access.
1 parent 9476664 commit a15a8ab

File tree

1 file changed

+18
-1
lines changed

1 file changed

+18
-1
lines changed

src/woff2_dec.cc

+18-1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ const size_t kCompositeGlyphBegin = 10;
7070
// Largest glyph ever observed was 72k bytes
7171
const size_t kDefaultGlyphBuf = 5120;
7272

73+
// Over 14k test fonts the max compression ratio seen to date was ~20.
74+
// >100 suggests you wrote a bad uncompressed size.
75+
const float kMaxPlausibleCompressionRatio = 100.0;
76+
7377
// metadata for a TTC font entry
7478
struct TtcFont {
7579
uint32_t flavor;
@@ -478,7 +482,7 @@ bool ReconstructGlyf(const uint8_t* data, Table* glyf_table,
478482
}
479483
}
480484

481-
size_t size_needed = 2 + composite_size + instruction_size;
485+
size_t size_needed = 12 + composite_size + instruction_size;
482486
if (PREDICT_FALSE(glyph_buf_size < size_needed)) {
483487
glyph_buf.reset(new uint8_t[size_needed]);
484488
glyph_buf_size = size_needed;
@@ -672,6 +676,11 @@ bool ReconstructTransformedHmtx(const uint8_t* transformed_buf,
672676

673677
assert(x_mins.size() == num_glyphs);
674678

679+
// num_glyphs 0 is OK if there is no 'glyf' but cannot then xform 'hmtx'.
680+
if (PREDICT_FALSE(num_hmetrics > num_glyphs)) {
681+
return FONT_COMPRESSION_FAILURE();
682+
}
683+
675684
for (uint16_t i = 0; i < num_hmetrics; i++) {
676685
uint16_t advance_width;
677686
if (PREDICT_FALSE(!hmtx_buff_in.ReadU16(&advance_width))) {
@@ -1270,6 +1279,14 @@ bool ConvertWOFF2ToTTF(const uint8_t* data, size_t length,
12701279
return FONT_COMPRESSION_FAILURE();
12711280
}
12721281

1282+
const float compression_ratio = (float) hdr.uncompressed_size / length;
1283+
if (compression_ratio > kMaxPlausibleCompressionRatio) {
1284+
#ifdef FONT_COMPRESSION_BIN
1285+
fprintf(stderr, "Implausible compression ratio %.01f\n", compression_ratio);
1286+
#endif
1287+
return FONT_COMPRESSION_FAILURE();
1288+
}
1289+
12731290
const uint8_t* src_buf = data + hdr.compressed_offset;
12741291
std::vector<uint8_t> uncompressed_buf(hdr.uncompressed_size);
12751292
if (PREDICT_FALSE(!Woff2Uncompress(&uncompressed_buf[0],

0 commit comments

Comments
 (0)