Handle exceptions inside QV8QObjectConnectionList::qt_metacall
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>
This commit is contained in:
parent
7810092782
commit
8eec0518d6
|
@ -51,6 +51,7 @@
|
||||||
#include <private/qjsvalue_p.h>
|
#include <private/qjsvalue_p.h>
|
||||||
#include <private/qscript_impl_p.h>
|
#include <private/qscript_impl_p.h>
|
||||||
#include <private/qdeclarativeaccessors_p.h>
|
#include <private/qdeclarativeaccessors_p.h>
|
||||||
|
#include <private/qdeclarativeexpression_p.h>
|
||||||
|
|
||||||
#include <QtDeclarative/qjsvalue.h>
|
#include <QtDeclarative/qjsvalue.h>
|
||||||
#include <QtCore/qvarlengtharray.h>
|
#include <QtCore/qvarlengtharray.h>
|
||||||
|
@ -1229,11 +1230,22 @@ int QV8QObjectConnectionList::qt_metacall(QMetaObject::Call method, int index, v
|
||||||
Connection &connection = connections[ii];
|
Connection &connection = connections[ii];
|
||||||
if (connection.needsDestroy)
|
if (connection.needsDestroy)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
v8::TryCatch try_catch;
|
||||||
if (connection.thisObject.IsEmpty()) {
|
if (connection.thisObject.IsEmpty()) {
|
||||||
connection.function->Call(engine->global(), argCount, args.data());
|
connection.function->Call(engine->global(), argCount, args.data());
|
||||||
} else {
|
} else {
|
||||||
connection.function->Call(connection.thisObject, argCount, args.data());
|
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--;
|
connectionList.connectionsInUse--;
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -199,6 +199,7 @@ private slots:
|
||||||
void qtbug_11606();
|
void qtbug_11606();
|
||||||
void qtbug_11600();
|
void qtbug_11600();
|
||||||
void qtbug_21864();
|
void qtbug_21864();
|
||||||
|
void qobjectConnectionListExceptionHandling();
|
||||||
void nonscriptable();
|
void nonscriptable();
|
||||||
void deleteLater();
|
void deleteLater();
|
||||||
void in();
|
void in();
|
||||||
|
@ -5181,6 +5182,20 @@ void tst_qdeclarativeecmascript::qtbug_21864()
|
||||||
delete o;
|
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
|
// Reading and writing non-scriptable properties should fail
|
||||||
void tst_qdeclarativeecmascript::nonscriptable()
|
void tst_qdeclarativeecmascript::nonscriptable()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue