forked from quickshell/quickshell
core/reloader: null generation ref in reloadables on destruction
On the post-reload reloadable initialzation path, a timer is used to delay reload(). This change fixes a UAF when switching generations while that timer is running.
This commit is contained in:
parent
3edb3f4efa
commit
13b6eeaa22
2 changed files with 11 additions and 0 deletions
|
@ -16,6 +16,15 @@ void Reloadable::componentComplete() {
|
||||||
if (this->engineGeneration->reloadComplete) {
|
if (this->engineGeneration->reloadComplete) {
|
||||||
// Delayed due to Component.onCompleted running after QQmlParserStatus::componentComplete.
|
// Delayed due to Component.onCompleted running after QQmlParserStatus::componentComplete.
|
||||||
QTimer::singleShot(0, this, &Reloadable::onReloadFinished);
|
QTimer::singleShot(0, this, &Reloadable::onReloadFinished);
|
||||||
|
|
||||||
|
// This only matters for preventing the above timer from UAFing the generation,
|
||||||
|
// so it isn't connected anywhere else.
|
||||||
|
QObject::connect(
|
||||||
|
this->engineGeneration,
|
||||||
|
&QObject::destroyed,
|
||||||
|
this,
|
||||||
|
&Reloadable::onGenerationDestroyed
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
this->engineGeneration,
|
this->engineGeneration,
|
||||||
|
@ -43,6 +52,7 @@ void Reloadable::reload(QObject* oldInstance) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reloadable::onReloadFinished() { this->reload(nullptr); }
|
void Reloadable::onReloadFinished() { this->reload(nullptr); }
|
||||||
|
void Reloadable::onGenerationDestroyed() { this->engineGeneration = nullptr; }
|
||||||
|
|
||||||
void ReloadPropagator::onReload(QObject* oldInstance) {
|
void ReloadPropagator::onReload(QObject* oldInstance) {
|
||||||
auto* old = qobject_cast<ReloadPropagator*>(oldInstance);
|
auto* old = qobject_cast<ReloadPropagator*>(oldInstance);
|
||||||
|
|
|
@ -71,6 +71,7 @@ public:
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onReloadFinished();
|
void onReloadFinished();
|
||||||
|
void onGenerationDestroyed();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Called unconditionally in the reload phase, with nullptr if no source could be determined.
|
// Called unconditionally in the reload phase, with nullptr if no source could be determined.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue