From 8cda26604462a4941818b7c9574851d9a07acebf Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Fri, 11 Dec 2009 11:39:11 +1000 Subject: Throw error when attempting to write to a read-only property via script. --- src/declarative/qml/qmlobjectscriptclass.cpp | 15 +++++++++------ .../auto/declarative/qmlecmascript/data/scriptErrors.qml | 3 ++- tests/auto/declarative/qmlecmascript/testtypes.h | 1 + .../auto/declarative/qmlecmascript/tst_qmlecmascript.cpp | 4 ++++ 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/declarative/qml/qmlobjectscriptclass.cpp b/src/declarative/qml/qmlobjectscriptclass.cpp index 7a2b132..d7ab631 100644 --- a/src/declarative/qml/qmlobjectscriptclass.cpp +++ b/src/declarative/qml/qmlobjectscriptclass.cpp @@ -155,12 +155,8 @@ QmlObjectScriptClass::queryProperty(QObject *obj, const Identifier &name, lastData = &local; } - if (lastData) { - QScriptClass::QueryFlags rv = QScriptClass::HandlesReadAccess; - if (lastData->flags & QmlPropertyCache::Data::IsWritable) - rv |= QScriptClass::HandlesWriteAccess; - return rv; - } + if (lastData) + return QScriptClass::HandlesReadAccess | QScriptClass::HandlesWriteAccess; if (!evalContext && context()) { // Global object, QScriptContext activation object, QmlContext object @@ -267,6 +263,13 @@ void QmlObjectScriptClass::setProperty(QObject *obj, Q_ASSERT(obj); Q_ASSERT(lastData); + if (!(lastData->flags & QmlPropertyCache::Data::IsWritable)) { + QString error = QLatin1String("Cannot assign to read-only property \"") + + toString(name) + QLatin1Char('\"'); + if (context()) + context()->throwError(error); + } + QmlEnginePrivate *enginePriv = QmlEnginePrivate::get(engine); if (!evalContext && context()) { diff --git a/tests/auto/declarative/qmlecmascript/data/scriptErrors.qml b/tests/auto/declarative/qmlecmascript/data/scriptErrors.qml index 9d99b41..5c8b1f8 100644 --- a/tests/auto/declarative/qmlecmascript/data/scriptErrors.qml +++ b/tests/auto/declarative/qmlecmascript/data/scriptErrors.qml @@ -10,6 +10,7 @@ MyQmlObject { property int y: (a.value, undefinedObject) onBasicSignal: { console.log(a.value); } - + id: myObj + onAnotherBasicSignal: myObj.trueProperty = false; } diff --git a/tests/auto/declarative/qmlecmascript/testtypes.h b/tests/auto/declarative/qmlecmascript/testtypes.h index d566681..d7f7d31 100644 --- a/tests/auto/declarative/qmlecmascript/testtypes.h +++ b/tests/auto/declarative/qmlecmascript/testtypes.h @@ -117,6 +117,7 @@ signals: void argumentSignal(int a, QString b, qreal c); void stringChanged(); void objectChanged(); + void anotherBasicSignal(); public slots: void deleteMe() { delete this; } diff --git a/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp b/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp index c3c7977..30ecc51 100644 --- a/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp +++ b/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp @@ -830,6 +830,7 @@ void tst_qmlecmascript::scriptErrors() QString warning4 = url + ":12: TypeError: Result of expression 'a' [undefined] is not an object."; QString warning5 = url + ":10: TypeError: Result of expression 'a' [undefined] is not an object."; QString warning6 = url + ":9: Unable to assign [undefined] to int"; + QString warning7 = url + ":14: Error: Cannot assign to read-only property \"trueProperty\""; QTest::ignoreMessage(QtWarningMsg, warning1.toLatin1().constData()); QTest::ignoreMessage(QtWarningMsg, warning2.toLatin1().constData()); @@ -841,6 +842,9 @@ void tst_qmlecmascript::scriptErrors() QTest::ignoreMessage(QtWarningMsg, warning4.toLatin1().constData()); emit object->basicSignal(); + + QTest::ignoreMessage(QtWarningMsg, warning7.toLatin1().constData()); + emit object->anotherBasicSignal(); } /* -- cgit v0.12