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

Fail to retrieve QFileInfo list with filename in NFC form.

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • P3: Somewhat important
    • 5.12.5, 5.13.1, 5.14.0 Alpha
    • 5.12.3
    • Core: I/O
    • None
    • macOS
    • d01693733f6c1ebe6b3709f9c1284239ce3b5354 (qt/qtbase/5.12)

    Description

       Enviroments:

      1. macOS, 10.14.5
      2. Python, 3.7.3
      3. PySide2, 5.12.3

      A minimal example:

      from PySide2.QtCore import QDir
      import os
      import fnmatch
      import unicodedata
      
      
      if __name__ == "__main__":
          task = ["r\u00E9-0.txt", "re\u0301-1.txt"]
          for one in task:
              print("open", one, ascii(one), ascii(unicodedata.normalize("NFC", one)))
              with open(one, "w") as f:
                  f.write(one)
          for e in os.listdir("."):
              if fnmatch.fnmatch(e, "*.txt"):
                  print("os.listdir", e, ascii(e))
          for e in QDir(".").entryInfoList(["*.txt"]):
              print("QDir", e.fileName())
      

      Terminal output on one APFS disk:

      open ré-0.txt 'r\xe9-0.txt' 'r\xe9-0.txt'
      open ré-1.txt 're\u0301-1.txt' 'r\xe9-1.txt'
      os.listdir ré-0.txt 'r\xe9-0.txt'
      os.listdir ré-1.txt 're\u0301-1.txt'
      QDir ré-1.txt
      

      Terminal output on one HFS+ disk:

      open ré-0.txt 'r\xe9-0.txt' 'r\xe9-0.txt'
      open ré-1.txt 're\u0301-1.txt' 'r\xe9-1.txt'
      os.listdir ré-0.txt 're\u0301-0.txt'
      os.listdir ré-1.txt 're\u0301-1.txt'
      QDir ré-0.txt
      QDir ré-1.txt
      

      Related source, qfilesystemiterator_unix.cpp

      bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaData &metaData)
      {
          if (!dir)
              return false;
      
          for (;;) {
              dirEntry = QT_READDIR(dir);
      
              if (dirEntry) {
                  // process entries with correct UTF-8 names only
                  if (QFile::encodeName(QFile::decodeName(dirEntry->d_name)) == dirEntry->d_name) {
                      fileEntry = QFileSystemEntry(nativePath + QByteArray(dirEntry->d_name), QFileSystemEntry::FromNativePath());
                      metaData.fillFromDirEnt(*dirEntry);
                      return true;
                  }
              } else {
                  break;
              }
          }
      
          lastError = errno;
          return false;
      }
      

      Related source, qfile.h:

      #if defined(Q_OS_DARWIN)
          // Mac always expects filenames in UTF-8... and decomposed...
          static inline QByteArray encodeName(const QString &fileName)
          {
              return fileName.normalized(QString::NormalizationForm_D).toUtf8();
          }
          static QString decodeName(const QByteArray &localFileName)
          {
              // note: duplicated in qglobal.cpp (qEnvironmentVariable)
              return QString::fromUtf8(localFileName).normalized(QString::NormalizationForm_C);
          }
      #else
          static inline QByteArray encodeName(const QString &fileName)
          {
              return fileName.toLocal8Bit();
          }
          static QString decodeName(const QByteArray &localFileName)
          {
              return QString::fromLocal8Bit(localFileName);
          }
      #endif
      

      Reference of APFS on filename handling:

       How does Apple File System handle filenames?

       

      Attachments

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

        Activity

          People

            thiago Thiago Macieira
            clerk_ma Clerk Ma
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes