src: fix boolean QJSValueList construction
What changed, and why it matters
This commit fixes a Qt 6 compatibility bug in the Monero GUI wallet. In Qt 6, passing a plain true/false value into a JavaScript callback argument list was being misread as a list size, so the callback received 'undefined' instead of the actual result. The fix explicitly wraps each value as a QJSValue. This is a reliability/functional bug, not a security vulnerability: there is no evidence it can be exploited to steal funds, run code, or bypass protections.
Treat as a normal bug-fix commit. No security response required. Ensure GUI builds against Qt 6 are regression-tested for async callback behavior.
Security signals we found
No memory corruption, injection, or privilege change present in diff
Change is a Qt API-usage correction, not a trust boundary or input validation change
No cryptographic, wallet-seed, or key-handling code modified
No references to CVEs, security advisories, or researcher attribution in commit
Evidence from the diff
The patch changes QJSValueList construction from brace-initializer syntax (e.g., QJSValueList({false})) to explicit QJSValue wrapping (QJSValueList{QJSValue(false)}). Under Qt 6, the old form could resolve to a size_t constructor overload, treating the boolean as a list capacity rather than a single element, leaving callbacks with undefined arguments. The affected async helpers are DaemonManager::stopAsync, runningAsync, sendCommandAsync and Wallet::storeAsync. The fix restores correct callback argument delivery.
Changed components
src/daemon/DaemonManager.cppsrc/libwalletqt/Wallet.cppInspect captured patch +6 / −6
diff --git a/src/daemon/DaemonManager.cpp b/src/daemon/DaemonManager.cpp
index 60feebc..449a3c6 100644
--- a/src/daemon/DaemonManager.cpp
+++ b/src/daemon/DaemonManager.cpp
@@ -148,12 +148,12 @@ void DaemonManager::stopAsync(NetworkType::Type nettype, const QString &dataDir,
QString message;
sendCommand({"exit"}, nettype, dataDir, message);
- return QJSValueList({stopWatcher(nettype, dataDir)});
+ return QJSValueList{QJSValue(stopWatcher(nettype, dataDir))};
}, callback);
if (!feature.first)
{
- QJSValue(callback).call(QJSValueList({false}));
+ QJSValue(callback).call(QJSValueList{QJSValue(false)});
}
}
@@ -252,7 +252,7 @@ bool DaemonManager::noSync() const noexcept
void DaemonManager::runningAsync(NetworkType::Type nettype, const QString &dataDir, const QJSValue& callback) const
{
m_scheduler.run([this, nettype, dataDir] {
- return QJSValueList({running(nettype, dataDir)});
+ return QJSValueList{QJSValue(running(nettype, dataDir))};
}, callback);
}
@@ -287,7 +287,7 @@ void DaemonManager::sendCommandAsync(const QStringList &cmd, NetworkType::Type n
{
m_scheduler.run([this, cmd, nettype, dataDir] {
QString message;
- return QJSValueList({sendCommand(cmd, nettype, dataDir, message)});
+ return QJSValueList{QJSValue(sendCommand(cmd, nettype, dataDir, message))};
}, callback);
}
diff --git a/src/libwalletqt/Wallet.cpp b/src/libwalletqt/Wallet.cpp
index bc086a1..8e32b52 100644
--- a/src/libwalletqt/Wallet.cpp
+++ b/src/libwalletqt/Wallet.cpp
@@ -230,12 +230,12 @@ void Wallet::storeAsync(const QJSValue &callback, const QString &path /* = "" */
[this, path] {
QMutexLocker locker(&m_asyncMutex);
- return QJSValueList({m_walletImpl->store(path.toStdString())});
+ return QJSValueList{QJSValue(m_walletImpl->store(path.toStdString()))};
},
callback);
if (!future.first)
{
- QJSValue(callback).call(QJSValueList({false}));
+ QJSValue(callback).call(QJSValueList{QJSValue(false)});
}
}
Why this scored 23/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.