diff options
author | Joerg Bornemann <joerg.bornemann@digia.com> | 2012-10-22 16:26:16 +0200 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@digia.com> | 2012-10-23 12:30:35 +0200 |
commit | 1d067c0957c56b5926931132cf43853e57a7361e (patch) | |
tree | fc09bdd043092785bdd9e4470134808ebc07a336 | |
parent | d88d876315dc325d99a92d4cce4dc99cf0d76101 (diff) |
fix handling of source file paths that contain "../"
Task-number: QBS-139
Change-Id: I8c0e9f0574859c26abe7ead2e64aa0ecd4bfa3ec
Reviewed-by: Christian Kandeler <christian.kandeler@digia.com>
-rw-r--r-- | src/lib/language/loader.cpp | 2 | ||||
-rw-r--r-- | src/lib/tools/fileinfo.cpp | 24 | ||||
-rw-r--r-- | tests/auto/language/tst_language.cpp | 10 | ||||
-rw-r--r-- | tests/auto/tools/tst_tools.cpp | 3 |
4 files changed, 31 insertions, 8 deletions
diff --git a/src/lib/language/loader.cpp b/src/lib/language/loader.cpp index 2efbdec9b..74f9e1e1a 100644 --- a/src/lib/language/loader.cpp +++ b/src/lib/language/loader.cpp @@ -1788,6 +1788,7 @@ static bool checkCondition(EvaluationObject *object) ResolvedProject::Ptr Loader::resolveProject(ProjectFile::Ptr projectFile, const QString &buildDirectoryRoot, const QVariantMap &userProperties, bool resolveProductDependencies) { + Q_ASSERT(FileInfo::isAbsolute(buildDirectoryRoot)); if (qbsLogLevel(LoggerTrace)) qbsTrace() << "[LDR] resolving " << m_project->fileName; m_project = projectFile; @@ -2082,6 +2083,7 @@ void Loader::resolveModule(ResolvedProduct::Ptr rproduct, const QString &moduleN Group::Ptr group = rproduct->groups.first(); artifact = SourceArtifact::create(); artifact->configuration = group->configuration; + fileName = QDir::cleanPath(fileName); artifact->absoluteFilePath = FileInfo::resolvePath(rproduct->sourceDirectory, fileName); group->files += artifact; } diff --git a/src/lib/tools/fileinfo.cpp b/src/lib/tools/fileinfo.cpp index 0c16fec9c..1abec14d6 100644 --- a/src/lib/tools/fileinfo.cpp +++ b/src/lib/tools/fileinfo.cpp @@ -148,18 +148,36 @@ bool FileInfo::isPattern(const QStringRef &str) return false; } +/** + * Concatenates the paths \a base and \a rel. + * Base must be an absolute path. + * Double dots at the start of \a rel are handled. + * This function assumes that both paths are clean, that is they don't contain + * double slashes or redundant dot parts. + */ QString FileInfo::resolvePath(const QString &base, const QString &rel) { + Q_ASSERT(isAbsolute(base)); if (isAbsolute(rel)) return rel; if (rel.size() == 1 && rel.at(0) == QLatin1Char('.')) return base; QString r = base; - if (!r.endsWith(QLatin1Char('/'))) - r.append(QLatin1Char('/')); - r.append(rel); + if (r.endsWith(QLatin1Char('/'))) + r.chop(1); + + QString s = rel; + while (s.startsWith(QLatin1String("../"))) { + s.remove(0, 3); + int idx = r.lastIndexOf(QLatin1Char('/')); + if (idx >= 0) + r.truncate(idx); + } + r.reserve(r.length() + 1 + s.length()); + r += QLatin1Char('/'); + r += s; return r; } diff --git a/tests/auto/language/tst_language.cpp b/tests/auto/language/tst_language.cpp index c1c7e5add..5d545e466 100644 --- a/tests/auto/language/tst_language.cpp +++ b/tests/auto/language/tst_language.cpp @@ -78,7 +78,7 @@ void TestLanguage::conditionalDepends() ResolvedModule::ConstPtr dependency; try { ProjectFile::Ptr projectFile = loader->loadProject(SRCDIR "testdata/conditionaldepends.qbs"); - ResolvedProject::Ptr project = loader->resolveProject(projectFile, "someBuildDirectory", + ResolvedProject::Ptr project = loader->resolveProject(projectFile, "/some/build/directory", buildConfig); QVERIFY(project); QHash<QString, ResolvedProduct::Ptr> products = productsFromProject(project); @@ -148,7 +148,7 @@ void TestLanguage::groupName() bool exceptionCaught = false; try { ProjectFile::Ptr projectFile = loader->loadProject(SRCDIR "testdata/groupname.qbs"); - ResolvedProject::Ptr project = loader->resolveProject(projectFile, "someBuildDirectory", + ResolvedProject::Ptr project = loader->resolveProject(projectFile, "/some/build/directory", buildConfig); QVERIFY(project); QHash<QString, ResolvedProduct::Ptr> products = productsFromProject(project); @@ -189,7 +189,7 @@ void TestLanguage::productConditions() bool exceptionCaught = false; try { ProjectFile::Ptr projectFile = loader->loadProject(SRCDIR "testdata/productconditions.qbs"); - ResolvedProject::Ptr project = loader->resolveProject(projectFile, "someBuildDirectory", + ResolvedProject::Ptr project = loader->resolveProject(projectFile, "/some/build/directory", buildConfig); QVERIFY(project); QHash<QString, ResolvedProduct::Ptr> products = productsFromProject(project); @@ -230,7 +230,7 @@ void TestLanguage::propertiesBlocks() bool exceptionCaught = false; try { ProjectFile::Ptr projectFile = loader->loadProject(SRCDIR "testdata/propertiesblocks.qbs"); - project = loader->resolveProject(projectFile, "someBuildDirectory", buildConfig); + project = loader->resolveProject(projectFile, "/some/build/directory", buildConfig); QVERIFY(project); } catch (const Error &e) { exceptionCaught = true; @@ -277,7 +277,7 @@ void TestLanguage::fileTags() bool exceptionCaught = false; try { ProjectFile::Ptr projectFile = loader->loadProject(SRCDIR "testdata/filetags.qbs"); - project = loader->resolveProject(projectFile, "someBuildDirectory", buildConfig); + project = loader->resolveProject(projectFile, "/some/build/directory", buildConfig); QVERIFY(project); } catch (const Error &e) { diff --git a/tests/auto/tools/tst_tools.cpp b/tests/auto/tools/tst_tools.cpp index e4758ad34..827ae5a9e 100644 --- a/tests/auto/tools/tst_tools.cpp +++ b/tests/auto/tools/tst_tools.cpp @@ -88,6 +88,9 @@ private slots: QVERIFY(qbs::FileInfo::isAbsolute("C:\\bla\\lol")); #endif QCOMPARE(qbs::FileInfo::resolvePath("/abc/lol", "waffl"), QString("/abc/lol/waffl")); + QCOMPARE(qbs::FileInfo::resolvePath("/abc/def/ghi/jkl/", "../foo/bar"), QString("/abc/def/ghi/foo/bar")); + QCOMPARE(qbs::FileInfo::resolvePath("/abc/def/ghi/jkl/", "../../foo/bar"), QString("/abc/def/foo/bar")); + QCOMPARE(qbs::FileInfo::resolvePath("/abc", "../../../foo/bar"), QString("/foo/bar")); } void testProjectFileLookup() |