From 548fbd814bdd77c8e537adf8745e5168533871c2 Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Thu, 10 Jul 2014 19:57:19 -0700 Subject: [PATCH] Fix a use-after-free when a SubsEditCtrl is destroyed while the thesaurus is loading --- src/thesaurus.cpp | 13 ++++++++++--- src/thesaurus.h | 3 +++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/thesaurus.cpp b/src/thesaurus.cpp index 7f0b396f5..025110a08 100644 --- a/src/thesaurus.cpp +++ b/src/thesaurus.cpp @@ -42,7 +42,7 @@ Thesaurus::Thesaurus() } Thesaurus::~Thesaurus() { - // Explicit empty destructor needed for scoped_ptr with incomplete types + if (cancel_load) *cancel_load = true; } std::vector Thesaurus::Lookup(std::string word) { @@ -98,11 +98,18 @@ void Thesaurus::OnLanguageChanged() { LOG_I("thesaurus/file") << "Using thesaurus: " << dat; + if (cancel_load) *cancel_load = true; + cancel_load = new bool{false}; + auto cancel = cancel_load; // Needed to avoid capturing via `this` agi::dispatch::Background().Async([=]{ try { auto thes = agi::make_unique(dat, idx); - agi::dispatch::Main().Sync([&thes, this]{ - impl = std::move(thes); + agi::dispatch::Main().Sync([&thes, cancel, this]{ + if (!*cancel) { + impl = std::move(thes); + cancel_load = nullptr; + } + delete cancel; }); } catch (agi::Exception const& e) { diff --git a/src/thesaurus.h b/src/thesaurus.h index 0383cce45..662dbb76b 100644 --- a/src/thesaurus.h +++ b/src/thesaurus.h @@ -39,6 +39,9 @@ class Thesaurus { agi::signal::Connection dict_path_listener; /// Thesaurus path change handler void OnPathChanged(); + + bool *cancel_load = nullptr; + public: /// A pair of a word and synonyms for that word typedef std::pair> Entry;