From 55ab987c9a518f217c02ca1382656ac97c53b307 Mon Sep 17 00:00:00 2001 From: Karsten Heimrich Date: Tue, 28 Sep 2021 13:56:16 +0200 Subject: [PATCH] Fix QDir::entryList to work for directories that end with '.lnk' In addition to checking the .lnk extension, check that the the specified path is not a path to a directory. Pick-to: 6.2 Fixes: QTBUG-85058 Change-Id: I83cef3d94c6ffa82a88f374c5b41779e88fe40b8 Reviewed-by: Friedemann Kleint Reviewed-by: Edward Welbourne Reviewed-by: Kai Koehne Reviewed-by: Qt CI Bot --- src/corelib/io/qfilesystemengine_p.h | 1 + src/corelib/io/qfilesystemengine_win.cpp | 7 +++---- src/corelib/io/qfilesystemiterator_win.cpp | 2 +- tests/auto/corelib/io/qdir/testdir/dir.lnk/aaaaa.txt | 0 .../io/qdir/testdir/dir.lnk/subdir.lnk/subdir.lnk.txt | 0 .../corelib/io/qdir/testdir/dir.lnk/subdir/subdir.txt | 0 tests/auto/corelib/io/qdir/tst_qdir.cpp | 9 ++++++--- 7 files changed, 11 insertions(+), 8 deletions(-) create mode 100644 tests/auto/corelib/io/qdir/testdir/dir.lnk/aaaaa.txt create mode 100644 tests/auto/corelib/io/qdir/testdir/dir.lnk/subdir.lnk/subdir.lnk.txt create mode 100644 tests/auto/corelib/io/qdir/testdir/dir.lnk/subdir/subdir.txt diff --git a/src/corelib/io/qfilesystemengine_p.h b/src/corelib/io/qfilesystemengine_p.h index b5daa3b88e..0b6f0fbd84 100644 --- a/src/corelib/io/qfilesystemengine_p.h +++ b/src/corelib/io/qfilesystemengine_p.h @@ -144,6 +144,7 @@ public: QAbstractFileEngine::FileTime whatTime, QSystemError &error); static QString owner(const QFileSystemEntry &entry, QAbstractFileEngine::FileOwner own); static QString nativeAbsoluteFilePath(const QString &path); + static bool isDirPath(const QString &path, bool *existed); #endif //homePath, rootPath and tempPath shall return clean paths static QString homePath(); diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 0d3dd2e0b2..33a123d6fd 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -1022,8 +1022,6 @@ bool QFileSystemEngine::fillMetaData(HANDLE fHandle, QFileSystemMetaData &data, return data.hasFlags(what); } -static bool isDirPath(const QString &dirPath, bool *existed); - //static bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::MetaDataFlags what) @@ -1103,7 +1101,8 @@ static inline bool rmDir(const QString &path) return ::RemoveDirectory((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16()); } -static bool isDirPath(const QString &dirPath, bool *existed) +//static +bool QFileSystemEngine::isDirPath(const QString &dirPath, bool *existed) { QString path = dirPath; if (path.length() == 2 && path.at(1) == QLatin1Char(':')) @@ -1141,7 +1140,7 @@ static bool createDirectoryWithParents(const QString &nativeName, bool shouldMkd }; const auto isDir = [](const QString &nativeName) { bool exists = false; - return isDirPath(nativeName, &exists) && exists; + return QFileSystemEngine::isDirPath(nativeName, &exists) && exists; }; // Do not try to mkdir a UNC root path or a drive letter. if (isUNCRoot(nativeName) || isDriveName(nativeName)) diff --git a/src/corelib/io/qfilesystemiterator_win.cpp b/src/corelib/io/qfilesystemiterator_win.cpp index 1b65ae3c09..ac52dacdce 100644 --- a/src/corelib/io/qfilesystemiterator_win.cpp +++ b/src/corelib/io/qfilesystemiterator_win.cpp @@ -59,7 +59,7 @@ QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Fi { Q_UNUSED(nameFilters); Q_UNUSED(flags); - if (nativePath.endsWith(QLatin1String(".lnk"))) { + if (nativePath.endsWith(u".lnk"_qs) && !QFileSystemEngine::isDirPath(dirPath, nullptr)) { QFileSystemMetaData metaData; QFileSystemEntry link = QFileSystemEngine::getLinkTarget(entry, metaData); nativePath = link.nativeFilePath(); diff --git a/tests/auto/corelib/io/qdir/testdir/dir.lnk/aaaaa.txt b/tests/auto/corelib/io/qdir/testdir/dir.lnk/aaaaa.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/auto/corelib/io/qdir/testdir/dir.lnk/subdir.lnk/subdir.lnk.txt b/tests/auto/corelib/io/qdir/testdir/dir.lnk/subdir.lnk/subdir.lnk.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/auto/corelib/io/qdir/testdir/dir.lnk/subdir/subdir.txt b/tests/auto/corelib/io/qdir/testdir/dir.lnk/subdir/subdir.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/auto/corelib/io/qdir/tst_qdir.cpp b/tests/auto/corelib/io/qdir/tst_qdir.cpp index 0e6f629b06..3675e45f83 100644 --- a/tests/auto/corelib/io/qdir/tst_qdir.cpp +++ b/tests/auto/corelib/io/qdir/tst_qdir.cpp @@ -722,13 +722,16 @@ void tst_QDir::entryList_data() << QString("qdir.pro,qrc_qdir.cpp,tst_qdir.cpp").split(','); QTest::newRow("testdir1") << (m_dataPath + "/testdir") << QStringList() << (int)(QDir::AllDirs) << (int)(QDir::NoSort) - << QString(".,..,dir,spaces").split(','); + << QString(".,..,dir,dir.lnk,spaces").split(','); QTest::newRow("resources1") << QString(":/tst_qdir/resources/entryList") << QStringList("*.data") << (int)(QDir::NoFilter) << (int)(QDir::NoSort) << QString("file1.data,file2.data,file3.data").split(','); QTest::newRow("resources2") << QString(":/tst_qdir/resources/entryList") << QStringList("*.data") << (int)(QDir::Files) << (int)(QDir::NoSort) << QString("file1.data,file2.data,file3.data").split(','); + QTest::newRow("testdir.lnk") << (m_dataPath + "/testdir/dir.lnk") << QStringList() + << (int)(QDir::NoFilter) << (int)(QDir::NoSort) + << QString(".,..,aaaaa.txt,subdir,subdir.lnk").split(','); } void tst_QDir::entryList() @@ -1685,9 +1688,9 @@ void tst_QDir::dotAndDotDot() { QDir dir(QString((m_dataPath + "/testdir/"))); QStringList entryList = dir.entryList(QDir::Dirs); - QCOMPARE(entryList, QStringList() << QString(".") << QString("..") << QString("dir") << QString("spaces")); + QCOMPARE(entryList, QStringList({ u"."_qs, u".."_qs, u"dir"_qs, u"dir.lnk"_qs, u"spaces"_qs })); entryList = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); - QCOMPARE(entryList, QStringList() << QString("dir") << QString("spaces")); + QCOMPARE(entryList, QStringList({ u"dir"_qs, u"dir.lnk"_qs, u"spaces"_qs })); } void tst_QDir::homePath()