diff --git a/build-deps.sh b/build-deps.sh index 50522b4..220acd8 100755 --- a/build-deps.sh +++ b/build-deps.sh @@ -56,6 +56,7 @@ patch -p1 < $SCRIPT_DIR/patches/qt/qt.patch pushd qtbase patch -p1 < $SCRIPT_DIR/patches/qt/qtcore-5.15.2-gcc11.patch patch -p1 < $SCRIPT_DIR/patches/qt/0008-Add-missing-limits-include.patch +patch -p1 < $SCRIPT_DIR/patches/qt/wasm-settings.patch popd ./configure -xplatform wasm-emscripten -nomake examples -prefix $PWD/qtbase -feature-thread -opensource -confirm-license make module-qtbase module-qtdeclarative qtsvg -j$(nproc) diff --git a/patches/qt/wasm-settings.patch b/patches/qt/wasm-settings.patch new file mode 100644 index 0000000..fccdbdd --- /dev/null +++ b/patches/qt/wasm-settings.patch @@ -0,0 +1,139 @@ +From 25c2d05340eee01cf55457b8327f8f69d408879a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Morten=20S=C3=B8rvig?= +Date: Fri, 24 Jun 2022 13:10:33 +0200 +Subject: wasm: don't access deleted settings objects +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The emscripten_idb_async_ functions are async, so there +is no guarantee that the QSettings object which made +the request will be live by the time the completion +callback is made. + +Keep track of live QWasmSettingsPrivate objects, return +early from the callbacks if userData does not point +to a valid QWasmSettingsPrivate. + +Pick-to: 6.4 6.3 6.2 5.15 +Change-Id: Ia319b1875dcf2c329ba27954e3f026e004fe0aac +Reviewed-by: Morten Johan Sørvig +Reviewed-by: Lorn Potter +--- + src/corelib/io/qsettings_wasm.cpp | 43 ++++++++++++++++++++++++++------------- + 1 file changed, 29 insertions(+), 14 deletions(-) + +(limited to 'src/corelib/io/qsettings_wasm.cpp') + +diff --git a/src/corelib/io/qsettings_wasm.cpp b/src/corelib/io/qsettings_wasm.cpp +index ba081997fd..5c15e6d89b 100644 +--- a/src/corelib/io/qsettings_wasm.cpp ++++ b/src/corelib/io/qsettings_wasm.cpp +@@ -13,6 +13,8 @@ + + #include + #include ++#include ++ + #include + + QT_BEGIN_NAMESPACE +@@ -27,6 +29,7 @@ public: + QWasmSettingsPrivate(QSettings::Scope scope, const QString &organization, + const QString &application); + ~QWasmSettingsPrivate(); ++ static QWasmSettingsPrivate *get(void *userData); + + std::optional get(const QString &key) const override; + QStringList children(const QString &prefix, ChildSpec spec) const override; +@@ -43,14 +46,19 @@ public: + private: + QString databaseName; + QString id; ++ static QList liveSettings; + }; + ++QList QWasmSettingsPrivate::liveSettings; ++ + static void QWasmSettingsPrivate_onLoad(void *userData, void *dataPtr, int size) + { +- QWasmSettingsPrivate *wasm = reinterpret_cast(userData); ++ QWasmSettingsPrivate *settings = QWasmSettingsPrivate::get(userData); ++ if (!settings) ++ return; + +- QFile file(wasm->fileName()); +- QFileInfo fileInfo(wasm->fileName()); ++ QFile file(settings->fileName()); ++ QFileInfo fileInfo(settings->fileName()); + QDir dir(fileInfo.path()); + if (!dir.exists()) + dir.mkpath(fileInfo.path()); +@@ -58,32 +66,29 @@ static void QWasmSettingsPrivate_onLoad(void *userData, void *dataPtr, int size) + if (file.open(QFile::WriteOnly)) { + file.write(reinterpret_cast(dataPtr), size); + file.close(); +- wasm->setReady(); ++ settings->setReady(); + } + } + + static void QWasmSettingsPrivate_onError(void *userData) + { +- QWasmSettingsPrivate *wasm = reinterpret_cast(userData); +- if (wasm) +- wasm->setStatus(QSettings::AccessError); ++ if (QWasmSettingsPrivate *settings = QWasmSettingsPrivate::get(userData)) ++ settings->setStatus(QSettings::AccessError); + } + + static void QWasmSettingsPrivate_onStore(void *userData) + { +- QWasmSettingsPrivate *wasm = reinterpret_cast(userData); +- if (wasm) +- wasm->setStatus(QSettings::NoError); ++ if (QWasmSettingsPrivate *settings = QWasmSettingsPrivate::get(userData)) ++ settings->setStatus(QSettings::NoError); + } + + static void QWasmSettingsPrivate_onCheck(void *userData, int exists) + { +- QWasmSettingsPrivate *wasm = reinterpret_cast(userData); +- if (wasm) { ++ if (QWasmSettingsPrivate *settings = QWasmSettingsPrivate::get(userData)) { + if (exists) +- wasm->loadLocal(wasm->fileName().toLocal8Bit()); ++ settings->loadLocal(settings->fileName().toLocal8Bit()); + else +- wasm->setReady(); ++ settings->setReady(); + } + } + +@@ -114,6 +119,8 @@ QWasmSettingsPrivate::QWasmSettingsPrivate(QSettings::Scope scope, const QString + const QString &application) + : QConfFileSettingsPrivate(QSettings::NativeFormat, scope, organization, application) + { ++ liveSettings.push_back(this); ++ + setStatus(QSettings::AccessError); // access error until sandbox gets loaded + databaseName = organization; + id = application; +@@ -127,6 +134,14 @@ QWasmSettingsPrivate::QWasmSettingsPrivate(QSettings::Scope scope, const QString + + QWasmSettingsPrivate::~QWasmSettingsPrivate() + { ++ liveSettings.removeAll(this); ++} ++ ++QWasmSettingsPrivate *QWasmSettingsPrivate::get(void *userData) ++{ ++ if (QWasmSettingsPrivate::liveSettings.contains(reinterpret_cast(userData))) ++ return reinterpret_cast(userData); ++ return nullptr; + } + + void QWasmSettingsPrivate::initAccess() +-- +cgit v1.2.3 +