Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-15421

[Regression] QDirIterator returns hidden directories when it should only return files and returns hidden files when it should only return directories

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • P1: Critical
    • 4.7.4
    • 4.6.0, 4.6.1, 4.6.2, 4.6.3, 4.7.0, 4.7.1
    • Core: I/O
    • None
    • linux-g++
      The bug occurs with both Qt built from a source package with no additional options passed to configure script and with pre-built Qt supplied by Ubuntu distro.
    • b3ba4b7de3bac0e444654fe150b4e5b3cc82fb39

    Description

      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.

      This regression is demonstrated by the following test program:

      #include <QtCore/QCoreApplication>
      #include <QtCore/QDir>
      #include <QtCore/QDirIterator>
      #include <QtCore/QFileInfo>
      #include <QtCore/QString>
      #include <stdio.h>
      
      int main(int argc, char **argv)
      {
          printf("Testing using Qt version %s\n", QT_VERSION_STR);
      
          QCoreApplication app(argc, argv);
      
          QStringList args = app.arguments();
          args.takeFirst();           // the executable name
      
          if (args.count() < 1) {
              printf("Usage: test <dirname>\n");
              return 1;
          }
      
          QDir qtdir = args.takeFirst();
      
          if (!qtdir.exists()) {
              printf("Directory %s does not exist", qPrintable(qtdir.path()));
              return 1;
          }
      
          qtdir.makeAbsolute();
      
          {
              printf("Performing file search test...\n");
              int matches = 0;
              int failures = 0;
              QDirIterator di(qtdir.path(), QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
              while (di.hasNext()) {
                  ++matches;
                  QString filename = di.next();
                  if (QFileInfo(filename).isDir()) {
                      printf("\tSearch returned directory %s\n", qPrintable(filename));
                      ++failures;    // search was only supposed to find files
                  }
              }
              printf("Search returned %d items, %d of which weren't files.\n", matches, failures);
              printf("File search test result: %s.\n", failures ? "Fail" : "Pass" );
          }
      
          {
              printf("Performing directory search test...\n");
              int matches = 0;
              int failures = 0;
              QDirIterator di(qtdir.path(), QDir::Dirs | QDir::Hidden | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
              while (di.hasNext()) {
                  ++matches;
                  QString filename = di.next();
                  if (!QFileInfo(filename).isDir()) {
                      printf("\tSearch returned file %s\n", qPrintable(filename));
                      ++failures;    // search was only supposed to find files
                  }
              }
              printf("Search returned %d items, %d of which weren't directories.\n", matches, failures);
              printf("Directory search test result: %s.\n", failures ? "Fail" : "Pass" );
          }
      
          return 0;
      }
      

      When run against Qt 4.5.3 and passed the path to my copy of the qt-release repository, this program produces the following (correct) output:

      user@host:~/test$ (make clean && qmake && make) >> /dev/null && ./test ~/depot/qt-releases
      Testing using Qt version 4.5.3
      Performing file search test...
      Search returned 43355 items, 0 of which weren't files.
      File search test result: Pass.
      Performing directory search test...
      Search returned 4482 items, 0 of which weren't directories.
      Directory search test result: Pass.
      

      When run against Qt 4.6.0 and passed the path to my copy of the qt-releases repository, the program produces the following (incorrect) output:

      user@host:~/test$ (make clean && qmake && make) >> /dev/null && ./test ~/depot/qt-releases
      Testing using Qt version 4.6.0
      Performing file search test...
              Search returned directory /home/user/depot/qt-releases/.git
      Search returned 43356 items, 1 of which weren't files.
      File search test result: Fail.
      Performing directory search test...
              Search returned file /home/user/depot/qt-releases/.gitignore
      ...
      Search returned 5012 items, 530 of which weren't directories.
      Directory search test result: Fail.
      

      The difference is even more dramatic if you run the program on your home directory instead.

      This regression broke part of Qt's packaging system when we moved it from OpenSuSE 11.2 (Qt 4.5.3) to Ubuntu 10.04 (Qt 4.6.2). The behaviour should be restored to that of 4.5.3 and earlier releases.

      Attachments

        Issue Links

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

              cduclos Carlos Duclos (Inactive)
              jasmcdon Jason McDonald (Closed Nokia Identity. Please assign to "macadder" instead) (Inactive)
              Votes:
              1 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes