[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>(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 @@
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 <typename T = item_t,
+ hb_enable_if (hb_is_reference (T))>
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 @@
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);