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

qt file system classes on windows are wrong in certain circumstances

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P3: Somewhat important
    • None
    • 5.4.1
    • Core: I/O
    • None
    • qt 5.4.1 windows 8.1 compiled from source using msvc 2012

    Description

      The following program:
      """
      #include <QCoreApplication>
      #include <QFileInfo>
      #include <QDebug>

      #define DEBUG_PP(X) qDebug() << #X << X;
      int main(int argc, char *argv[])
      {
      QCoreApplication a(argc, argv);
      QString root = a.applicationFilePath().split("/").first();
      DEBUG_PP(root);
      DEBUG_PP(QFileInfo(root).canonicalFilePath())
      DEBUG_PP(QFileInfo("C:").canonicalFilePath())
      DEBUG_PP(QFileInfo("Z:").canonicalFilePath())
      DEBUG_PP(QFileInfo("C:").absoluteFilePath())
      DEBUG_PP(QFileInfo("Z:").absoluteFilePath())
      DEBUG_PP(QFileInfo("C:/").canonicalFilePath())
      DEBUG_PP(QFileInfo("Z:/").canonicalFilePath())
      DEBUG_PP(QFileInfo("C:/").absoluteFilePath())
      DEBUG_PP(QFileInfo("Z:/").absoluteFilePath())
      return 0;

      """
      produces the following output
      """
      Starting C:\Users\Kim\Documents\build-qt_fs_win_fail-5_4_1_msvc2012-Debug\debug\qt_fs_win_fail.exe...
      root "C:"
      QFileInfo(root).canonicalFilePath() "C:/Users/Kim/Documents/build-qt_fs_win_fail-5_4_1_msvc2012-Debug"
      QFileInfo("C:").canonicalFilePath() "C:/Users/Kim/Documents/build-qt_fs_win_fail-5_4_1_msvc2012-Debug"
      QFileInfo("Z:").canonicalFilePath() "Z:/"
      QFileInfo("C:").absoluteFilePath() "C:/Users/Kim/Documents/build-qt_fs_win_fail-5_4_1_msvc2012-Debug"
      QFileInfo("Z:").absoluteFilePath() "Z:/"
      QFileInfo("C:/").canonicalFilePath() "C:/"
      QFileInfo("Z:/").canonicalFilePath() "Z:/"
      QFileInfo("C:/").absoluteFilePath() "C:/"
      QFileInfo("Z:/").absoluteFilePath() "Z:/"
      """
      This is not what i expected. And the documentation says nothing about requiring a trailing / to ensure that resolving paths correctly work.

      Also
      """
      #include <QCoreApplication>
      #include <QDir>
      #include <QDebug>
      #include <QFileInfo>

      int main(int argc, char *argv[])
      {
      auto fn = [](QString s){
      const QFileInfoList lst = QDir(s).entryInfoList(QDir::Hidden | QDir::Files | QDir::Dirs | QDir::System | QDir::NoDotAndDotDot);
      if(lst.isEmpty())

      { qDebug() << "empty"; return; }

      qDebug() << "##### does exist...";
      foreach(QFileInfo fi, lst)
      qDebug() << fi.absoluteFilePath() << "exists" << fi.exists();
      qDebug() << "##### does not exist...";
      foreach(QFileInfo fi, lst)
      qDebug() << fi.absoluteFilePath() << "exists" << fi.exists() << "issymlink" << fi.isSymLink();
      };
      QCoreApplication a(argc, argv);
      fn(a.applicationDirPath()+"/wat.lnk");
      return 0;
      }

      """
      The produced output of each foreach() loop is a list each file and folder present on the drive (presumably C this was run on prepended with QCoreApplication::applicationDirPath()+"/wat.lnk/"
      The expected output should be "empty" (provided you don't actually have a valid shortcut called wat.lnk in your build folder)
      This is a snippet of the output on my windows 8.1 device:
      """

              1. does exist...
                "C:/Users/Kim/Documents/build-qt_fs_win_fail-5_4_1_msvc2012-Debug/debug/wat.lnk/$Recycle.Bin" exists true
                "C:/Users/Kim/Documents/build-qt_fs_win_fail-5_4_1_msvc2012-Debug/debug/wat.lnk/dev" exists true
                "C:/Users/Kim/Documents/build-qt_fs_win_fail-5_4_1_msvc2012-Debug/debug/wat.lnk/Go" exists true
                "C:/Users/Kim/Documents/build-qt_fs_win_fail-5_4_1_msvc2012-Debug/debug/wat.lnk/hiberfil.sys" exists true
                "C:/Users/Kim/Documents/build-qt_fs_win_fail-5_4_1_msvc2012-Debug/debug/wat.lnk/Jenkins" exists true
                "C:/Users/Kim/Documents/build-qt_fs_win_fail-5_4_1_msvc2012-Debug/debug/wat.lnk/pagefile.sys" exists true
                "C:/Users/Kim/Documents/build-qt_fs_win_fail-5_4_1_msvc2012-Debug/debug/wat.lnk/PerfLogs" exists true
                "C:/Users/Kim/Documents/build-qt_fs_win_fail-5_4_1_msvc2012-Debug/debug/wat.lnk/Perl64" exists true
                "C:/Users/Kim/Documents/build-qt_fs_win_fail-5_4_1_msvc2012-Debug/debug/wat.lnk/Program Files" exists true
                "C:/Users/Kim/Documents/build-qt_fs_win_fail-5_4_1_msvc2012-Debug/debug/wat.lnk/Program Files (x86)" exists true
                "C:/Users/Kim/Documents/build-qt_fs_win_fail-5_4_1_msvc2012-Debug/debug/wat.lnk/ProgramData" exists true
                "C:/Users/Kim/Documents/build-qt_fs_win_fail-5_4_1_msvc2012-Debug/debug/wat.lnk/Qt" exists true
                (...)
              2. does not exist...
                "C:/Users/Kim/Documents/build-qt_fs_win_fail-5_4_1_msvc2012-Debug/debug/wat.lnk/$Recycle.Bin" exists false issymlink false
                "C:/Users/Kim/Documents/build-qt_fs_win_fail-5_4_1_msvc2012-Debug/debug/wat.lnk/dev" exists false issymlink false
                "C:/Users/Kim/Documents/build-qt_fs_win_fail-5_4_1_msvc2012-Debug/debug/wat.lnk/Go" exists false issymlink false
                "C:/Users/Kim/Documents/build-qt_fs_win_fail-5_4_1_msvc2012-Debug/debug/wat.lnk/hiberfil.sys" exists false issymlink false
                "C:/Users/Kim/Documents/build-qt_fs_win_fail-5_4_1_msvc2012-Debug/debug/wat.lnk/Jenkins" exists false issymlink false
                "C:/Users/Kim/Documents/build-qt_fs_win_fail-5_4_1_msvc2012-Debug/debug/wat.lnk/pagefile.sys" exists false issymlink false
                "C:/Users/Kim/Documents/build-qt_fs_win_fail-5_4_1_msvc2012-Debug/debug/wat.lnk/PerfLogs" exists false issymlink false
                "C:/Users/Kim/Documents/build-qt_fs_win_fail-5_4_1_msvc2012-Debug/debug/wat.lnk/Perl64" exists false issymlink false
                "C:/Users/Kim/Documents/build-qt_fs_win_fail-5_4_1_msvc2012-Debug/debug/wat.lnk/Program Files" exists false issymlink false
                "C:/Users/Kim/Documents/build-qt_fs_win_fail-5_4_1_msvc2012-Debug/debug/wat.lnk/Program Files (x86)" exists false issymlink false
                "C:/Users/Kim/Documents/build-qt_fs_win_fail-5_4_1_msvc2012-Debug/debug/wat.lnk/ProgramData" exists false issymlink false
                "C:/Users/Kim/Documents/build-qt_fs_win_fail-5_4_1_msvc2012-Debug/debug/wat.lnk/Qt" exists false issymlink false
                (...)
                """

      What happened here?
      QDir("non-existing.lnk").entryInfoList(flags) was given a path that does not exist AND ends with .lnk.
      The ".lnk" suffix is important. If any other suffix had been used the output would have been "empty" as expected.
      So this is probably related to how qt resolves windows shortcuts.

      There is also the issue of the first loop printing exists true (which obviously is not the case) and the second loop printing exists false and the only difference being that issymlink() is called before exists() is. And issymlink() should be const.

      Sorry if i should not have lumped these two cases together, but they seemed related to me.

      Attachments

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

        Activity

          People

            cnn Qt Core & Network
            kimbs Kim Bowles Sørhus
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes