From d71ef06fc1261968b8c5ecf7a438db02e2654b29 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 16 Jul 2009 17:08:50 +1000 Subject: Protect against overriding FINAL properties --- src/declarative/qml/qmlcompiler.cpp | 12 ++++++++++-- src/declarative/qml/qmldom.cpp | 4 ++-- src/declarative/qml/qmlparser.cpp | 2 +- src/declarative/qml/qmlparser_p.h | 2 +- src/declarative/qml/qmlscriptparser.cpp | 4 ++-- tests/auto/declarative/qmlparser/finalOverride.errors.txt | 1 + tests/auto/declarative/qmlparser/finalOverride.txt | 3 +++ tests/auto/declarative/qmlparser/testtypes.h | 2 +- tests/auto/declarative/qmlparser/tst_qmlparser.cpp | 1 + 9 files changed, 22 insertions(+), 9 deletions(-) create mode 100644 tests/auto/declarative/qmlparser/finalOverride.errors.txt create mode 100644 tests/auto/declarative/qmlparser/finalOverride.txt diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp index 182495a..b0bc6e8 100644 --- a/src/declarative/qml/qmlcompiler.cpp +++ b/src/declarative/qml/qmlcompiler.cpp @@ -160,8 +160,8 @@ bool QmlCompiler::isSignalPropertyName(const QByteArray &name) QString exceptionDescription; \ QmlError error; \ error.setUrl(output->url); \ - error.setLine(token->location.start.line); \ - error.setColumn(token->location.start.column); \ + error.setLine((token)->location.start.line); \ + error.setColumn((token)->location.start.column); \ QDebug d(&exceptionDescription); \ d << desc; \ error.setDescription(exceptionDescription.trimmed()); \ @@ -1738,6 +1738,14 @@ bool QmlCompiler::buildDynamicMeta(QmlParser::Object *obj, DynamicMetaMode mode) for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) { const Object::DynamicProperty &p = obj->dynamicProperties.at(ii); + int propIdx = + obj->metaObject()->indexOfProperty(p.name.constData()); + if (-1 != propIdx) { + QMetaProperty prop = obj->metaObject()->property(propIdx); + if (prop.isFinal()) + COMPILE_EXCEPTION(&p, "Cannot override FINAL property"); + } + if (p.isDefaultProperty && (p.type != Object::DynamicProperty::Alias || mode == ResolveAliases)) diff --git a/src/declarative/qml/qmldom.cpp b/src/declarative/qml/qmldom.cpp index 505d872..293ea6a 100644 --- a/src/declarative/qml/qmldom.cpp +++ b/src/declarative/qml/qmldom.cpp @@ -587,7 +587,7 @@ QmlDomProperty QmlDomDynamicProperty::defaultValue() const int QmlDomDynamicProperty::position() const { if (isValid()) { - return d->property.range.offset; + return d->property.location.range.offset; } else return -1; } @@ -599,7 +599,7 @@ int QmlDomDynamicProperty::position() const int QmlDomDynamicProperty::length() const { if (isValid()) - return d->property.range.length; + return d->property.location.range.length; else return -1; } diff --git a/src/declarative/qml/qmlparser.cpp b/src/declarative/qml/qmlparser.cpp index e2d334e..8eb58c8 100644 --- a/src/declarative/qml/qmlparser.cpp +++ b/src/declarative/qml/qmlparser.cpp @@ -146,7 +146,7 @@ QmlParser::Object::DynamicProperty::DynamicProperty(const DynamicProperty &o) type(o.type), name(o.name), defaultValue(o.defaultValue), - range(o.range) + location(o.location) { } diff --git a/src/declarative/qml/qmlparser_p.h b/src/declarative/qml/qmlparser_p.h index 84e6dd4..d23b4ea 100644 --- a/src/declarative/qml/qmlparser_p.h +++ b/src/declarative/qml/qmlparser_p.h @@ -169,7 +169,7 @@ namespace QmlParser Type type; QByteArray name; QmlParser::Property *defaultValue; - LocationRange range; + LocationSpan location; }; struct DynamicSignal { DynamicSignal(); diff --git a/src/declarative/qml/qmlscriptparser.cpp b/src/declarative/qml/qmlscriptparser.cpp index 5f97c71..c1c11c7 100644 --- a/src/declarative/qml/qmlscriptparser.cpp +++ b/src/declarative/qml/qmlscriptparser.cpp @@ -530,8 +530,8 @@ bool ProcessAST::visit(AST::UiPublicMember *node) property.isDefaultProperty = node->isDefaultMember; property.type = type; property.name = name.toUtf8(); - property.range.offset = node->firstSourceLocation().offset; - property.range.length = node->semicolonToken.end() - property.range.offset; + property.location = location(node->firstSourceLocation(), + node->lastSourceLocation()); if (node->expression) { // default value property.defaultValue = new Property; diff --git a/tests/auto/declarative/qmlparser/finalOverride.errors.txt b/tests/auto/declarative/qmlparser/finalOverride.errors.txt new file mode 100644 index 0000000..fc7070c --- /dev/null +++ b/tests/auto/declarative/qmlparser/finalOverride.errors.txt @@ -0,0 +1 @@ +2:5:Cannot override FINAL property diff --git a/tests/auto/declarative/qmlparser/finalOverride.txt b/tests/auto/declarative/qmlparser/finalOverride.txt new file mode 100644 index 0000000..54ea6fb --- /dev/null +++ b/tests/auto/declarative/qmlparser/finalOverride.txt @@ -0,0 +1,3 @@ +MyQmlObject { + property int value: 10 +} diff --git a/tests/auto/declarative/qmlparser/testtypes.h b/tests/auto/declarative/qmlparser/testtypes.h index ab67a4a..7528331 100644 --- a/tests/auto/declarative/qmlparser/testtypes.h +++ b/tests/auto/declarative/qmlparser/testtypes.h @@ -51,7 +51,7 @@ private: class MyQmlObject : public QObject, public MyInterface, public QmlParserStatus { Q_OBJECT - Q_PROPERTY(int value READ value WRITE setValue) + Q_PROPERTY(int value READ value WRITE setValue FINAL) Q_PROPERTY(QString readOnlyString READ readOnlyString) Q_PROPERTY(bool enabled READ enabled WRITE setEnabled) Q_PROPERTY(QRect rect READ rect WRITE setRect) diff --git a/tests/auto/declarative/qmlparser/tst_qmlparser.cpp b/tests/auto/declarative/qmlparser/tst_qmlparser.cpp index 7023263..f722ca3 100644 --- a/tests/auto/declarative/qmlparser/tst_qmlparser.cpp +++ b/tests/auto/declarative/qmlparser/tst_qmlparser.cpp @@ -137,6 +137,7 @@ void tst_qmlparser::errors_data() QTest::newRow("missingObject") << "missingObject.txt" << "missingObject.errors.txt" << false; QTest::newRow("failingComponent") << "failingComponent.txt" << "failingComponent.errors.txt" << false; QTest::newRow("missingSignal") << "missingSignal.txt" << "missingSignal.errors.txt" << false; + QTest::newRow("finalOverride") << "finalOverride.txt" << "finalOverride.errors.txt" << false; } void tst_qmlparser::errors() -- cgit v0.12