From 9d01d183fdddcae7cab11c2c346203c95952ee43 Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Tue, 17 Jan 2023 10:55:24 +0100 Subject: [PATCH] qmllint: Fix null deref in quick plugin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In certain degenerate cases (e.g. missing imports), we might end up with a composite type which does not have a base type. That so far caused a crash in the binding check. To fix this, simply detect the situation, and skip the warning – we will already warn about the unknown type anyway. Fixes: QTBUG-106562 Change-Id: Iff7e202cf5bd6b5c8d7cb90a46fb2573cb74ecaa Reviewed-by: Ulf Hermann (cherry picked from commit 8bf24e93ba9c79080b01ee5dfb89f76430dc6e76) Reviewed-by: Qt Cherry-pick Bot --- src/plugins/qmllint/quick/quicklintplugin.cpp | 15 +++++++++++++-- .../data/pluginQuick_noCrashOnUneresolved.qml | 10 ++++++++++ tests/auto/qml/qmllint/tst_qmllint.cpp | 1 + 3 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 tests/auto/qml/qmllint/data/pluginQuick_noCrashOnUneresolved.qml diff --git a/src/plugins/qmllint/quick/quicklintplugin.cpp b/src/plugins/qmllint/quick/quicklintplugin.cpp index 2f06d98f20..3b89635748 100644 --- a/src/plugins/qmllint/quick/quicklintplugin.cpp +++ b/src/plugins/qmllint/quick/quicklintplugin.cpp @@ -482,9 +482,20 @@ void VarBindingTypeValidatorPass::onBinding(const QQmlSA::Element &element, [&](const QQmlSA::Element &scope) { return bindingType->inherits(scope); }) == range.second) { + const bool bindingTypeIsComposite = bindingType->isComposite(); + if (bindingTypeIsComposite && !bindingType->baseType()) { + /* broken module or missing import, there is nothing we + can really check here, as something is amiss. We + simply skip this binding, and assume that whatever + caused the breakage here will already cause another + warning somewhere else. + */ + return; + } const QString bindingTypeName = QQmlJSScope::prettyName( - bindingType->isComposite() ? bindingType->baseType()->internalName() - : bindingType->internalName()); + bindingTypeIsComposite + ? bindingType->baseType()->internalName() + : bindingType->internalName()); QStringList expectedTypeNames; for (auto it = range.first; it != range.second; it++) diff --git a/tests/auto/qml/qmllint/data/pluginQuick_noCrashOnUneresolved.qml b/tests/auto/qml/qmllint/data/pluginQuick_noCrashOnUneresolved.qml new file mode 100644 index 0000000000..7e04394350 --- /dev/null +++ b/tests/auto/qml/qmllint/data/pluginQuick_noCrashOnUneresolved.qml @@ -0,0 +1,10 @@ +import QtQuick.Controls + +Item { + + Tumbler { + + contentItem: Item { + } + } +} diff --git a/tests/auto/qml/qmllint/tst_qmllint.cpp b/tests/auto/qml/qmllint/tst_qmllint.cpp index 57af0f7aac..e3d91b1346 100644 --- a/tests/auto/qml/qmllint/tst_qmllint.cpp +++ b/tests/auto/qml/qmllint/tst_qmllint.cpp @@ -1897,6 +1897,7 @@ void TestQmllint::quickPlugin() runTest("pluginQuick_varPropClean.qml", Result::clean()); runTest("pluginQuick_attachedClean.qml", Result::clean()); runTest("pluginQuick_attachedIgnore.qml", Result::clean()); + runTest("pluginQuick_noCrashOnUneresolved.qml", Result {}); // we don't care about the specific warnings } #endif