From eec58534ab9c3fae74a1b4cb0861d4b40253cd2d Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Wed, 10 Jan 2018 13:51:23 +0100 Subject: Fix segfault when alias target refers to lowercase-named type Create an error via QQmlCompileError and return it instead of asserting. Task-number: QTBUG-43567 Change-Id: I0c0741943d30516379eff5f44ed8618a0f0116a4 Reviewed-by: Simon Hausmann --- src/qml/compiler/qqmlpropertycachecreator_p.h | 27 ++++++++++++++++++--------- src/qml/compiler/qqmltypecompiler.cpp | 6 +++++- 2 files changed, 23 insertions(+), 10 deletions(-) (limited to 'src/qml') diff --git a/src/qml/compiler/qqmlpropertycachecreator_p.h b/src/qml/compiler/qqmlpropertycachecreator_p.h index 22e83de9ae..8743a57d7a 100644 --- a/src/qml/compiler/qqmlpropertycachecreator_p.h +++ b/src/qml/compiler/qqmlpropertycachecreator_p.h @@ -536,11 +536,11 @@ public: void appendAliasPropertiesToMetaObjects(); - void appendAliasesToPropertyCache(const CompiledObject &component, int objectIndex); + QQmlCompileError appendAliasesToPropertyCache(const CompiledObject &component, int objectIndex); private: void appendAliasPropertiesInMetaObjectsWithinComponent(const CompiledObject &component, int firstObjectIndex); - void propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, QQmlPropertyRawData::Flags *propertyFlags); + QQmlCompileError propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, QQmlPropertyRawData::Flags *propertyFlags); void collectObjectsWithAliasesRecursively(int objectIndex, QVector *objectsWithAliases) const; @@ -651,7 +651,7 @@ inline void QQmlPropertyCacheAliasCreator::collectObjectsWithAl } template -inline void QQmlPropertyCacheAliasCreator::propertyDataForAlias( +inline QQmlCompileError QQmlPropertyCacheAliasCreator::propertyDataForAlias( const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, QQmlPropertyData::Flags *propertyFlags) { @@ -670,12 +670,16 @@ inline void QQmlPropertyCacheAliasCreator::propertyDataForAlias auto targetAlias = targetObject.aliasesBegin(); for (uint i = 0; i < alias.localAliasIndex; ++i) ++targetAlias; - propertyDataForAlias(component, *targetAlias, type, propertyFlags); - return; + return propertyDataForAlias(component, *targetAlias, type, propertyFlags); } else if (alias.encodedMetaPropertyIndex == -1) { Q_ASSERT(alias.flags & QV4::CompiledData::Alias::AliasPointsToPointerObject); auto *typeRef = objectContainer->resolvedTypes.value(targetObject.inheritedTypeNameIndex); - Q_ASSERT(typeRef); + if (!typeRef) { + // Can be caused by the alias target not being a valid id or property. E.g.: + // property alias dataValue: dataVal + // invalidAliasComponent { id: dataVal } + return QQmlCompileError(targetObject.location, QQmlPropertyCacheCreatorBase::tr("Invalid alias target")); + } if (typeRef->type.isValid()) *type = typeRef->type.typeId(); @@ -718,15 +722,16 @@ inline void QQmlPropertyCacheAliasCreator::propertyDataForAlias propertyFlags->isWritable = !(alias.flags & QV4::CompiledData::Property::IsReadOnly) && writable; propertyFlags->isResettable = resettable; + return QQmlCompileError(); } template -inline void QQmlPropertyCacheAliasCreator::appendAliasesToPropertyCache( +inline QQmlCompileError QQmlPropertyCacheAliasCreator::appendAliasesToPropertyCache( const CompiledObject &component, int objectIndex) { const CompiledObject &object = *objectContainer->objectAt(objectIndex); if (!object.aliasCount()) - return; + return QQmlCompileError(); QQmlPropertyCache *propertyCache = propertyCaches->at(objectIndex); Q_ASSERT(propertyCache); @@ -742,7 +747,9 @@ inline void QQmlPropertyCacheAliasCreator::appendAliasesToPrope int type = 0; QQmlPropertyData::Flags propertyFlags; - propertyDataForAlias(component, *alias, &type, &propertyFlags); + QQmlCompileError error = propertyDataForAlias(component, *alias, &type, &propertyFlags); + if (error.isSet()) + return error; const QString propertyName = objectContainer->stringAt(alias->nameIndex); @@ -752,6 +759,8 @@ inline void QQmlPropertyCacheAliasCreator::appendAliasesToPrope propertyCache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++, type, effectiveSignalIndex++); } + + return QQmlCompileError(); } template diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp index d152d26968..0eae909cf7 100644 --- a/src/qml/compiler/qqmltypecompiler.cpp +++ b/src/qml/compiler/qqmltypecompiler.cpp @@ -1010,7 +1010,11 @@ bool QQmlComponentAndAliasResolver::resolveAliases(int componentIndex) } if (result == AllAliasesResolved) { - aliasCacheCreator.appendAliasesToPropertyCache(*qmlObjects->at(componentIndex), objectIndex); + QQmlCompileError error = aliasCacheCreator.appendAliasesToPropertyCache(*qmlObjects->at(componentIndex), objectIndex); + if (error.isSet()) { + recordError(error); + return false; + } atLeastOneAliasResolved = true; } else if (result == SomeAliasesResolved) { atLeastOneAliasResolved = true; -- cgit v1.2.3