From b168c6c8248662da31dbaaf2afb8e771a9ecdc85 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 17 Nov 2015 22:21:53 -0800 Subject: QStorageInfo: fix matching of mountpoints to sibling directories The path "/usrfoo" starts with "/usr", so if you tried to get QStorageInfo("/usrfoo") when "/usr" is a mount point, you'd get the wrong filesystem. [ChangeLog][QtCore][QStorageInfo] Fixed a bug that caused QStorageInfo to report information for the wrong filesystem if there is a mounted filesystem at a path that is a prefix of the requested path (e.g., it would report "/usr" filesystem for "/usrfoo"). Task-number: QTBUG-49498 Change-Id: I3e15a26e0e424169ac2bffff1417b7a27cd0132d Reviewed-by: Jake Petroules --- src/corelib/io/qstorageinfo_unix.cpp | 58 +++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 24 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp index e365d8d7e6..bbcc29c50b 100644 --- a/src/corelib/io/qstorageinfo_unix.cpp +++ b/src/corelib/io/qstorageinfo_unix.cpp @@ -102,25 +102,6 @@ QT_BEGIN_NAMESPACE -static bool isPseudoFs(const QString &mountDir, const QByteArray &type) -{ - if (mountDir.startsWith(QLatin1String("/dev")) - || mountDir.startsWith(QLatin1String("/proc")) - || mountDir.startsWith(QLatin1String("/sys")) - || mountDir.startsWith(QLatin1String("/var/run")) - || mountDir.startsWith(QLatin1String("/var/lock"))) { - return true; - } - if (type == "tmpfs") - return true; -#if defined(Q_OS_LINUX) - if (type == "rootfs" || type == "rpc_pipefs") - return true; -#endif - - return false; -} - class QStorageIterator { public: @@ -158,6 +139,36 @@ private: #endif }; +template +static bool isParentOf(const String &parent, const QString &dirName) +{ + return dirName.startsWith(parent) && + (dirName.size() == parent.size() || dirName.at(parent.size()) == QLatin1Char('/') || + parent.size() == 1); +} + +static bool isPseudoFs(const QStorageIterator &it) +{ + QString mountDir = it.rootPath(); + if (isParentOf(QLatin1String("/dev"), mountDir) + || isParentOf(QLatin1String("/proc"), mountDir) + || isParentOf(QLatin1String("/sys"), mountDir) + || isParentOf(QLatin1String("/var/run"), mountDir) + || isParentOf(QLatin1String("/var/lock"), mountDir)) { + return true; + } + + QByteArray type = it.fileSystemType(); + if (type == "tmpfs") + return true; +#if defined(Q_OS_LINUX) + if (type == "rootfs" || type == "rpc_pipefs") + return true; +#endif + + return false; +} + #if defined(Q_OS_BSD4) inline QStorageIterator::QStorageIterator() @@ -444,10 +455,10 @@ void QStorageInfoPrivate::initRootPath() while (it.next()) { const QString mountDir = it.rootPath(); const QByteArray fsName = it.fileSystemType(); - if (isPseudoFs(mountDir, fsName)) + if (isPseudoFs(it)) continue; // we try to find most suitable entry - if (oldRootPath.startsWith(mountDir) && maxLength < mountDir.length()) { + if (isParentOf(mountDir, oldRootPath) && maxLength < mountDir.length()) { maxLength = mountDir.length(); rootPath = mountDir; device = it.device(); @@ -536,11 +547,10 @@ QList QStorageInfoPrivate::mountedVolumes() QList volumes; while (it.next()) { - const QString mountDir = it.rootPath(); - const QByteArray fsName = it.fileSystemType(); - if (isPseudoFs(mountDir, fsName)) + if (isPseudoFs(it)) continue; + const QString mountDir = it.rootPath(); volumes.append(QStorageInfo(mountDir)); } -- cgit v1.2.3