Skip to content

Commit

Permalink
Handle exceptions inside QV8QObjectConnectionList::qt_metacall
Browse files Browse the repository at this point in the history
Previously, exceptions were not handled in the connectionlist.
This could cause v8 to assert under certain circumstances.

Task-number: QTBUG-23375
Change-Id: Ie5f043b50bb6b02a77be464ca18ea8e3bbb0f501
Reviewed-by: Alan Alpert <alan.alpert@nokia.com>
  • Loading branch information
Chris Adams authored and Qt by Nokia committed Dec 29, 2011
1 parent 7810092 commit 8eec051
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 0 deletions.
12 changes: 12 additions & 0 deletions src/declarative/qml/v8/qv8qobjectwrapper.cpp
Expand Up @@ -51,6 +51,7 @@
#include <private/qjsvalue_p.h>
#include <private/qscript_impl_p.h>
#include <private/qdeclarativeaccessors_p.h>
#include <private/qdeclarativeexpression_p.h>

#include <QtDeclarative/qjsvalue.h>
#include <QtCore/qvarlengtharray.h>
Expand Down Expand Up @@ -1229,11 +1230,22 @@ int QV8QObjectConnectionList::qt_metacall(QMetaObject::Call method, int index, v
Connection &connection = connections[ii];
if (connection.needsDestroy)
continue;

v8::TryCatch try_catch;
if (connection.thisObject.IsEmpty()) {
connection.function->Call(engine->global(), argCount, args.data());
} else {
connection.function->Call(connection.thisObject, argCount, args.data());
}

if (try_catch.HasCaught()) {
QDeclarativeError error;
error.setDescription(QString(QLatin1String("Unknown exception occurred during evaluation of connected function: %1")).arg(engine->toString(connection.function->GetName())));
v8::Local<v8::Message> message = try_catch.Message();
if (!message.IsEmpty())
QDeclarativeExpressionPrivate::exceptionToError(message, error);
QDeclarativeEnginePrivate::get(engine->engine())->warning(error);
}
}

connectionList.connectionsInUse--;
Expand Down
@@ -0,0 +1,24 @@
import QtQuick 2.0

Item {
id: root
property int first: 5
property bool test: false

Item {
id: exceptional
function exceptionalFunction() {
var obj = undefined;
var prop = undefined;
return obj[prop];
}
}

Component.onCompleted: {
root["firstChanged"].connect(exceptional.exceptionalFunction);
root["firstChanged"].connect(exceptional.exceptionalFunction);
root["firstChanged"].connect(exceptional.exceptionalFunction);
first = 6;
test = true;
}
}
Expand Up @@ -199,6 +199,7 @@ private slots:
void qtbug_11606();
void qtbug_11600();
void qtbug_21864();
void qobjectConnectionListExceptionHandling();
void nonscriptable();
void deleteLater();
void in();
Expand Down Expand Up @@ -5181,6 +5182,20 @@ void tst_qdeclarativeecmascript::qtbug_21864()
delete o;
}

void tst_qdeclarativeecmascript::qobjectConnectionListExceptionHandling()
{
// QTBUG-23375
QDeclarativeComponent component(&engine, testFileUrl("qobjectConnectionListExceptionHandling.qml"));
QString warning = component.url().toString() + QLatin1String(":13: TypeError: Cannot read property 'undefined' of undefined");
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
QObject *o = component.create();
QVERIFY(o != 0);
QCOMPARE(o->property("test").toBool(), true);
delete o;
}

// Reading and writing non-scriptable properties should fail
void tst_qdeclarativeecmascript::nonscriptable()
{
Expand Down

0 comments on commit 8eec051

Please sign in to comment.