summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/3rdparty/webkit/VERSION2
-rw-r--r--src/3rdparty/webkit/WebCore/ChangeLog13
-rw-r--r--src/3rdparty/webkit/WebCore/plugins/symbian/PluginViewSymbian.cpp2
-rw-r--r--src/script/api/qscriptengine.cpp8
-rw-r--r--src/script/api/qscriptvalue.cpp13
-rw-r--r--tests/auto/qscriptengine/tst_qscriptengine.cpp127
6 files changed, 159 insertions, 6 deletions
diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION
index 45608c5..7c9ea04 100644
--- a/src/3rdparty/webkit/VERSION
+++ b/src/3rdparty/webkit/VERSION
@@ -8,4 +8,4 @@ The commit imported was from the
and has the sha1 checksum
- e3dc4ef2b801d91e115c54f833fa7766d392ceda
+ 14feb62c96ffe2c37e3e2fdac4e370fdbc76ef62
diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog
index a2bd5c3..b7e46c7 100644
--- a/src/3rdparty/webkit/WebCore/ChangeLog
+++ b/src/3rdparty/webkit/WebCore/ChangeLog
@@ -1,3 +1,16 @@
+2010-04-09 David Leong <david.leong@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] Symbian apps crash on exit due to a bad qObject_cast.
+
+ https://bugs.webkit.org/show_bug.cgi?id=37303
+
+ Added check for NULL to avoid the crash.
+
+ * plugins/symbian/PluginViewSymbian.cpp:
+ (WebCore::PluginView::platformDestroy):
+
2009-11-15 Dave Tapuska <dtapuska@rim.com>
Reviewed by George Staikos.
diff --git a/src/3rdparty/webkit/WebCore/plugins/symbian/PluginViewSymbian.cpp b/src/3rdparty/webkit/WebCore/plugins/symbian/PluginViewSymbian.cpp
index 9e107cd..0c742a2 100644
--- a/src/3rdparty/webkit/WebCore/plugins/symbian/PluginViewSymbian.cpp
+++ b/src/3rdparty/webkit/WebCore/plugins/symbian/PluginViewSymbian.cpp
@@ -453,7 +453,7 @@ bool PluginView::platformStart()
void PluginView::platformDestroy()
{
QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient();
- if (QGraphicsWebView *webView = qobject_cast<QGraphicsWebView*>(client->pluginParent()))
+ if (client && qobject_cast<QGraphicsWebView*>(client->pluginParent()))
delete static_cast<PluginContainerSymbian*>(platformPluginWidget())->proxy();
else
delete platformPluginWidget();
diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp
index 13b8e7c..2417d80 100644
--- a/src/script/api/qscriptengine.cpp
+++ b/src/script/api/qscriptengine.cpp
@@ -1067,11 +1067,15 @@ void QScriptEnginePrivate::setGlobalObject(JSC::JSObject *object)
if (object == globalObject())
return;
QScript::GlobalObject *glob = static_cast<QScript::GlobalObject*>(originalGlobalObject());
- if (object == originalGlobalObjectProxy)
+ if (object == originalGlobalObjectProxy) {
glob->customGlobalObject = 0;
- else {
+ // Sync the internal prototype, since JSObject::prototype() is not virtual.
+ glob->setPrototype(originalGlobalObjectProxy->prototype());
+ } else {
Q_ASSERT(object != originalGlobalObject());
glob->customGlobalObject = object;
+ // Sync the internal prototype, since JSObject::prototype() is not virtual.
+ glob->setPrototype(object->prototype());
}
}
diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp
index 7469f9a..1310c8c 100644
--- a/src/script/api/qscriptvalue.cpp
+++ b/src/script/api/qscriptvalue.cpp
@@ -538,19 +538,28 @@ void QScriptValue::setPrototype(const QScriptValue &prototype)
"a different engine");
return;
}
+ JSC::JSObject *thisObject = JSC::asObject(d->jscValue);
JSC::JSValue other = d->engine->scriptValueToJSCValue(prototype);
// check for cycle
JSC::JSValue nextPrototypeValue = other;
while (nextPrototypeValue && nextPrototypeValue.isObject()) {
JSC::JSObject *nextPrototype = JSC::asObject(nextPrototypeValue);
- if (nextPrototype == JSC::asObject(d->jscValue)) {
+ if (nextPrototype == thisObject) {
qWarning("QScriptValue::setPrototype() failed: cyclic prototype value");
return;
}
nextPrototypeValue = nextPrototype->prototype();
}
- JSC::asObject(d->jscValue)->setPrototype(other);
+
+ thisObject->setPrototype(other);
+
+ // Sync the internal Global Object prototype if appropriate.
+ if (((thisObject == d->engine->originalGlobalObjectProxy)
+ && !d->engine->customGlobalObject())
+ || (thisObject == d->engine->customGlobalObject())) {
+ d->engine->originalGlobalObject()->setPrototype(other);
+ }
}
/*!
diff --git a/tests/auto/qscriptengine/tst_qscriptengine.cpp b/tests/auto/qscriptengine/tst_qscriptengine.cpp
index 3c6c7b2..25d8e3df 100644
--- a/tests/auto/qscriptengine/tst_qscriptengine.cpp
+++ b/tests/auto/qscriptengine/tst_qscriptengine.cpp
@@ -104,6 +104,8 @@ private slots:
void getSetGlobalObject();
void globalObjectProperties();
void globalObjectGetterSetterProperty();
+ void customGlobalObjectWithPrototype();
+ void globalObjectWithCustomPrototype();
void builtinFunctionNames_data();
void builtinFunctionNames();
void checkSyntax_data();
@@ -1177,6 +1179,131 @@ void tst_QScriptEngine::globalObjectGetterSetterProperty()
QVERIFY(global.property("baz").equals(789));
}
+void tst_QScriptEngine::customGlobalObjectWithPrototype()
+{
+ for (int x = 0; x < 2; ++x) {
+ QScriptEngine engine;
+ QScriptValue wrap = engine.newObject();
+ QScriptValue global = engine.globalObject();
+ QScriptValue originalGlobalProto = global.prototype();
+ if (!x) {
+ // Set prototype before setting global object
+ wrap.setPrototype(global);
+ QVERIFY(wrap.prototype().strictlyEquals(global));
+ engine.setGlobalObject(wrap);
+ } else {
+ // Set prototype after setting global object
+ engine.setGlobalObject(wrap);
+ wrap.setPrototype(global);
+ QVERIFY(wrap.prototype().strictlyEquals(global));
+ }
+ {
+ QScriptValue ret = engine.evaluate("print");
+ QVERIFY(ret.isFunction());
+ QVERIFY(ret.strictlyEquals(wrap.property("print")));
+ }
+ {
+ QScriptValue ret = engine.evaluate("this.print");
+ QVERIFY(ret.isFunction());
+ QVERIFY(ret.strictlyEquals(wrap.property("print")));
+ }
+ {
+ QScriptValue ret = engine.evaluate("hasOwnProperty('print')");
+ QVERIFY(ret.isBool());
+ QVERIFY(!ret.toBool());
+ }
+ {
+ QScriptValue ret = engine.evaluate("this.hasOwnProperty('print')");
+ QVERIFY(ret.isBool());
+ QVERIFY(!ret.toBool());
+ }
+
+ QScriptValue anotherProto = engine.newObject();
+ anotherProto.setProperty("anotherProtoProperty", 123);
+ global.setPrototype(anotherProto);
+ {
+ QScriptValue ret = engine.evaluate("print");
+ QVERIFY(ret.isFunction());
+ QVERIFY(ret.strictlyEquals(wrap.property("print")));
+ }
+ {
+ QScriptValue ret = engine.evaluate("anotherProtoProperty");
+ QVERIFY(ret.isNumber());
+ QVERIFY(ret.strictlyEquals(wrap.property("anotherProtoProperty")));
+ }
+ {
+ QScriptValue ret = engine.evaluate("this.anotherProtoProperty");
+ QVERIFY(ret.isNumber());
+ QVERIFY(ret.strictlyEquals(wrap.property("anotherProtoProperty")));
+ }
+
+ wrap.setPrototype(anotherProto);
+ {
+ QScriptValue ret = engine.evaluate("print");
+ QVERIFY(ret.isError());
+ QCOMPARE(ret.toString(), QString::fromLatin1("ReferenceError: Can't find variable: print"));
+ }
+ {
+ QScriptValue ret = engine.evaluate("anotherProtoProperty");
+ QVERIFY(ret.isNumber());
+ QVERIFY(ret.strictlyEquals(wrap.property("anotherProtoProperty")));
+ }
+ QVERIFY(global.prototype().strictlyEquals(anotherProto));
+
+ global.setPrototype(originalGlobalProto);
+ engine.setGlobalObject(global);
+ {
+ QScriptValue ret = engine.evaluate("anotherProtoProperty");
+ QVERIFY(ret.isError());
+ QCOMPARE(ret.toString(), QString::fromLatin1("ReferenceError: Can't find variable: anotherProtoProperty"));
+ }
+ {
+ QScriptValue ret = engine.evaluate("print");
+ QVERIFY(ret.isFunction());
+ QVERIFY(ret.strictlyEquals(global.property("print")));
+ }
+ QVERIFY(!anotherProto.property("print").isValid());
+ }
+}
+
+void tst_QScriptEngine::globalObjectWithCustomPrototype()
+{
+ QScriptEngine engine;
+ QScriptValue proto = engine.newObject();
+ proto.setProperty("protoProperty", 123);
+ QScriptValue global = engine.globalObject();
+ QScriptValue originalProto = global.prototype();
+ global.setPrototype(proto);
+ {
+ QScriptValue ret = engine.evaluate("protoProperty");
+ QVERIFY(ret.isNumber());
+ QVERIFY(ret.strictlyEquals(global.property("protoProperty")));
+ }
+ {
+ QScriptValue ret = engine.evaluate("this.protoProperty");
+ QVERIFY(ret.isNumber());
+ QVERIFY(ret.strictlyEquals(global.property("protoProperty")));
+ }
+ {
+ QScriptValue ret = engine.evaluate("hasOwnProperty('protoProperty')");
+ QVERIFY(ret.isBool());
+ QVERIFY(!ret.toBool());
+ }
+ {
+ QScriptValue ret = engine.evaluate("this.hasOwnProperty('protoProperty')");
+ QVERIFY(ret.isBool());
+ QVERIFY(!ret.toBool());
+ }
+
+ // Custom prototype set from JS
+ {
+ QScriptValue ret = engine.evaluate("this.__proto__ = { 'a': 123 }; a");
+ QVERIFY(ret.isNumber());
+ QEXPECT_FAIL("", "QTBUG-9737", Continue);
+ QVERIFY(ret.strictlyEquals(global.property("a")));
+ }
+}
+
void tst_QScriptEngine::builtinFunctionNames_data()
{
QTest::addColumn<QString>("expression");