@@ -70,6 +70,10 @@ const size_t kCompositeGlyphBegin = 10;
7070// Largest glyph ever observed was 72k bytes
7171const 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
7478struct 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