diff options
author | Morten Sørvig <morten.sorvig@qt.io> | 2022-11-11 12:41:06 +0100 |
---|---|---|
committer | Morten Johan Sørvig <morten.sorvig@qt.io> | 2022-12-28 18:14:44 +0000 |
commit | 8a20a278fa5f1e2890f88a69d8b5f96873a67ac9 (patch) | |
tree | f09ada567397adee57154d982ded6c45118564a1 /src/corelib/io | |
parent | ce560d28c8b426d3cb797fa04e9e78d980fc8501 (diff) |
wasm: avoid LocalStorage past-the-end access on clear()
We were looping over all keys and removing the Qt keys
using an integer index. However, removing one key shifts
all other keys at higher indexes down one step such that
the loop eventually indexes past the end.
Fix this by getting the keys first in a separate step,
and then remove keys without relying on a stable iteration
order (which is also not guaranteed by the standard).
Pick-to: 6.4 6.5
Change-Id: I8bc577d1831d6931ebca2b2e04faf65c9affb429
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
Diffstat (limited to 'src/corelib/io')
-rw-r--r-- | src/corelib/io/qsettings_wasm.cpp | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/src/corelib/io/qsettings_wasm.cpp b/src/corelib/io/qsettings_wasm.cpp index 8404a526b6..15ab688abe 100644 --- a/src/corelib/io/qsettings_wasm.cpp +++ b/src/corelib/io/qsettings_wasm.cpp @@ -122,13 +122,21 @@ QStringList QWasmLocalStorageSettingsPrivate::children(const QString &prefix, Ch void QWasmLocalStorageSettingsPrivate::clear() { - // Remove all Qt keys from window.localStorage + // Get all Qt keys from window.localStorage const int length = m_localStorage["length"].as<int>(); + std::vector<std::string> keys; + keys.reserve(length); for (int i = 0; i < length; ++i) { - std::string fullKey = (m_localStorage.call<val>("key", i).as<std::string>()); - QString key = QString::fromStdString(fullKey); - if (removeStoragePrefix(QStringView(key)).isEmpty() == false) - m_localStorage.call<val>("removeItem", fullKey); + std::string key = (m_localStorage.call<val>("key", i).as<std::string>()); + keys.push_back(std::move(key)); + } + + // Remove all Qt keys. Note that localStorage does not guarantee a stable + // iteration order when the storage is mutated, which is why removal is done + // in a second step after getting all keys. + for (std::string key: keys) { + if (removeStoragePrefix(QString::fromStdString(key)).isEmpty() == false) + m_localStorage.call<val>("removeItem", key); } } |