mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-08-11 12:07:38 +00:00
Fix use-after-free in CallAfter lambda; replace raw thread pointer with unique_ptr
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
#include "WebGuideDialog.hpp"
|
#include "WebGuideDialog.hpp"
|
||||||
#include "ConfigWizard.hpp"
|
#include "ConfigWizard.hpp"
|
||||||
|
|
||||||
#include <boost/filesystem/operations.hpp>
|
#include <boost/filesystem/operations.hpp>
|
||||||
@@ -191,11 +191,10 @@ GuideFrame::GuideFrame(GUI_App *pGUI, long style)
|
|||||||
GuideFrame::~GuideFrame()
|
GuideFrame::~GuideFrame()
|
||||||
{
|
{
|
||||||
m_destroy = true;
|
m_destroy = true;
|
||||||
if (m_load_task && m_load_task->joinable()) {
|
*m_cancel_token = true; // signal any queued CallAfter lambdas before join
|
||||||
|
if (m_load_task && m_load_task->joinable())
|
||||||
m_load_task->join();
|
m_load_task->join();
|
||||||
delete m_load_task;
|
m_load_task.reset();
|
||||||
m_load_task = nullptr;
|
|
||||||
}
|
|
||||||
if (m_browser) {
|
if (m_browser) {
|
||||||
delete m_browser;
|
delete m_browser;
|
||||||
m_browser = nullptr;
|
m_browser = nullptr;
|
||||||
@@ -362,11 +361,11 @@ void GuideFrame::OnNavigationComplete(wxWebViewEvent &evt)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Steps 3+4 are slow — delegate to background thread.
|
// Steps 3+4 are slow — delegate to background thread.
|
||||||
m_load_task = new boost::thread(boost::bind(&GuideFrame::LoadProfileData, this));
|
m_load_task = std::make_unique<boost::thread>(boost::bind(&GuideFrame::LoadProfileData, this));
|
||||||
}
|
}
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ", init error: " << e.what();
|
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ", init error: " << e.what();
|
||||||
m_load_task = new boost::thread(boost::bind(&GuideFrame::LoadProfileData, this));
|
m_load_task = std::make_unique<boost::thread>(boost::bind(&GuideFrame::LoadProfileData, this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1580,8 +1579,11 @@ int GuideFrame::LoadProfileData()
|
|||||||
if (!m_destroy)
|
if (!m_destroy)
|
||||||
save_guide_cache();
|
save_guide_cache();
|
||||||
|
|
||||||
wxGetApp().CallAfter([this] {
|
// Capture the cancel token by value (shared_ptr) so the lambda doesn't
|
||||||
if (!m_destroy)
|
// touch `this` if GuideFrame is destroyed before the event fires.
|
||||||
|
auto tok = m_cancel_token;
|
||||||
|
wxGetApp().CallAfter([this, tok] {
|
||||||
|
if (!*tok)
|
||||||
on_profile_loaded();
|
on_profile_loaded();
|
||||||
});
|
});
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
|
|||||||
@@ -31,10 +31,13 @@
|
|||||||
#include "slic3r/Utils/PresetUpdater.hpp"
|
#include "slic3r/Utils/PresetUpdater.hpp"
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <memory>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
#include <boost/thread.hpp>
|
||||||
|
|
||||||
namespace Slic3r { namespace GUI {
|
namespace Slic3r { namespace GUI {
|
||||||
|
|
||||||
class GuideFrame : public DPIDialog
|
class GuideFrame : public DPIDialog
|
||||||
@@ -120,7 +123,10 @@ private:
|
|||||||
//First Load
|
//First Load
|
||||||
bool bFirstComplete{false};
|
bool bFirstComplete{false};
|
||||||
std::atomic<bool> m_destroy{false};
|
std::atomic<bool> m_destroy{false};
|
||||||
boost::thread* m_load_task{ nullptr };
|
// Shared cancel token captured by CallAfter lambdas so they don't touch
|
||||||
|
// `this` after the destructor has run and the object is freed.
|
||||||
|
std::shared_ptr<std::atomic<bool>> m_cancel_token{std::make_shared<std::atomic<bool>>(false)};
|
||||||
|
std::unique_ptr<boost::thread> m_load_task;
|
||||||
|
|
||||||
// User Config
|
// User Config
|
||||||
bool PrivacyUse;
|
bool PrivacyUse;
|
||||||
|
|||||||
Reference in New Issue
Block a user