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>bb10
parent
254d7189d8
commit
e8192883b2
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Reference in New Issue