Details
-
Bug
-
Resolution: Done
-
P1: Critical
-
5.15.2, 6.0
-
9b321a34490cd17c0eb043b69bd7c9d8d8f513d5 (qt/qtdeclarative/dev) b3848de6945d8514b6bea0909659310cbe38af61 (qt/qtdeclarative/6.0) 810a0afe1e9bd14e4393a73bf6c299b25745dbc5 (qt/qtdeclarative/5.15)
Description
Calling hasOwnProperty() on a proxy object correctly invokes the getOwnPropertyDescriptor() trap. But the program crashes because QV4::ProxyObject::virtualGetOwnProperty() tries to assign data to a null-pointer at https://code.qt.io/cgit/qt/qtdeclarative.git/tree/src/qml/jsruntime/qv4proxy.cpp?h=5.15.2#n268
Example:
#include <QtCore/qcoreapplication.h> #include <QtCore/qdebug.h> #include <QtCore/qobject.h> #include <QtCore/qtimer.h> #include <QtCore/qstring.h> #include <QtQml/qjsengine.h> #include <QtQml/qjsvalue.h> static const QString jsCode = QStringLiteral(R"666( (function(handler){ const target = {}; const proxy = new Proxy(target, handler); if (proxy.hasOwnProperty("does_not_exist")) { // crashes console.log("FAIL"); } else { console.log("SUCCESS"); } }) )666"); class ProxyHandler: public QObject { Q_OBJECT public: // This is a non-sense handler, but should be valid. Q_INVOKABLE QJSValue getOwnPropertyDescriptor(QJSValue target, const QJSValue &key) { Q_ASSERT(key.isString()); QJSValue result; QString name = key.toString(); if (target.hasOwnProperty(name)) { QJSValue value = target.property(name); result = qjsEngine(this)->newObject(); result.setProperty(QStringLiteral("configurable"), true); result.setProperty(QStringLiteral("enumerable"), true); result.setProperty(QStringLiteral("writable"), false); result.setProperty(QStringLiteral("value"), value); } return result; } }; void test() { QJSEngine engine; engine.installExtensions(QJSEngine::ConsoleExtension); QJSValue proxyTest = engine.evaluate(jsCode, QStringLiteral("proxy.js")); if (proxyTest.isError()) qWarning() << "Error: " << proxyTest.toString(); Q_ASSERT(!proxyTest.isError()); QJSValue handler = engine.newQObject(new ProxyHandler()); QJSValue result = proxyTest.call(QJSValueList{ handler }); if (result.isError()) qWarning() << "Error: " << result.toString(); Q_ASSERT(!result.isError()); QCoreApplication::exit(0); } int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); QTimer::singleShot(0, &test); return app.exec(); } #include "main.moc"
The Object.isEnumerableProperty() is affected, too.
Attachments
Issue Links
- is required for
-
QBS-913 QtScript dependency needs to be removed
- Closed