summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarlos Manuel Duclos Vergara <carlos.duclos@nokia.com>2011-03-30 12:05:03 (GMT)
committerCarlos Manuel Duclos Vergara <carlos.duclos@nokia.com>2011-03-30 12:20:14 (GMT)
commitb3ba4b7de3bac0e444654fe150b4e5b3cc82fb39 (patch)
tree6191316d70bd7a326dd1fd836f45fd20ff53020d
parent0cc8a2d09d8dc1d2da87878e70fad0d343b0dcd6 (diff)
downloadQt-b3ba4b7de3bac0e444654fe150b4e5b3cc82fb39.zip
Qt-b3ba4b7de3bac0e444654fe150b4e5b3cc82fb39.tar.gz
Qt-b3ba4b7de3bac0e444654fe150b4e5b3cc82fb39.tar.bz2
QDirIterator returns hidden directories when it should only return files
In Qt 4.5.3 and earlier, creating a QDirIterator with QDir::Files | QDir::Hidden (i.e. search for all files, including hidden files) returned a list of all hidden and non-hidden files in a directory tree. In Qt 4.6.0 and later the same filter causes QDirIterator to return a list of all hidden and non-hidden files and all hidden directories. As the user is asking only for files, clearly returning hidden directories too is incorrect behaviour. Similarly, when asking for QDir::Dirs | QDir::Hidden (i.e. all directories, including hidden directories), hidden files are also (wrongly) returned. Task-number: QTBUG-15421 Reviewed-by: joao
-rw-r--r--src/corelib/io/qdiriterator.cpp28
-rw-r--r--tests/auto/qdiriterator/tst_qdiriterator.cpp55
2 files changed, 70 insertions, 13 deletions
diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp
index 3b4adc3..4d3f50b 100644
--- a/src/corelib/io/qdiriterator.cpp
+++ b/src/corelib/io/qdiriterator.cpp
@@ -278,6 +278,7 @@ void QDirIteratorPrivate::checkAndPushDirectory(const QFileInfo &fileInfo)
current entry will be returned as part of the directory iteration);
otherwise, false is returned.
*/
+
bool QDirIteratorPrivate::matchesFilters(const QString &fileName, const QFileInfo &fi) const
{
Q_ASSERT(!fileName.isEmpty());
@@ -312,6 +313,14 @@ bool QDirIteratorPrivate::matchesFilters(const QString &fileName, const QFileInf
return false;
}
#endif
+ // skip symlinks
+ const bool skipSymlinks = (filters & QDir::NoSymLinks);
+ const bool includeSystem = (filters & QDir::System);
+ if(skipSymlinks && fi.isSymLink()) {
+ // The only reason to save this file is if it is a broken link and we are requesting system files.
+ if(!includeSystem || fi.exists())
+ return false;
+ }
// filter hidden
const bool includeHidden = (filters & QDir::Hidden);
@@ -319,27 +328,20 @@ bool QDirIteratorPrivate::matchesFilters(const QString &fileName, const QFileInf
return false;
// filter system files
- const bool includeSystem = (filters & QDir::System);
- if (!includeSystem && ((!fi.isFile() && !fi.isDir() && !fi.isSymLink())
+ if (!includeSystem && (!(fi.isFile() || fi.isDir() || fi.isSymLink())
|| (!fi.exists() && fi.isSymLink())))
return false;
// skip directories
const bool skipDirs = !(filters & (QDir::Dirs | QDir::AllDirs));
- if (skipDirs && fi.isDir()) {
- if (!((includeHidden && !dotOrDotDot && fi.isHidden())
- || (includeSystem && !fi.exists() && fi.isSymLink())))
- return false;
- }
+ if (skipDirs && fi.isDir())
+ return false;
// skip files
const bool skipFiles = !(filters & QDir::Files);
- const bool skipSymlinks = (filters & QDir::NoSymLinks);
- if ((skipFiles && (fi.isFile() || !fi.exists())) || (skipSymlinks && fi.isSymLink())) {
- if (!((includeHidden && !dotOrDotDot && fi.isHidden())
- || (includeSystem && !fi.exists() && fi.isSymLink())))
- return false;
- }
+ if (skipFiles && fi.isFile())
+ // Basically we need a reason not to exclude this file otherwise we just eliminate it.
+ return false;
// filter permissions
const bool filterPermissions = ((filters & QDir::PermissionMask)
diff --git a/tests/auto/qdiriterator/tst_qdiriterator.cpp b/tests/auto/qdiriterator/tst_qdiriterator.cpp
index f7666dc..9689bee 100644
--- a/tests/auto/qdiriterator/tst_qdiriterator.cpp
+++ b/tests/auto/qdiriterator/tst_qdiriterator.cpp
@@ -118,6 +118,7 @@ private slots:
void longPath();
void task185502_dirorder();
void relativePaths();
+ void qtbug15421_hiddenDirs_hiddenFiles();
};
tst_QDirIterator::tst_QDirIterator()
@@ -163,6 +164,20 @@ tst_QDirIterator::tst_QDirIterator()
createLink("nothing", "entrylist/brokenlink.lnk");
# endif
#endif
+
+ createDirectory("qtbug15421_hiddenDirs_hiddenFiles");
+ createFile("qtbug15421_hiddenDirs_hiddenFiles/normalFile");
+ createFile("qtbug15421_hiddenDirs_hiddenFiles/.hiddenFile");
+ createDirectory("qtbug15421_hiddenDirs_hiddenFiles/normalDirectory");
+ createDirectory("qtbug15421_hiddenDirs_hiddenFiles/.hiddenDirectory");
+ createFile("qtbug15421_hiddenDirs_hiddenFiles/normalDirectory/normalFile");
+ createFile("qtbug15421_hiddenDirs_hiddenFiles/normalDirectory/.hiddenFile");
+ createFile("qtbug15421_hiddenDirs_hiddenFiles/.hiddenDirectory/normalFile");
+ createFile("qtbug15421_hiddenDirs_hiddenFiles/.hiddenDirectory/.hiddenFile");
+ createDirectory("qtbug15421_hiddenDirs_hiddenFiles/normalDirectory/normalDirectory");
+ createDirectory("qtbug15421_hiddenDirs_hiddenFiles/normalDirectory/.hiddenDirectory");
+ createDirectory("qtbug15421_hiddenDirs_hiddenFiles/.hiddenDirectory/normalDirectory");
+ createDirectory("qtbug15421_hiddenDirs_hiddenFiles/.hiddenDirectory/.hiddenDirectory");
}
tst_QDirIterator::~tst_QDirIterator()
@@ -532,6 +547,46 @@ void tst_QDirIterator::relativePaths()
}
}
+void tst_QDirIterator::qtbug15421_hiddenDirs_hiddenFiles()
+{
+ // In Unix it is easy to create hidden files, but in Windows it requires
+ // a special call since hidden files need to be "marked" while in Unix
+ // anything starting by a '.' is a hidden file.
+ // For that reason this test is not run in Windows.
+#if defined Q_OS_WIN || Q_OS_WINCE
+ QSKIP("To create hidden files a special call is required in Windows.");
+#else
+ // Only files
+ {
+ int matches = 0;
+ int failures = 0;
+ QDirIterator di("qtbug15421_hiddenDirs_hiddenFiles", QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
+ while (di.hasNext()) {
+ ++matches;
+ QString filename = di.next();
+ if (QFileInfo(filename).isDir())
+ ++failures; // search was only supposed to find files
+ }
+ QCOMPARE(matches, 6);
+ QCOMPARE(failures, 0);
+ }
+ // Only directories
+ {
+ int matches = 0;
+ int failures = 0;
+ QDirIterator di("qtbug15421_hiddenDirs_hiddenFiles", QDir::Dirs | QDir::Hidden | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
+ while (di.hasNext()) {
+ ++matches;
+ QString filename = di.next();
+ if (!QFileInfo(filename).isDir())
+ ++failures; // search was only supposed to find files
+ }
+ QCOMPARE(matches, 6);
+ QCOMPARE(failures, 0);
+ }
+#endif // Q_OS_WIN || Q_OS_WINCE
+}
+
QTEST_MAIN(tst_QDirIterator)
#include "tst_qdiriterator.moc"