From 8c24a03b5ed91f71265acc0a12c4f982144b035f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 6 Jun 2025 16:12:57 -0300 Subject: [PATCH] QFileSystemEngine/Unix: avoid an unnecessary conversion to QString Sometimes, fillMetaData() is called with a QFileSystemEntry with only the native (QByteArray) format, which we used above in this function anyway in order to lstat() and stat() the path. This avoids forcing the QFSE to create the QString form for us to check the first character. Pick-to: 6.8 Change-Id: I8d93f6db83a28d70a192fffd6668734a8024b88b Reviewed-by: Ahmad Samir (cherry picked from commit e1d418bcd07aba891da79c653f5b0e3c6852fb30) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 8e7ddf261ed13197c6f9cd864ef9d39ed75be75e) --- src/corelib/io/qfilesystemengine_unix.cpp | 15 ++++++++++++--- tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp | 12 ++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index e4cee613ff9..341f8f550ff 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -1083,9 +1083,18 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM #endif if (what & QFileSystemMetaData::HiddenAttribute - && !data.isHidden()) { - QString fileName = entry.fileName(); - if (fileName.startsWith(u'.') + && !data.isHidden()) { + // reusing nativeFilePath from above instead of entry.fileName(), to + // avoid memory allocation for the QString result. + qsizetype lastSlash = nativeFilePath.size(); + + while (lastSlash && nativeFilePath.at(lastSlash - 1) == '/') + --lastSlash; // skip ending slashes + while (lastSlash && nativeFilePath.at(lastSlash - 1) != '/') + --lastSlash; // skip non-slashes + --lastSlash; // point to the slash or -1 if no slash + + if (nativeFilePath.at(lastSlash + 1) == '.' #if defined(Q_OS_DARWIN) || (entryErrno == 0 && hasResourcePropertyFlag(data, entry, kCFURLIsHiddenKey)) #endif diff --git a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp index 4f0534ab177..0ee011af517 100644 --- a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp @@ -1551,14 +1551,26 @@ void tst_QFileInfo::isHidden_data() #if defined(Q_OS_WIN) QVERIFY(QDir("./hidden-directory").exists() || QDir().mkdir("./hidden-directory")); QVERIFY(SetFileAttributesW(reinterpret_cast(QString("./hidden-directory").utf16()),FILE_ATTRIBUTE_HIDDEN)); + QTest::newRow("hidden-directory") << QString::fromLatin1("hidden-directory") << true; QTest::newRow("C:/path/to/hidden-directory") << QDir::currentPath() + QString::fromLatin1("/hidden-directory") << true; QTest::newRow("C:/path/to/hidden-directory/.") << QDir::currentPath() + QString::fromLatin1("/hidden-directory/.") << true; #endif #if defined(Q_OS_UNIX) QVERIFY(QDir("./.hidden-directory").exists() || QDir().mkdir("./.hidden-directory")); + QTest::newRow(".hidden-directory") << QString(".hidden-directory") << true; + QTest::newRow(".hidden-directory/") << QString(".hidden-directory/") << true; + QTest::newRow(".hidden-directory//") << QString(".hidden-directory//") << true; + QTest::newRow(".hidden-directory/.") << QString(".hidden-directory/.") << true; + QTest::newRow(".hidden-directory//.") << QString(".hidden-directory//.") << true; + QTest::newRow(".hidden-directory/..") << QString(".hidden-directory/..") << true; + QTest::newRow(".hidden-directory//..") << QString(".hidden-directory//..") << true; QTest::newRow("/path/to/.hidden-directory") << QDir::currentPath() + QString("/.hidden-directory") << true; + QTest::newRow("/path/to/.hidden-directory/") << QDir::currentPath() + QString("/.hidden-directory/") << true; + QTest::newRow("/path/to/.hidden-directory//") << QDir::currentPath() + QString("/.hidden-directory//") << true; QTest::newRow("/path/to/.hidden-directory/.") << QDir::currentPath() + QString("/.hidden-directory/.") << true; + QTest::newRow("/path/to/.hidden-directory//.") << QDir::currentPath() + QString("/.hidden-directory//.") << true; QTest::newRow("/path/to/.hidden-directory/..") << QDir::currentPath() + QString("/.hidden-directory/..") << true; + QTest::newRow("/path/to/.hidden-directory//..") << QDir::currentPath() + QString("/.hidden-directory//..") << true; #endif #if defined(Q_OS_DARWIN)