aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoerg Bornemann <joerg.bornemann@digia.com>2012-10-22 16:26:16 +0200
committerChristian Kandeler <christian.kandeler@digia.com>2012-10-23 12:30:35 +0200
commit1d067c0957c56b5926931132cf43853e57a7361e (patch)
treefc09bdd043092785bdd9e4470134808ebc07a336
parentd88d876315dc325d99a92d4cce4dc99cf0d76101 (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.cpp2
-rw-r--r--src/lib/tools/fileinfo.cpp24
-rw-r--r--tests/auto/language/tst_language.cpp10
-rw-r--r--tests/auto/tools/tst_tools.cpp3
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()