summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKent Hansen <kent.hansen@nokia.com>2010-11-08 14:03:05 (GMT)
committerKent Hansen <kent.hansen@nokia.com>2010-11-08 14:50:00 (GMT)
commit626f13421baf258407f03e3bf21ed67138d55ea4 (patch)
tree9d445d9b709f57734c515e752c46d8c3bf9704cd
parenta3a84a872bb731d375a431626ccfcde5a660dd72 (diff)
downloadQt-626f13421baf258407f03e3bf21ed67138d55ea4.zip
Qt-626f13421baf258407f03e3bf21ed67138d55ea4.tar.gz
Qt-626f13421baf258407f03e3bf21ed67138d55ea4.tar.bz2
Don't crash if QScriptClass property getter returns an invalid value
It's possible that a class claims to have a property of a given name (i.e. queryProperty() returns true), but returns an invalid value for that property. In that case we should silently convert the value to undefined, otherwise the value may wreak havoc in JS. This is a regression from Qt 4.5 (pre-JavaScriptCore-based), which had this check. Task-number: QTBUG-15079 Reviewed-by: Jedrzej Nowacki
-rw-r--r--src/script/bridge/qscriptclassobject.cpp12
-rw-r--r--tests/auto/qscriptclass/tst_qscriptclass.cpp21
2 files changed, 33 insertions, 0 deletions
diff --git a/src/script/bridge/qscriptclassobject.cpp b/src/script/bridge/qscriptclassobject.cpp
index dd229f1..228e755 100644
--- a/src/script/bridge/qscriptclassobject.cpp
+++ b/src/script/bridge/qscriptclassobject.cpp
@@ -78,6 +78,12 @@ bool ClassObjectDelegate::getOwnPropertySlot(QScriptObject* object,
scriptObject, scriptName, QScriptClass::HandlesReadAccess, &id);
if (flags & QScriptClass::HandlesReadAccess) {
QScriptValue value = m_scriptClass->property(scriptObject, scriptName, id);
+ if (!value.isValid()) {
+ // The class claims to have the property, but returned an invalid
+ // value. Silently convert to undefined to avoid the invalid value
+ // "escaping" into JS.
+ value = QScriptValue(QScriptValue::UndefinedValue);
+ }
slot.setValue(engine->scriptValueToJSCValue(value));
return true;
}
@@ -119,6 +125,12 @@ bool ClassObjectDelegate::getOwnPropertyDescriptor(QScriptObject *object,
attribs |= pflags & QScriptValue::UserRange;
// Rather than calling the getter, we could return an access descriptor here.
QScriptValue value = m_scriptClass->property(scriptObject, scriptName, id);
+ if (!value.isValid()) {
+ // The class claims to have the property, but returned an invalid
+ // value. Silently convert to undefined to avoid the invalid value
+ // "escaping" into JS.
+ value = QScriptValue(QScriptValue::UndefinedValue);
+ }
descriptor.setDescriptor(engine->scriptValueToJSCValue(value), attribs);
return true;
}
diff --git a/tests/auto/qscriptclass/tst_qscriptclass.cpp b/tests/auto/qscriptclass/tst_qscriptclass.cpp
index b4dbe73..da6c76f 100644
--- a/tests/auto/qscriptclass/tst_qscriptclass.cpp
+++ b/tests/auto/qscriptclass/tst_qscriptclass.cpp
@@ -66,6 +66,7 @@ public:
private slots:
void newInstance();
void getAndSetProperty();
+ void getProperty_invalidValue();
void enumerate();
void extension();
};
@@ -741,6 +742,26 @@ void tst_QScriptClass::getAndSetProperty()
QVERIFY(!obj1.property(bar).isValid());
}
+void tst_QScriptClass::getProperty_invalidValue()
+{
+ QScriptEngine eng;
+ TestClass cls(&eng);
+ cls.addCustomProperty(eng.toStringHandle("foo"), QScriptClass::HandlesReadAccess,
+ /*id=*/0, QScriptValue::ReadOnly, QScriptValue());
+ QScriptValue obj = eng.newObject(&cls);
+
+ QVERIFY(obj.property("foo").isUndefined());
+
+ eng.globalObject().setProperty("obj", obj);
+ QVERIFY(eng.evaluate("obj.hasOwnProperty('foo'))").toBool());
+ // The JS environment expects that a valid value is returned,
+ // otherwise we could crash.
+ QVERIFY(eng.evaluate("obj.foo").isUndefined());
+ QVERIFY(eng.evaluate("obj.foo + ''").isString());
+ QVERIFY(eng.evaluate("Object.getOwnPropertyDescriptor(obj, 'foo').value").isUndefined());
+ QVERIFY(eng.evaluate("Object.getOwnPropertyDescriptor(obj, 'foo').value +''").isString());
+}
+
void tst_QScriptClass::enumerate()
{
QScriptEngine eng;