From cab8eee85c049de2f1e3b557c262da7c22ce464f Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Tue, 14 Feb 2023 08:09:28 +0100 Subject: [PATCH] Utils: Fix fileInfoFlagsfromStatMode Previously the checks for the mode bits were incorrectly using AND checks. As a fix the contents of "stat.h" was copied and converted so it can be used directly and on platforms that do not contain stat.h Change-Id: If735dcffb8ffc490d297dae7f8c43ae01e79f460 Reviewed-by: Qt CI Bot Reviewed-by: Reviewed-by: hjk --- src/libs/utils/filepathinfo.h | 5 ++ src/libs/utils/fileutils.cpp | 55 +++++++++++---- tests/auto/utils/fileutils/tst_fileutils.cpp | 74 ++++++++++++++++++++ 3 files changed, 121 insertions(+), 13 deletions(-) diff --git a/src/libs/utils/filepathinfo.h b/src/libs/utils/filepathinfo.h index 0b942340787..31f6fd1728c 100644 --- a/src/libs/utils/filepathinfo.h +++ b/src/libs/utils/filepathinfo.h @@ -47,6 +47,11 @@ struct FilePathInfo Q_DECLARE_FLAGS(FileFlags, FileFlag) + bool operator==(const FilePathInfo &other) const + { + return fileSize == other.fileSize && fileFlags == other.fileFlags + && lastModified == other.lastModified; + } qint64 fileSize = 0; FileFlags fileFlags; diff --git a/src/libs/utils/fileutils.cpp b/src/libs/utils/fileutils.cpp index 399f0913656..69c31729149 100644 --- a/src/libs/utils/fileutils.cpp +++ b/src/libs/utils/fileutils.cpp @@ -586,8 +586,36 @@ FilePaths FileUtils::getOpenFilePaths(QWidget *parent, #endif // QT_WIDGETS_LIB +// Converts a hex string of the st_mode field of a stat structure to FileFlags. FilePathInfo::FileFlags fileInfoFlagsfromStatRawModeHex(const QString &hexString) { + // Copied from stat.h + enum st_mode { + IFMT = 00170000, + IFSOCK = 0140000, + IFLNK = 0120000, + IFREG = 0100000, + IFBLK = 0060000, + IFDIR = 0040000, + IFCHR = 0020000, + IFIFO = 0010000, + ISUID = 0004000, + ISGID = 0002000, + ISVTX = 0001000, + IRWXU = 00700, + IRUSR = 00400, + IWUSR = 00200, + IXUSR = 00100, + IRWXG = 00070, + IRGRP = 00040, + IWGRP = 00020, + IXGRP = 00010, + IRWXO = 00007, + IROTH = 00004, + IWOTH = 00002, + IXOTH = 00001, + }; + bool ok = false; uint mode = hexString.toUInt(&ok, 16); @@ -595,31 +623,32 @@ FilePathInfo::FileFlags fileInfoFlagsfromStatRawModeHex(const QString &hexString FilePathInfo::FileFlags result; - if (mode & 0x100) // S_IRUSR + if (mode & IRUSR) result |= FilePathInfo::ReadOwnerPerm; - if (mode & 0x80) // S_IWUSR + if (mode & IWUSR) result |= FilePathInfo::WriteOwnerPerm; - if (mode & 0x40) // S_IXUSR + if (mode & IXUSR) result |= FilePathInfo::ExeOwnerPerm; - if (mode & 0x20) // S_IRGRP + if (mode & IRGRP) result |= FilePathInfo::ReadGroupPerm; - if (mode & 0x10) // S_IWGRP + if (mode & IWGRP) result |= FilePathInfo::WriteGroupPerm; - if (mode & 0x8) // S_IXGRP + if (mode & IXGRP) result |= FilePathInfo::ExeGroupPerm; - if (mode & 0x4) // S_IROTH + if (mode & IROTH) result |= FilePathInfo::ReadOtherPerm; - if (mode & 0x2) // S_IWOTH + if (mode & IWOTH) result |= FilePathInfo::WriteOtherPerm; - if (mode & 0x1) // S_IXOTH + if (mode & IXOTH) result |= FilePathInfo::ExeOtherPerm; - if (mode & 0xa000) // S_IFLNK + + if ((mode & IFMT) == IFLNK) result |= FilePathInfo::LinkType; - if (mode & 0x8000) // S_IFREG + if ((mode & IFMT) == IFREG) result |= FilePathInfo::FileType; - if (mode & 0x4000) // S_IFDIR + if ((mode & IFMT) == IFDIR) result |= FilePathInfo::DirectoryType; - if (mode & 0x6000) // S_IFBLK + if ((mode & IFMT) == IFBLK) result |= FilePathInfo::LocalDiskFlag; if (result != 0) // There is no Exist flag, but if anything was set before, it must exist. diff --git a/tests/auto/utils/fileutils/tst_fileutils.cpp b/tests/auto/utils/fileutils/tst_fileutils.cpp index a7272e490b1..15604602776 100644 --- a/tests/auto/utils/fileutils/tst_fileutils.cpp +++ b/tests/auto/utils/fileutils/tst_fileutils.cpp @@ -118,6 +118,9 @@ private slots: void tmp_data(); void tmp(); + void filePathInfoFromTriple_data(); + void filePathInfoFromTriple(); + private: QTemporaryDir tempDir; QString rootPath; @@ -1358,6 +1361,77 @@ void tst_fileutils::tmp() } } +void tst_fileutils::filePathInfoFromTriple_data() +{ + QTest::addColumn("statoutput"); + QTest::addColumn("expected"); + + QTest::newRow("empty") << QString() << FilePathInfo(); + + QTest::newRow("linux-root") << QString("41ed 1676354359 4096") + << FilePathInfo{4096, + FilePathInfo::FileFlags( + FilePathInfo::ReadOwnerPerm + | FilePathInfo::WriteOwnerPerm + | FilePathInfo::ExeOwnerPerm + | FilePathInfo::ReadGroupPerm + | FilePathInfo::ExeGroupPerm + | FilePathInfo::ReadOtherPerm + | FilePathInfo::ExeOtherPerm + | FilePathInfo::DirectoryType + | FilePathInfo::ExistsFlag), + QDateTime::fromSecsSinceEpoch(1676354359)}; + + QTest::newRow("linux-grep-bin") + << QString("81ed 1668852790 808104") + << FilePathInfo{808104, + FilePathInfo::FileFlags( + FilePathInfo::ReadOwnerPerm | FilePathInfo::WriteOwnerPerm + | FilePathInfo::ExeOwnerPerm | FilePathInfo::ReadGroupPerm + | FilePathInfo::ExeGroupPerm | FilePathInfo::ReadOtherPerm + | FilePathInfo::ExeOtherPerm | FilePathInfo::FileType + | FilePathInfo::ExistsFlag), + QDateTime::fromSecsSinceEpoch(1668852790)}; + + QTest::newRow("linux-disk") << QString("61b0 1651167746 0") + << FilePathInfo{0, + FilePathInfo::FileFlags( + FilePathInfo::ReadOwnerPerm + | FilePathInfo::WriteOwnerPerm + | FilePathInfo::ReadGroupPerm + | FilePathInfo::WriteGroupPerm + | FilePathInfo::LocalDiskFlag + | FilePathInfo::ExistsFlag), + QDateTime::fromSecsSinceEpoch(1651167746)}; +} + +void tst_fileutils::filePathInfoFromTriple() +{ + QFETCH(QString, statoutput); + QFETCH(FilePathInfo, expected); + + const FilePathInfo result = FileUtils::filePathInfoFromTriple(statoutput); + + QCOMPARE(result, expected); +} + +QT_BEGIN_NAMESPACE +namespace QTest { +template<> +char *toString(const FilePathInfo &filePathInfo) +{ + QByteArray ba = "FilePathInfo("; + ba += QByteArray::number(filePathInfo.fileSize); + ba += ", "; + ba += QByteArray::number(filePathInfo.fileFlags, 16); + ba += ", "; + ba += filePathInfo.lastModified.toString().toUtf8(); + ba += ")"; + return qstrdup(ba.constData()); +} + +} // namespace QTest + QTEST_GUILESS_MAIN(tst_fileutils) #include "tst_fileutils.moc"