Don't allow cd'ing to above root.

Task-number: QTBUG-23893
Change-Id: Ifc6e22f135a1f6bff7c0fa8bef3ea7e1042ae819
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@nokia.com>
Reviewed-by: David Faure <david.faure@kdab.com>
bb10
Jonas Gastal 2012-01-29 22:57:56 -02:00 committed by Qt by Nokia
parent 763d0a55e9
commit 63f634322b
2 changed files with 44 additions and 6 deletions

View File

@ -861,19 +861,28 @@ bool QDir::cd(const QString &dirName)
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

View File

@ -190,6 +190,8 @@ private slots:
void isReadable();
void cdBelowRoot();
private:
QString m_dataPath;
};
@ -1942,6 +1944,33 @@ void tst_QDir::isReadable()
#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"