diff options
author | Chris Adams <christopher.adams@nokia.com> | 2012-02-02 14:51:17 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-02-09 07:32:07 +0100 |
commit | a4b4932efb631a3c467c9bb4b3e4f99ca70a066d (patch) | |
tree | da3f6180bab6a392c1b56e01fc62802349b4e037 /src/declarative | |
parent | 298b86b95bd42d12e15e8d8a137cd9bee21d6094 (diff) |
Check dynamic slot function for nullness before evaluation
Previously, we didn't check whether the function object handle
associated with a dynamic slot's method index was null before
attempting to evaluate it, which could cause a crash in some
circumstances. This change also adds better error reporting
during function compilation.
Task-number: QTBUG-24064
Task-number: QTBUG-24037
Task-number: QTBUG-23387
Change-Id: I3c5e35e8c16187870125736013a5935fcc5cb1f2
Reviewed-by: Aaron Kennedy <aaron.kennedy@nokia.com>
Diffstat (limited to 'src/declarative')
-rw-r--r-- | src/declarative/qml/qdeclarativeexpression.cpp | 26 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativevmemetaobject.cpp | 11 |
2 files changed, 34 insertions, 3 deletions
diff --git a/src/declarative/qml/qdeclarativeexpression.cpp b/src/declarative/qml/qdeclarativeexpression.cpp index 94ed7b7296..97afaa8281 100644 --- a/src/declarative/qml/qdeclarativeexpression.cpp +++ b/src/declarative/qml/qdeclarativeexpression.cpp @@ -148,13 +148,33 @@ QDeclarativeExpressionPrivate::evalFunction(QDeclarativeContextData *ctxt, QObje // QtScript days v8::HandleScope handle_scope; v8::Context::Scope ctxtscope(ep->v8engine()->context()); - + v8::TryCatch tc; v8::Local<v8::Object> scopeobject = ep->v8engine()->qmlScope(ctxt, scope); v8::Local<v8::Script> script = ep->v8engine()->qmlModeCompile(code, filename, line); - if (tc.HasCaught()) return v8::Persistent<v8::Function>(); + if (tc.HasCaught()) { + QDeclarativeError error; + error.setDescription(QLatin1String("Exception occurred during function compilation")); + error.setLine(line); + error.setUrl(QUrl::fromLocalFile(filename)); + v8::Local<v8::Message> message = tc.Message(); + if (!message.IsEmpty()) + QDeclarativeExpressionPrivate::exceptionToError(message, error); + ep->warning(error); + return v8::Persistent<v8::Function>(); + } v8::Local<v8::Value> result = script->Run(scopeobject); - if (tc.HasCaught()) return v8::Persistent<v8::Function>(); + if (tc.HasCaught()) { + QDeclarativeError error; + error.setDescription(QLatin1String("Exception occurred during function evaluation")); + error.setLine(line); + error.setUrl(QUrl::fromLocalFile(filename)); + v8::Local<v8::Message> message = tc.Message(); + if (!message.IsEmpty()) + QDeclarativeExpressionPrivate::exceptionToError(message, error); + ep->warning(error); + return v8::Persistent<v8::Function>(); + } if (qmlscope) *qmlscope = qPersistentNew<v8::Object>(scopeobject); return qPersistentNew<v8::Function>(v8::Local<v8::Function>::Cast(result)); } diff --git a/src/declarative/qml/qdeclarativevmemetaobject.cpp b/src/declarative/qml/qdeclarativevmemetaobject.cpp index e5c798e354..18b29f3411 100644 --- a/src/declarative/qml/qdeclarativevmemetaobject.cpp +++ b/src/declarative/qml/qdeclarativevmemetaobject.cpp @@ -730,6 +730,17 @@ int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation. v8::Handle<v8::Function> function = method(id); + if (function.IsEmpty()) { + // The function was not compiled. There are some exceptional cases which the + // expression rewriter does not rewrite properly (e.g., \r-terminated lines + // are not rewritten correctly but this bug is deemed out-of-scope to fix for + // performance reasons; see QTBUG-24064) and thus compilation will have failed. + QDeclarativeError e; + e.setDescription(QString(QLatin1String("Exception occurred during compilation of function: %1")).arg(QMetaObject::method(_id).signature())); + ep->warning(e); + return -1; // The dynamic method with that id is not available. + } + QDeclarativeVMEMetaData::MethodData *data = metaData->methodData() + id; v8::HandleScope handle_scope; |