diff options
author | Ritt Konstantin <ritt.ks@gmail.com> | 2010-04-27 02:12:47 (GMT) |
---|---|---|
committer | Qt Commercial Integration <QtCommercial@digia.com> | 2012-01-31 10:24:53 (GMT) |
commit | 313c0c388524891c3887a29344135c452c4c301a (patch) | |
tree | 408da3acd7ee8043eacc36dddae19191b9edda0f | |
parent | d56db447348d7b641097bf146d188751ba8a76ae (diff) | |
download | Qt-313c0c388524891c3887a29344135c452c4c301a.zip Qt-313c0c388524891c3887a29344135c452c4c301a.tar.gz Qt-313c0c388524891c3887a29344135c452c4c301a.tar.bz2 |
avoid infinite recursion in canonicalized() if cwd is a symlink
if current directory is a symlink to another directory
on the same drive (the simplest example; say, c:\current\dir
is a symlink to c:\target) then the first valid prefix for
"c:\target" in canonicalized() is "c:" (NOT "c:\") and would
be treated like "c:\current\dir" again...and again...
until stack overflow :)
Merge-Request: 494
Task-number: QTBUG-7610
Reviewed-by: Zeno Albisser
-rw-r--r-- | src/corelib/io/qfsfileengine.cpp | 12 | ||||
-rw-r--r-- | tests/auto/qfileinfo/tst_qfileinfo.cpp | 20 |
2 files changed, 29 insertions, 3 deletions
diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index 8689c57..d15b4a7 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -189,9 +189,15 @@ QString QFSFileEnginePrivate::canonicalized(const QString &path) known.insert(path); do { #ifdef Q_OS_WIN - // UNC, skip past the first two elements - if (separatorPos == 0 && tmpPath.startsWith(QLatin1String("//"))) - separatorPos = tmpPath.indexOf(slash, 2); + if (separatorPos == 0) { + if (tmpPath.size() >= 2 && tmpPath.at(0) == slash && tmpPath.at(1) == slash) { + // UNC, skip past the first two elements + separatorPos = tmpPath.indexOf(slash, 2); + } else if (tmpPath.size() >= 3 && tmpPath.at(1) == QLatin1Char(':') && tmpPath.at(2) == slash) { + // volume root, skip since it can not be a symlink + separatorPos = 2; + } + } if (separatorPos != -1) #endif separatorPos = tmpPath.indexOf(slash, separatorPos + 1); diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index 6291f1c..af28848 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -46,6 +46,7 @@ #include <qfile.h> #include <qdir.h> #include <qcoreapplication.h> +#include <qlibrary.h> #include <qtemporaryfile.h> #include <qdir.h> #include <qfileinfo.h> @@ -584,6 +585,25 @@ void tst_QFileInfo::canonicalFilePath() } # endif #endif + +#ifdef Q_OS_WIN + typedef BOOL (WINAPI *PtrCreateSymbolicLink)(LPTSTR, LPTSTR, DWORD); + PtrCreateSymbolicLink ptrCreateSymbolicLink = + (PtrCreateSymbolicLink)QLibrary::resolve(QLatin1String("kernel32"), "CreateSymbolicLink"); + + if (!ptrCreateSymbolicLink || + ptrCreateSymbolicLink((wchar_t*)QString("res").utf16(), (wchar_t*)QString("resources").utf16(), 1) == 0) { + QSKIP("Symbolic links aren't supported by FS", SkipAll); + } + + QString currentPath = QDir::currentPath(); + QCOMPARE(QDir::setCurrent("res"), true); + + QCOMPARE(QFileInfo("file1").canonicalFilePath(), currentPath + "/resources/file1"); + + QCOMPARE(QDir::setCurrent(currentPath), true); + QFile::remove("res"); +#endif } void tst_QFileInfo::fileName_data() |