if (isAbsolutePath(dirName)) {
newPath = cleanPath(dirName);
} else {
- if (isRoot()) {
- if (dirName == QLatin1String(".."))
- return false;
+ if (isRoot())
newPath = d->dirEntry.filePath();
- } else {
+ else
newPath = d->dirEntry.filePath() % QLatin1Char('/');
- }
-
newPath += dirName;
if (dirName.indexOf(QLatin1Char('/')) >= 0
|| dirName == QLatin1String("..")
|| d->dirEntry.filePath() == QLatin1String(".")) {
newPath = cleanPath(newPath);
+#if defined (Q_OS_UNIX)
+ //After cleanPath() if path is "/.." or starts with "/../" it means trying to cd above root.
+ if (newPath.startsWith(QLatin1String("/../")) || newPath == QLatin1String("/.."))
+#else
+ /*
+ cleanPath() already took care of replacing '\' with '/'.
+ We can't use startsWith here because the letter of the drive is unknown.
+ After cleanPath() if path is "[A-Z]:/.." or starts with "[A-Z]:/../" it means trying to cd above root.
+ */
+
+ if (newPath.midRef(1, 4) == QLatin1String(":/..") && (newPath.length() == 5 || newPath.at(5) == QLatin1Char('/')))
+#endif
+ return false;
/*
If newPath starts with .., we convert it to absolute to
avoid infinite looping on
void isReadable();
+ void cdBelowRoot();
+
private:
QString m_dataPath;
};
#endif
}
+void tst_QDir::cdBelowRoot()
+{
+#if defined (Q_OS_UNIX)
+#define ROOT QString("/")
+#define DIR QString("/tmp")
+#define CD_INTO "tmp"
+#else
+#define ROOT QString::fromLocal8Bit(qgetenv("SystemDrive"))+"/"
+#define DIR QString::fromLocal8Bit(qgetenv("SystemRoot")).replace('\\', '/')
+#define CD_INTO QString::fromLocal8Bit(qgetenv("SystemRoot")).mid(3)
+#endif
+
+ QDir root(ROOT);
+ QVERIFY(!root.cd(".."));
+ QCOMPARE(root.path(), ROOT);
+ QVERIFY(root.cd(CD_INTO));
+ QCOMPARE(root.path(), DIR);
+
+ QDir dir(DIR);
+ QVERIFY(!dir.cd("../.."));
+ QCOMPARE(dir.path(), DIR);
+ QVERIFY(!dir.cd("../abs/../.."));
+ QCOMPARE(dir.path(), DIR);
+ QVERIFY(dir.cd(".."));
+ QCOMPARE(dir.path(), ROOT);
+}
+
QTEST_MAIN(tst_QDir)
#include "tst_qdir.moc"