summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKent Hansen <khansen@trolltech.com>2009-09-22 18:01:43 (GMT)
committerKent Hansen <khansen@trolltech.com>2009-09-22 18:04:43 (GMT)
commit66da7e609e92fff2322c1ef42e4ac9132bc33fab (patch)
treeac1ce13e436e658cb54273a8cc598b58d0136c40
parent1f67584c5260b0d9f275ed5f3a24e444168ec3eb (diff)
downloadQt-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.cpp14
-rw-r--r--src/script/bridge/qscriptclassobject.cpp1
-rw-r--r--tests/auto/qscriptclass/tst_qscriptclass.cpp12
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()