From 06479ddfe3a9319fd371cd50f4d2f2316d51055a Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Sun, 2 Mar 2014 20:35:57 +0100 Subject: [new compiler] Add the correct object index to the custom parser Without the correct index the calls to astForBinding run out of bounds. Fixes tst_qqmllistmodel crash. Change-Id: I6fb8b77866cbf247e7373cdbece6833c92be3615 Reviewed-by: Lars Knoll --- src/qml/compiler/qqmltypecompiler.cpp | 2 +- src/qml/qml/qqmlcustomparser_p.h | 2 +- src/qml/types/qqmlconnections.cpp | 3 ++- src/qml/types/qqmlconnections_p.h | 2 +- src/qml/types/qqmllistmodel.cpp | 12 ++++++------ src/qml/types/qqmllistmodel_p.h | 4 ++-- src/quick/util/qquickpropertychanges.cpp | 3 ++- src/quick/util/qquickpropertychanges_p.h | 2 +- tests/auto/qml/qqmllanguage/testtypes.cpp | 6 ++++-- tests/auto/qml/qqmllanguage/testtypes.h | 6 +++--- 10 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp index d41f3bf1ec..4ee15a530c 100644 --- a/src/qml/compiler/qqmltypecompiler.cpp +++ b/src/qml/compiler/qqmltypecompiler.cpp @@ -1849,7 +1849,7 @@ bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledD customParser->compiler = this; QQmlCompiledData::CustomParserData data; data.bindings = customParserBindings; - data.compilationArtifact = customParser->compile(qmlUnit, customBindings); + data.compilationArtifact = customParser->compile(qmlUnit, objectIndex, customBindings); customParser->compiler = 0; customParserData->insert(objectIndex, data); const QList parserErrors = customParser->errors(); diff --git a/src/qml/qml/qqmlcustomparser_p.h b/src/qml/qml/qqmlcustomparser_p.h index 96810c2f40..4861456c3d 100644 --- a/src/qml/qml/qqmlcustomparser_p.h +++ b/src/qml/qml/qqmlcustomparser_p.h @@ -140,7 +140,7 @@ public: Flags flags() const { return m_flags; } virtual QByteArray compile(const QList &)=0; - virtual QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList &bindings) = 0; + virtual QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, int objectIndex, const QList &bindings) = 0; virtual void setCustomData(QObject *, const QByteArray &)=0; QList errors() const { return exceptions; } diff --git a/src/qml/types/qqmlconnections.cpp b/src/qml/types/qqmlconnections.cpp index b8920deb21..70f859ffe2 100644 --- a/src/qml/types/qqmlconnections.cpp +++ b/src/qml/types/qqmlconnections.cpp @@ -251,8 +251,9 @@ QQmlConnectionsParser::compile(const QList &props) return rv; } -QByteArray QQmlConnectionsParser::compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList &props) +QByteArray QQmlConnectionsParser::compile(const QV4::CompiledData::QmlUnit *qmlUnit, int objectIndex, const QList &props) { + Q_UNUSED(objectIndex) QByteArray rv; QDataStream ds(&rv, QIODevice::WriteOnly); diff --git a/src/qml/types/qqmlconnections_p.h b/src/qml/types/qqmlconnections_p.h index 2579e4c239..cb436b1eb4 100644 --- a/src/qml/types/qqmlconnections_p.h +++ b/src/qml/types/qqmlconnections_p.h @@ -85,7 +85,7 @@ class QQmlConnectionsParser : public QQmlCustomParser { public: virtual QByteArray compile(const QList &); - virtual QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList &props); + virtual QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, int objectIndex, const QList &props); virtual void setCustomData(QObject *, const QByteArray &); }; diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp index 0dc1c2c25c..fbf3c091c2 100644 --- a/src/qml/types/qqmllistmodel.cpp +++ b/src/qml/types/qqmllistmodel.cpp @@ -2385,10 +2385,10 @@ bool QQmlListModelParser::compileProperty(const QQmlCustomParserProperty &prop, return true; } -bool QQmlListModelParser::compileProperty(const QV4::CompiledData::QmlUnit *qmlUnit, const QV4::CompiledData::Binding *binding, QList &instr, QByteArray &data) +bool QQmlListModelParser::compileProperty(const QV4::CompiledData::QmlUnit *qmlUnit, int objectIndex, const QV4::CompiledData::Binding *binding, QList &instr, QByteArray &data) { - const quint32 targetObjectIndex = binding->value.objectIndex; if (binding->type >= QV4::CompiledData::Binding::Type_Object) { + const quint32 targetObjectIndex = binding->value.objectIndex; const QV4::CompiledData::Object *target = qmlUnit->objectAt(targetObjectIndex); QString objName = qmlUnit->header.stringAt(target->inheritedTypeNameIndex); if (objName != listElementTypeName) { @@ -2427,7 +2427,7 @@ bool QQmlListModelParser::compileProperty(const QV4::CompiledData::QmlUnit *qmlU li.dataIdx = ref; instr << li; - if (!compileProperty(qmlUnit, binding, instr, data)) + if (!compileProperty(qmlUnit, targetObjectIndex, binding, instr, data)) return false; li.type = ListInstruction::Pop; @@ -2466,7 +2466,7 @@ bool QQmlListModelParser::compileProperty(const QV4::CompiledData::QmlUnit *qmlU int v = evaluateEnum(script, &ok); if (!ok) { using namespace QQmlJS; - AST::Node *node = astForBinding(targetObjectIndex, binding->value.compiledScriptIndex); + AST::Node *node = astForBinding(objectIndex, binding->value.compiledScriptIndex); if (AST::ExpressionStatement *stmt = AST::cast(node)) node = stmt->expression; AST::StringLiteral *literal = 0; @@ -2552,7 +2552,7 @@ QByteArray QQmlListModelParser::compile(const QList &c return rv; } -QByteArray QQmlListModelParser::compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList &bindings) +QByteArray QQmlListModelParser::compile(const QV4::CompiledData::QmlUnit *qmlUnit, int objectIndex, const QList &bindings) { QList instr; QByteArray data; @@ -2564,7 +2564,7 @@ QByteArray QQmlListModelParser::compile(const QV4::CompiledData::QmlUnit *qmlUni error(binding, QQmlListModel::tr("ListModel: undefined property '%1'").arg(propName)); return QByteArray(); } - if (!compileProperty(qmlUnit, binding, instr, data)) + if (!compileProperty(qmlUnit, objectIndex, binding, instr, data)) return QByteArray(); } diff --git a/src/qml/types/qqmllistmodel_p.h b/src/qml/types/qqmllistmodel_p.h index 172d857687..1fd57f063c 100644 --- a/src/qml/types/qqmllistmodel_p.h +++ b/src/qml/types/qqmllistmodel_p.h @@ -160,7 +160,7 @@ class QQmlListModelParser : public QQmlCustomParser public: QQmlListModelParser() : QQmlCustomParser(QQmlCustomParser::AcceptsSignalHandlers) {} QByteArray compile(const QList &); - QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList &bindings); + QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, int objectIndex, const QList &bindings); void setCustomData(QObject *, const QByteArray &); private: @@ -176,7 +176,7 @@ private: ListInstruction *instructions() const; }; bool compileProperty(const QQmlCustomParserProperty &prop, QList &instr, QByteArray &data); - bool compileProperty(const QV4::CompiledData::QmlUnit *qmlUnit, const QV4::CompiledData::Binding *binding, QList &instr, QByteArray &data); + bool compileProperty(const QV4::CompiledData::QmlUnit *qmlUnit, int objectIndex, const QV4::CompiledData::Binding *binding, QList &instr, QByteArray &data); bool definesEmptyList(const QString &); diff --git a/src/quick/util/qquickpropertychanges.cpp b/src/quick/util/qquickpropertychanges.cpp index 7bb318fd79..916a605999 100644 --- a/src/quick/util/qquickpropertychanges.cpp +++ b/src/quick/util/qquickpropertychanges.cpp @@ -331,8 +331,9 @@ QQuickPropertyChangesParser::compile(const QList &prop return rv; } -QByteArray QQuickPropertyChangesParser::compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList &props) +QByteArray QQuickPropertyChangesParser::compile(const QV4::CompiledData::QmlUnit *qmlUnit, int objectIndex, const QList &props) { + Q_UNUSED(objectIndex) QList > data; for (int ii = 0; ii < props.count(); ++ii) compileList(data, QString(), qmlUnit, props.at(ii)); diff --git a/src/quick/util/qquickpropertychanges_p.h b/src/quick/util/qquickpropertychanges_p.h index 081ea72862..5073f3aca5 100644 --- a/src/quick/util/qquickpropertychanges_p.h +++ b/src/quick/util/qquickpropertychanges_p.h @@ -96,7 +96,7 @@ public: void compileList(QList > &list, const QString &pre, const QV4::CompiledData::QmlUnit *qmlUnit, const QV4::CompiledData::Binding *binding); virtual QByteArray compile(const QList &); - virtual QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList &props); + virtual QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, int objectIndex, const QList &props); virtual void setCustomData(QObject *, const QByteArray &); }; diff --git a/tests/auto/qml/qqmllanguage/testtypes.cpp b/tests/auto/qml/qqmllanguage/testtypes.cpp index b18e6133cb..895d5e75da 100644 --- a/tests/auto/qml/qqmllanguage/testtypes.cpp +++ b/tests/auto/qml/qqmllanguage/testtypes.cpp @@ -127,8 +127,9 @@ QByteArray CustomBindingParser::compile(const QList &p return result; } -QByteArray CustomBindingParser::compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList &bindings) +QByteArray CustomBindingParser::compile(const QV4::CompiledData::QmlUnit *qmlUnit, int objectIndex, const QList &bindings) { + Q_UNUSED(objectIndex) QByteArray result; QDataStream ds(&result, QIODevice::WriteOnly); @@ -222,9 +223,10 @@ QByteArray EnumSupportingCustomParser::compile(const QList &bindings) +QByteArray EnumSupportingCustomParser::compile(const QV4::CompiledData::QmlUnit *qmlUnit, int objectIndex, const QList &bindings) { Q_UNUSED(qmlUnit) + Q_UNUSED(objectIndex) if (bindings.count() != 1) { error(bindings.first(), QStringLiteral("Custom parser invoked incorrectly for unit test")); diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h index 5086180da1..fb1dc3ca67 100644 --- a/tests/auto/qml/qqmllanguage/testtypes.h +++ b/tests/auto/qml/qqmllanguage/testtypes.h @@ -723,7 +723,7 @@ class MyCustomParserTypeParser : public QQmlCustomParser { public: QByteArray compile(const QList &) { return QByteArray(); } - QByteArray compile(const QV4::CompiledData::QmlUnit *, const QList &) { return QByteArray(); } + QByteArray compile(const QV4::CompiledData::QmlUnit *, int, const QList &) { return QByteArray(); } void setCustomData(QObject *, const QByteArray &) {} }; @@ -731,7 +731,7 @@ class EnumSupportingCustomParser : public QQmlCustomParser { public: QByteArray compile(const QList &props); - QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList &bindings); + QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, int objectIndex, const QList &bindings); void setCustomData(QObject *, const QByteArray &) {} }; @@ -1103,7 +1103,7 @@ public: class CustomBindingParser : public QQmlCustomParser { virtual QByteArray compile(const QList &properties); - virtual QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList &bindings); + virtual QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, int objectIndex, const QList &bindings); virtual void setCustomData(QObject *object, const QByteArray &data); }; -- cgit v1.2.3