From: Behdad Esfahbod Date: Thu, 31 Jan 2019 00:03:16 +0000 (-0800) Subject: [iter] Fix mystery crash X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2d940946d5af0e3869a2324b6e36ca8ea3698c48;p=platform%2Fupstream%2FlibHarfBuzzSharp.git [iter] Fix mystery crash Fuzzer caught it: ==14==ERROR: AddressSanitizer: stack-use-after-return on address 0x7fca2ed7a3e0 at pc 0x0000006057aa bp 0x7ffc3290f1d0 sp 0x7ffc3290f1c8 READ of size 4 at 0x7fca2ed7a3e0 thread T0 SCARINESS: 55 (4-byte-read-stack-use-after-return) #0 0x6057a9 in OT::SingleSubstFormat2::subset(hb_subset_context_t*) const /src/harfbuzz/src/./hb-ot-layout-gsub-table.hh:194:40 #1 0x5ff921 in hb_subset_context_t::return_t OT::SingleSubst::dispatch(hb_subset_context_t*) const /src/harfbuzz/src/./hb-ot-layout-gsub-table.hh:256:13 I can't reproduce locally, but many of the bots are failing because of this as well. It's a pity that operator-> must return pointer. Ugh. Why?! --- diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 105379e..290e6af 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -71,6 +71,10 @@ struct hb_iter_t iter_t operator + () const { return *thiz(); } explicit_operator bool () const { return thiz()->__more__ (); } unsigned len () const { return thiz()->__len__ (); } + /* The following can only be enabled if item_t is reference type. Otherwise + * it will be returning pointer to temporary rvalue. */ + template hb_remove_reference (item_t)* operator -> () const { return hb_addressof (**thiz()); } item_t operator * () const { return thiz()->__item__ (); } item_t operator [] (unsigned i) const { return thiz()->__item_at__ (i); } diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index 518afaa..dd6f017 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -191,8 +191,8 @@ struct SingleSubstFormat2 for (auto it = hb_zip (this+coverage, substitute) | hb_filter (glyphset, hb_first); it; ++it) { - from.push ()->set (glyph_map[it->first]); - to.push ()->set (glyph_map[it->second]); + from.push ()->set (glyph_map[(*it).first]); + to.push ()->set (glyph_map[(*it).second]); } c->serializer->propagate_error (from, to); SingleSubst_serialize (c->serializer, from, to);