diff options
author | Kent Hansen <khansen@trolltech.com> | 2009-09-22 18:01:43 (GMT) |
---|---|---|
committer | Kent Hansen <khansen@trolltech.com> | 2009-09-22 18:04:43 (GMT) |
commit | 66da7e609e92fff2322c1ef42e4ac9132bc33fab (patch) | |
tree | ac1ce13e436e658cb54273a8cc598b58d0136c40 | |
parent | 1f67584c5260b0d9f275ed5f3a24e444168ec3eb (diff) | |
download | Qt-66da7e609e92fff2322c1ef42e4ac9132bc33fab.zip Qt-66da7e609e92fff2322c1ef42e4ac9132bc33fab.tar.gz Qt-66da7e609e92fff2322c1ef42e4ac9132bc33fab.tar.bz2 |
don't crash in property access after script class has been set to 0
When the script class is set to 0, we need to remove the script
object's delegate entirely, because the delegate requires a non-0
script class in order to be useful.
Reviewed-by: Olivier Goffart
-rw-r--r-- | src/script/api/qscriptvalue.cpp | 14 | ||||
-rw-r--r-- | src/script/bridge/qscriptclassobject.cpp | 1 | ||||
-rw-r--r-- | tests/auto/qscriptclass/tst_qscriptclass.cpp | 12 |
3 files changed, 21 insertions, 6 deletions
diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp index 6a6381e..2a33aea 100644 --- a/src/script/api/qscriptvalue.cpp +++ b/src/script/api/qscriptvalue.cpp @@ -2409,12 +2409,16 @@ void QScriptValue::setScriptClass(QScriptClass *scriptClass) return; } QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(d->jscValue)); - QScriptObjectDelegate *delegate = scriptObject->delegate(); - if (!delegate || (delegate->type() != QScriptObjectDelegate::ClassObject)) { - delegate = new QScript::ClassObjectDelegate(scriptClass); - scriptObject->setDelegate(delegate); + if (!scriptClass) { + scriptObject->setDelegate(0); + } else { + QScriptObjectDelegate *delegate = scriptObject->delegate(); + if (!delegate || (delegate->type() != QScriptObjectDelegate::ClassObject)) { + delegate = new QScript::ClassObjectDelegate(scriptClass); + scriptObject->setDelegate(delegate); + } + static_cast<QScript::ClassObjectDelegate*>(delegate)->setScriptClass(scriptClass); } - static_cast<QScript::ClassObjectDelegate*>(delegate)->setScriptClass(scriptClass); } /*! diff --git a/src/script/bridge/qscriptclassobject.cpp b/src/script/bridge/qscriptclassobject.cpp index b57909f..c1e386b 100644 --- a/src/script/bridge/qscriptclassobject.cpp +++ b/src/script/bridge/qscriptclassobject.cpp @@ -77,6 +77,7 @@ QScriptClass *ClassObjectDelegate::scriptClass() const void ClassObjectDelegate::setScriptClass(QScriptClass *scriptClass) { + Q_ASSERT(scriptClass != 0); m_scriptClass = scriptClass; } diff --git a/tests/auto/qscriptclass/tst_qscriptclass.cpp b/tests/auto/qscriptclass/tst_qscriptclass.cpp index 71fcc79..608a134 100644 --- a/tests/auto/qscriptclass/tst_qscriptclass.cpp +++ b/tests/auto/qscriptclass/tst_qscriptclass.cpp @@ -625,6 +625,7 @@ void tst_QScriptClass::getAndSetProperty() QScriptValue obj2 = eng.newObject(&cls); QScriptString foo = eng.toStringHandle("foo"); QScriptString bar = eng.toStringHandle("bar"); + QScriptValue num(&eng, 123); // should behave just like normal for (int x = 0; x < 2; ++x) { @@ -644,7 +645,6 @@ void tst_QScriptClass::getAndSetProperty() // write property cls.clearReceivedArgs(); - QScriptValue num(&eng, 123); o.setProperty(s, num); QVERIFY(cls.lastQueryPropertyObject().strictlyEquals(o)); QVERIFY(cls.lastQueryPropertyName() == s); @@ -712,6 +712,16 @@ void tst_QScriptClass::getAndSetProperty() QVERIFY(cls.lastPropertyName() == foo2); QCOMPARE(cls.lastPropertyId(), foo2Id); } + + // remove script class; normal properties should remain + obj1.setScriptClass(0); + QCOMPARE(obj1.scriptClass(), (QScriptClass*)0); + QVERIFY(obj1.property(foo).equals(num)); + QVERIFY(obj1.property(bar).equals(num)); + obj1.setProperty(foo, QScriptValue()); + QVERIFY(!obj1.property(foo).isValid()); + obj1.setProperty(bar, QScriptValue()); + QVERIFY(!obj1.property(bar).isValid()); } void tst_QScriptClass::enumerate() |