diff options
| author | Jeff Heller <jeffrey_heller@yahoo.com> | 2026-10-01 13:48:01 -0600 |
|---|---|---|
| committer | Jeff Heller <jeffrey_heller@yahoo.com> | 2026-10-02 15:36:15 +0000 |
| commit | 861a8762665baffc6b739704194d5a47e4110c71 (patch) | |
| tree | 78b7135386c64e39eb98420eab41e44f82036314 | |
| parent | bac9da45c9ec7927bde3b0a2b4dc7ed1fc3f032e (diff) | |
QQmlJSUtils: Accept a relative path in qmlSourcePathFromBuildPath()
qmlSourcePathFromBuildPath() found the module through a clean absolute
form of the path, then cut the module's absolute directory off the path
as passed in. qmllint passes the linted file's path as given on its
command line, so linting a build-folder copy by a relative path with
--resource read past the end of the string and crashed, for example:
cd build && qmllint --resource .qt/rcc/qmake_Mod.qrc \
--resource .qt/rcc/Mod_raw_qml_0.qrc Mod/Main.qml
Cut the module directory off the clean absolute path instead.
Pick-to: 6.12
Assisted-by: Claude Code
Change-Id: I92c078e7c45274b1eeb61c648d64514430cee817
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
| -rw-r--r-- | src/qmlcompiler/qqmljsutils.cpp | 7 | ||||
| -rw-r--r-- | tests/auto/qml/qqmljsutils/tst_qqmljsutils.cpp | 13 |
2 files changed, 17 insertions, 3 deletions
diff --git a/src/qmlcompiler/qqmljsutils.cpp b/src/qmlcompiler/qqmljsutils.cpp index 7fc31e9524..baa5d7cea0 100644 --- a/src/qmlcompiler/qqmljsutils.cpp +++ b/src/qmlcompiler/qqmljsutils.cpp @@ -322,12 +322,13 @@ QString qmlSourcePathFromBuildPath(const QQmlJSResourceFileMapper *mapper, if (!mapper) return pathInBuildFolder; - const auto qmlModuleEntry = - qmlModuleEntryFromBuildPath(mapper, pathInBuildFolder, LocalFileFilter); + // Slice the path the mapper matched against: its entries are absolute and clean. + const QString buildPath = QDir::cleanPath(QFileInfo(pathInBuildFolder).absoluteFilePath()); + const auto qmlModuleEntry = qmlModuleEntryFromBuildPath(mapper, buildPath, LocalFileFilter); if (!qmlModuleEntry.isValid()) return pathInBuildFolder; const QString qrcPath = qmlModuleEntry.resourcePath - + QStringView(pathInBuildFolder).sliced(qmlModuleEntry.filePath.size()); + + QStringView(buildPath).sliced(qmlModuleEntry.filePath.size()); const auto entry = mapper->entry(QQmlJSResourceFileMapper::resourceFileFilter(qrcPath)); return entry.isValid()? entry.filePath : pathInBuildFolder; diff --git a/tests/auto/qml/qqmljsutils/tst_qqmljsutils.cpp b/tests/auto/qml/qqmljsutils/tst_qqmljsutils.cpp index c258f52a53..6e391f451d 100644 --- a/tests/auto/qml/qqmljsutils/tst_qqmljsutils.cpp +++ b/tests/auto/qml/qqmljsutils/tst_qqmljsutils.cpp @@ -4,6 +4,9 @@ #include "tst_qqmljsutils.h" #include <QtQmlCompiler/private/qqmljsutils_p.h> +#include <QtCore/qdir.h> +#include <QtCore/qscopeguard.h> + using namespace Qt::StringLiterals; void tst_qqmljsutils::findResourceFilesFromBuildFolders() @@ -55,6 +58,16 @@ void tst_qqmljsutils::qmlFileSourcePathFromBuildPath() QCOMPARE(QQmlJSUtils::qmlSourcePathFromBuildPath(&mapper, buildFile), expectedSourceFile); QCOMPARE(QQmlJSUtils::qmlBuildPathFromSourcePath(&mapper, expectedSourceFile), buildFile); + + // qmllint passes the file's path as given on its command line. Relative to the build folder, + // so that it is relative on any drive. + const QString currentPath = QDir::currentPath(); + const auto restore = qScopeGuard([&]() { QDir::setCurrent(currentPath); }); + QVERIFY(QDir::setCurrent(buildFolder)); + const QString relativeBuildFile = QDir(buildFolder).relativeFilePath(buildFile); + QVERIFY(QDir::isRelativePath(relativeBuildFile)); + QCOMPARE(QQmlJSUtils::qmlSourcePathFromBuildPath(&mapper, relativeBuildFile), + expectedSourceFile); } void tst_qqmljsutils::qmlBuildPathFromSourcePathWithMultipleRegistrations() |
