From 67f8821fb25d9bd55719f5e29a582ae1af4b02b3 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 2 Nov 2015 15:37:29 -0800 Subject: [PATCH] [ot] Make bad-hmtx handling match FreeType Also route fuzzing-related tests through hb-ot-font, to reduce dependency on FreeType behavior for badly-broken fonts. Fixes failing test with FreeType master. --- src/hb-ot-font.cc | 24 ++++++++++++++---------- test/shaping/tests/fuzzed.tests | 10 +++++----- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 69d2503ab..bde63fa40 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -46,11 +46,9 @@ struct hb_ot_face_metrics_accelerator_t hb_blob_t *blob; inline void init (hb_face_t *face, - hb_tag_t _hea_tag, hb_tag_t _mtx_tag, - unsigned int default_advance_) + hb_tag_t _hea_tag, hb_tag_t _mtx_tag) { - this->default_advance = default_advance_; - this->num_metrics = face->get_num_glyphs (); + this->default_advance = face->get_upem (); hb_blob_t *_hea_blob = OT::Sanitizer::sanitize (face->reference_table (_hea_tag)); const OT::_hea *_hea = OT::Sanitizer::lock_instance (_hea_blob); @@ -58,8 +56,16 @@ struct hb_ot_face_metrics_accelerator_t hb_blob_destroy (_hea_blob); this->blob = OT::Sanitizer::sanitize (face->reference_table (_mtx_tag)); - if (unlikely (!this->num_advances || - 2 * (this->num_advances + this->num_metrics) > hb_blob_get_length (this->blob))) + + /* Cap num_metrics() and num_advances() based on table length. */ + unsigned int len = hb_blob_get_length (this->blob); + if (unlikely (this->num_advances * 4 < len)) + this->num_advances = len / 4; + this->num_metrics = this->num_advances + (len - 4 * this->num_advances) / 2; + + /* We MUSt set num_metrics to zero if num_advances is zero. + * Our get_advance() depends on that. */ + if (unlikely (!this->num_advances)) { this->num_metrics = this->num_advances = 0; hb_blob_destroy (this->blob); @@ -245,11 +251,9 @@ _hb_ot_font_create (hb_face_t *face) if (unlikely (!ot_font)) return NULL; - unsigned int upem = face->get_upem (); - ot_font->cmap.init (face); - ot_font->h_metrics.init (face, HB_OT_TAG_hhea, HB_OT_TAG_hmtx, upem>>1); - ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, upem); /* TODO Can we do this lazily? */ + ot_font->h_metrics.init (face, HB_OT_TAG_hhea, HB_OT_TAG_hmtx); + ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx); /* TODO Can we do this lazily? */ ot_font->glyf.init (face); return ot_font; diff --git a/test/shaping/tests/fuzzed.tests b/test/shaping/tests/fuzzed.tests index 5f64ccc29..6bb30b0fd 100644 --- a/test/shaping/tests/fuzzed.tests +++ b/test/shaping/tests/fuzzed.tests @@ -1,5 +1,5 @@ -fonts/sha1sum/1a6f1687b7a221f9f2c834b0b360d3c8463b6daf.ttf::U+0041:[gid0=0+1000] -fonts/sha1sum/5a5daf5eb5a4db77a2baa3ad9c7a6ed6e0655fa8.ttf::U+0041:[gid0=0+1000] -fonts/sha1sum/0509e80afb379d16560e9e47bdd7d888bebdebc6.ttf::U+0041:[gid0=0+1000] -fonts/sha1sum/641bd9db850193064d17575053ae2bf8ec149ddc.ttf::U+0041:[gid0=0+1000] -fonts/sha1sum/375d6ae32a3cbe52fbf81a4e5777e3377675d5a3.ttf::U+0041:[gid0=0+2048] +fonts/sha1sum/1a6f1687b7a221f9f2c834b0b360d3c8463b6daf.ttf:--font-funcs=ot:U+0041:[gid0=0+1000] +fonts/sha1sum/5a5daf5eb5a4db77a2baa3ad9c7a6ed6e0655fa8.ttf:--font-funcs=ot:U+0041:[gid0=0+1000] +fonts/sha1sum/0509e80afb379d16560e9e47bdd7d888bebdebc6.ttf:--font-funcs=ot:U+0041:[gid0=0+1000] +fonts/sha1sum/641bd9db850193064d17575053ae2bf8ec149ddc.ttf:--font-funcs=ot:U+0041:[gid0=0+1000] +fonts/sha1sum/375d6ae32a3cbe52fbf81a4e5777e3377675d5a3.ttf:--font-funcs=ot:U+0041:[gid0=0+4352]