Fix #492: wait for async backup before destroying QETProject

writeBackup() fires QtConcurrent::run(QET::writeToFile, ..., &m_backup_file)
fire-and-forget: the QFuture was discarded and nothing kept m_backup_file
alive until the worker finished. If the QETProject was destroyed first, the
worker wrote through the freed member -> use-after-free crash in
QET::writeToFile (intermittent; ~1/6 on short-lived CLI runs).

Store the QFuture and waitForFinished() in ~QETProject (and before
setFilePath() re-points the managed backup file). Also skip launching a new
backup while one is still running, so two threads never write m_backup_file
at once.

The Qt6 path is still a TODO stub and the QtConcurrent block is KF5-only, so
this affects only the Qt5/KF5 build that actually has the backup code.
This commit is contained in:
ispyisail
2026-06-19 08:34:02 +12:00
parent bd37f12edc
commit bf4d3353ae
2 changed files with 14 additions and 1 deletions
+2
View File
@@ -35,6 +35,7 @@
#endif
#include <QHash>
#include <QFuture>
class Diagram;
class ElementsLocation;
@@ -295,6 +296,7 @@ class QETProject : public QObject
bool m_freeze_new_conductors = false;
QTimer m_save_backup_timer,
m_autosave_timer;
QFuture<bool> m_backup_future;
#ifdef BUILD_WITHOUT_KF5
#else
KAutoSaveFile m_backup_file;