summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShane Kearns <shane.kearns@accenture.com>2011-09-01 15:04:33 +0100
committerQt by Nokia <qt-info@nokia.com>2011-09-02 10:01:20 +0200
commite8192883b2d00b7a1b68fb7c7154a1e75bab0b26 (patch)
treeb0530f494702b7109787d59700f3fc4ccc2407cf
parent254d7189d8ac3681ae52487513487f8a2cb7d0dc (diff)
Fix comparison of absolute, unclean paths in QDir
QDir::operator== was creating a clean absolute path for comparison purposes if the original path was relative. However original absolute paths were trusted, even though they could be unclean. Now they are checked for cleanliness first. Task-Number: QTBUG-19995 Task-Number: QTBUG-20495 Change-Id: I047a1a40ae5151e4604085e4ac87f30a4e4979c4 Reviewed-on: http://codereview.qt.nokia.com/4099 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Prasanth Ullattil <prasanth.ullattil@nokia.com>
-rw-r--r--src/corelib/io/qdir.cpp2
-rw-r--r--src/corelib/io/qfilesystementry.cpp31
-rw-r--r--src/corelib/io/qfilesystementry_p.h1
-rw-r--r--tests/auto/qdir/tst_qdir.cpp13
-rw-r--r--tests/auto/qfilesystementry/tst_qfilesystementry.cpp32
5 files changed, 78 insertions, 1 deletions
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index 49d8a7b4f7..d1c9be213b 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -190,7 +190,7 @@ inline void QDirPrivate::resolveAbsoluteEntry() const
QString absoluteName;
if (fileEngine.isNull()) {
- if (!dirEntry.isRelative()) {
+ if (!dirEntry.isRelative() && dirEntry.isClean()) {
absoluteDirEntry = dirEntry;
return;
}
diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp
index bb7cb4e6ab..2f37542f66 100644
--- a/src/corelib/io/qfilesystementry.cpp
+++ b/src/corelib/io/qfilesystementry.cpp
@@ -380,4 +380,35 @@ void QFileSystemEntry::findFileNameSeparators() const
}
}
+bool QFileSystemEntry::isClean() const
+{
+ resolveFilePath();
+ int dots = 0;
+ bool dotok = true; // checking for ".." or "." starts to relative paths
+ bool slashok = true;
+ for (QString::const_iterator iter = m_filePath.constBegin(); iter != m_filePath.constEnd(); iter++) {
+ if (*iter == QLatin1Char('/')) {
+ if (dots == 1 || dots == 2)
+ return false; // path contains "./" or "../"
+ if (!slashok)
+ return false; // path contains "//"
+ dots = 0;
+ dotok = true;
+ slashok = false;
+ } else if (dotok) {
+ slashok = true;
+ if (*iter == QLatin1Char('.')) {
+ dots++;
+ if (dots > 2)
+ dotok = false;
+ } else {
+ //path element contains a character other than '.', it's clean
+ dots = 0;
+ dotok = false;
+ }
+ }
+ }
+ return (dots != 1 && dots != 2); // clean if path doesn't end in . or ..
+}
+
QT_END_NAMESPACE
diff --git a/src/corelib/io/qfilesystementry_p.h b/src/corelib/io/qfilesystementry_p.h
index 34b083a03e..8d524c087e 100644
--- a/src/corelib/io/qfilesystementry_p.h
+++ b/src/corelib/io/qfilesystementry_p.h
@@ -91,6 +91,7 @@ public:
QString completeSuffix() const;
bool isAbsolute() const;
bool isRelative() const;
+ bool isClean() const;
#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
bool isDriveRoot() const;
diff --git a/tests/auto/qdir/tst_qdir.cpp b/tests/auto/qdir/tst_qdir.cpp
index 8436014c05..fd1ecd5793 100644
--- a/tests/auto/qdir/tst_qdir.cpp
+++ b/tests/auto/qdir/tst_qdir.cpp
@@ -1109,6 +1109,11 @@ void tst_QDir::absolutePath_data()
QTest::newRow("4") << "c:/machine/share/dir1" << "c:/machine/share/dir1";
QTest::newRow("5") << "c:\\machine\\share\\dir1" << "c:/machine/share/dir1";
#endif
+ //test dirty paths are cleaned (QTBUG-19995)
+ QTest::newRow("/home/qt/.") << QDir::rootPath() + "home/qt/." << QDir::rootPath() + "home/qt";
+ QTest::newRow("/system/data/../config") << QDir::rootPath() + "system/data/../config" << QDir::rootPath() + "system/config";
+ QTest::newRow("//home//qt/") << QDir::rootPath() + "/home//qt/" << QDir::rootPath() + "home/qt";
+ QTest::newRow("foo/../bar") << "foo/../bar" << QDir::currentPath() + "/bar";
QTest::newRow("resource") << ":/prefix/foo.bar" << ":/prefix/foo.bar";
}
@@ -1872,6 +1877,14 @@ void tst_QDir::equalityOperator_data()
<< "./entrylist" << "*.cpp" << int(QDir::Name) << int(QDir::Files)
<< true;
+ QTest::newRow("QTBUG-20495") << QDir::currentPath() + "/entrylist/.." << "*.cpp" << int(QDir::Name) << int(QDir::Files)
+ << "." << "*.cpp" << int(QDir::Name) << int(QDir::Files)
+ << true;
+
+ QTest::newRow("QTBUG-20495-root") << QDir::rootPath() + "tmp/.." << "*.cpp" << int(QDir::Name) << int(QDir::Files)
+ << QDir::rootPath() << "*.cpp" << int(QDir::Name) << int(QDir::Files)
+ << true;
+
QTest::newRow("diff-filters") << SRCDIR << "*.cpp" << int(QDir::Name) << int(QDir::Files)
<< SRCDIR << "*.cpp" << int(QDir::Name) << int(QDir::Dirs)
<< false;
diff --git a/tests/auto/qfilesystementry/tst_qfilesystementry.cpp b/tests/auto/qfilesystementry/tst_qfilesystementry.cpp
index 016bcbfe8a..2daabee48f 100644
--- a/tests/auto/qfilesystementry/tst_qfilesystementry.cpp
+++ b/tests/auto/qfilesystementry/tst_qfilesystementry.cpp
@@ -68,6 +68,8 @@ private slots:
void absoluteOrRelative_data();
void absoluteOrRelative();
#endif
+ void isClean_data();
+ void isClean();
};
#if defined(WIN_STUFF)
@@ -383,5 +385,35 @@ void tst_QFileSystemEntry::absoluteOrRelative()
}
#endif
+void tst_QFileSystemEntry::isClean_data()
+{
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<bool>("isClean");
+
+ QTest::newRow("simple") << "foo" << true;
+ QTest::newRow("complex") << "/foo/bar/bz" << true;
+ QTest::newRow(".file") << "/foo/.file" << true;
+ QTest::newRow("..file") << "/foo/..file" << true;
+ QTest::newRow("...") << "/foo/.../bar" << true;
+ QTest::newRow("./") << "./" << false;
+ QTest::newRow("../") << "../" << false;
+ QTest::newRow(".") << "." << false;
+ QTest::newRow("..") << ".." << false;
+ QTest::newRow("/.") << "/." << false;
+ QTest::newRow("/..") << "/.." << false;
+ QTest::newRow("/../") << "foo/../bar" << false;
+ QTest::newRow("/./") << "foo/./bar" << false;
+ QTest::newRow("//") << "foo//bar" << false;
+}
+
+void tst_QFileSystemEntry::isClean()
+{
+ QFETCH(QString, path);
+ QFETCH(bool, isClean);
+
+ QFileSystemEntry fi(path);
+ QCOMPARE(fi.isClean(), isClean);
+}
+
QTEST_MAIN(tst_QFileSystemEntry)
#include <tst_qfilesystementry.moc>