summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qdir.cpp
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2016-11-29 15:20:21 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2016-12-12 07:25:05 +0000
commitf7b44f879cdded7b2c6b604df873f7194e56a63a (patch)
tree4034f9d032b85d4f76e24f249ae7988678f77751 /src/corelib/io/qdir.cpp
parent8005e0652c367c5e8c780a298d9fee4ce18a370a (diff)
QDir::cleanPath(): Do not cd above root paths (UNC, WinRT)
Calling QDir::cleanPath() on "//server/path/.." resulted in "/". Factor out a function to determine the root path part of an absolute path for later use, and handle some special cases: - Consider server name of "//server/path/.." as part of the prefix. - Check on the root path for WinRT. Task-number: QTBUG-53712 Change-Id: Ibddacf06212b6fc86fa74a5e4078df6cfd5b66f5 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@qt.io> Reviewed-by: Maurice Kalinowski <maurice.kalinowski@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/io/qdir.cpp')
-rw-r--r--src/corelib/io/qdir.cpp55
1 files changed, 36 insertions, 19 deletions
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index 91953ebf26..8f43b77bd5 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -80,6 +80,40 @@ static QString driveSpec(const QString &path)
}
#endif
+enum {
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+ OSSupportsUncPaths = true
+#else
+ OSSupportsUncPaths = false
+#endif
+};
+
+// Return the length of the root part of an absolute path, for use by cleanPath(), cd().
+static int rootLength(const QString &name, bool allowUncPaths)
+{
+ const int len = name.length();
+ // starts with double slash
+ if (allowUncPaths && name.startsWith(QLatin1String("//"))) {
+ // Server name '//server/path' is part of the prefix.
+ const int nextSlash = name.indexOf(QLatin1Char('/'), 2);
+ return nextSlash >= 0 ? nextSlash + 1 : len;
+ }
+#if defined(Q_OS_WINRT)
+ const QString rootPath = QDir::rootPath(); // rootPath contains the trailing slash
+ if (name.startsWith(rootPath, Qt::CaseInsensitive))
+ return rootPath.size();
+#endif // Q_OS_WINRT
+#if defined(Q_OS_WIN)
+ if (len >= 2 && name.at(1) == QLatin1Char(':')) {
+ // Handle a possible drive letter
+ return len > 2 && name.at(2) == QLatin1Char('/') ? 3 : 2;
+ }
+#endif
+ if (name.at(0) == QLatin1Char('/'))
+ return 1;
+ return 0;
+}
+
//************* QDirPrivate
QDirPrivate::QDirPrivate(const QString &path, const QStringList &nameFilters_, QDir::SortFlags sort_, QDir::Filters filters_)
: QSharedData()
@@ -2066,19 +2100,7 @@ Q_AUTOTEST_EXPORT QString qt_normalizePathSegments(const QString &name, bool all
const QChar *prefix = p;
int up = 0;
- int prefixLength = 0;
-
- if (allowUncPaths && len >= 2 && p[1].unicode() == '/' && p[0].unicode() == '/') {
- // starts with double slash
- prefixLength = 2;
-#ifdef Q_OS_WIN
- } else if (len >= 2 && p[1].unicode() == ':') {
- // remember the drive letter
- prefixLength = (len > 2 && p[2].unicode() == '/') ? 3 : 2;
-#endif
- } else if (p[0].unicode() == '/') {
- prefixLength = 1;
- }
+ const int prefixLength = rootLength(name, allowUncPaths);
p += prefixLength;
i -= prefixLength;
@@ -2188,12 +2210,7 @@ QString QDir::cleanPath(const QString &path)
if (dir_separator != QLatin1Char('/'))
name.replace(dir_separator, QLatin1Char('/'));
- bool allowUncPaths = false;
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) //allow unc paths
- allowUncPaths = true;
-#endif
-
- QString ret = qt_normalizePathSegments(name, allowUncPaths);
+ QString ret = qt_normalizePathSegments(name, OSSupportsUncPaths);
// Strip away last slash except for root directories
if (ret.length() > 1 && ret.endsWith(QLatin1Char('/'))) {