From 437797d1c488d65c950219fe4b85aca9685c2d0a Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Tue, 7 Nov 2023 12:25:29 +0100 Subject: [PATCH] Utils: Fix endless loop when ls iterating subdirs findUsingLs did try to enter "." and "..", with especially "." leading to an endless loop. findUsingLs also did not correctly concatenate the parent folder for sub directories. Change-Id: Ieafad4d4ef38d2fb550ddef1d2edf8183ce8032e Reviewed-by: hjk --- src/libs/utils/devicefileaccess.cpp | 12 +++++---- src/libs/utils/devicefileaccess.h | 15 +++++------ .../tst_unixdevicefileaccess.cpp | 26 +++++++++++++++++++ 3 files changed, 40 insertions(+), 13 deletions(-) diff --git a/src/libs/utils/devicefileaccess.cpp b/src/libs/utils/devicefileaccess.cpp index a38a3617a7e..82e6a24a71d 100644 --- a/src/libs/utils/devicefileaccess.cpp +++ b/src/libs/utils/devicefileaccess.cpp @@ -1256,7 +1256,8 @@ bool UnixDeviceFileAccess::iterateWithFind(const FilePath &filePath, void UnixDeviceFileAccess::findUsingLs(const QString ¤t, const FileFilter &filter, - QStringList *found) const + QStringList *found, + const QString &start) const { const RunResult result = runInShell( {"ls", {"-1", "-a", "-p", "--", current}, OsType::OsTypeLinux}); @@ -1265,10 +1266,11 @@ void UnixDeviceFileAccess::findUsingLs(const QString ¤t, const QChar last = entry.back(); if (last == '/') { entry.chop(1); - if (filter.iteratorFlags.testFlag(QDirIterator::Subdirectories)) - findUsingLs(current + '/' + entry, filter, found); + if (filter.iteratorFlags.testFlag(QDirIterator::Subdirectories) && entry != "." + && entry != "..") + findUsingLs(current + '/' + entry, filter, found, start + entry + "/"); } - found->append(entry); + found->append(start + entry); } } @@ -1327,7 +1329,7 @@ void UnixDeviceFileAccess::iterateDirectory(const FilePath &filePath, // if we do not have find - use ls as fallback QStringList entries; - findUsingLs(filePath.path(), filter, &entries); + findUsingLs(filePath.path(), filter, &entries, {}); iterateLsOutput(filePath, entries, filter, callBack); } diff --git a/src/libs/utils/devicefileaccess.h b/src/libs/utils/devicefileaccess.h index 6dddbc70045..5b7c766a8a7 100644 --- a/src/libs/utils/devicefileaccess.h +++ b/src/libs/utils/devicefileaccess.h @@ -183,16 +183,15 @@ protected: expected_str createTempFile(const FilePath &filePath) override; + void findUsingLs(const QString ¤t, + const FileFilter &filter, + QStringList *found, + const QString &start) const; private: - bool iterateWithFind( - const FilePath &filePath, - const FileFilter &filter, - const FilePath::IterateDirCallback &callBack) const; - void findUsingLs( - const QString ¤t, - const FileFilter &filter, - QStringList *found) const; + bool iterateWithFind(const FilePath &filePath, + const FileFilter &filter, + const FilePath::IterateDirCallback &callBack) const; QStringList statArgs(const FilePath &filePath, const QString &linuxFormat, diff --git a/tests/auto/utils/unixdevicefileaccess/tst_unixdevicefileaccess.cpp b/tests/auto/utils/unixdevicefileaccess/tst_unixdevicefileaccess.cpp index 5eba8122241..a55577ef05e 100644 --- a/tests/auto/utils/unixdevicefileaccess/tst_unixdevicefileaccess.cpp +++ b/tests/auto/utils/unixdevicefileaccess/tst_unixdevicefileaccess.cpp @@ -48,6 +48,11 @@ public: p.waitForFinished(); return {p.exitCode(), p.readAllStandardOutput(), p.readAllStandardError()}; } + + void findUsingLs(const QString ¤t, const FileFilter &filter, QStringList *found) + { + UnixDeviceFileAccess::findUsingLs(current, filter, found, {}); + } }; class tst_unixdevicefileaccess : public QObject @@ -69,6 +74,27 @@ private slots: QCOMPARE(size, 1024); } + void findUsingLs() + { + QStringList result; + m_dfa.findUsingLs(m_tempDir.path(), + {{}, QDir::NoFilter, QDirIterator::Subdirectories}, + &result); + + QCOMPARE(result, QStringList({".", "..", "size-test"})); + + QDir tDir(m_tempDir.path()); + tDir.mkdir("lsfindsubdir"); + + result.clear(); + m_dfa.findUsingLs(m_tempDir.path(), + {{}, QDir::NoFilter, QDirIterator::Subdirectories}, + &result); + QCOMPARE(result, + QStringList( + {".", "..", "lsfindsubdir/.", "lsfindsubdir/..", "lsfindsubdir", "size-test"})); + } + private: TestDFA m_dfa; DeviceFileAccess *m_dfaPtr = &m_dfa;