diff options
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/io/qdir.cpp | 31 | ||||
-rw-r--r-- | src/corelib/io/qfilesystemengine_win.cpp | 14 | ||||
-rw-r--r-- | src/corelib/io/qfilesystementry.cpp | 28 | ||||
-rw-r--r-- | src/corelib/io/qfilesystementry_p.h | 1 |
4 files changed, 34 insertions, 40 deletions
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index c4dbd27aa1..e92d2f9ca7 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -953,35 +953,10 @@ QString QDir::toNativeSeparators(const QString &pathName) QString QDir::fromNativeSeparators(const QString &pathName) { #if defined(Q_OS_WIN) - const QChar nativeSeparator = u'\\'; - int i = pathName.indexOf(nativeSeparator); - if (i != -1) { - QString n(pathName); - const QStringView uncPrefix(uR"(\\?\UNC\)"); - const QStringView extendedLengthPathPrefix(uR"(\\?\)"); - if (n.startsWith(uncPrefix)) { - // Keep the initial double-slash, chop out the rest of the prefix. - n = n.remove(2, uncPrefix.size() - 2); - if ((i = n.indexOf(nativeSeparator)) == -1) - return n; - } else if (n.startsWith(extendedLengthPathPrefix)) { - n = n.sliced(extendedLengthPathPrefix.size()); - if ((i = n.indexOf(nativeSeparator)) == -1) - return n; - } - - QChar * const data = n.data(); - data[i++] = u'/'; - - for (; i < n.length(); ++i) { - if (data[i] == nativeSeparator) - data[i] = u'/'; - } - - return n; - } -#endif + return QFileSystemEntry::removeUncOrLongPathPrefix(pathName).replace(u'\\', u'/'); +#else return pathName; +#endif } static QString qt_cleanPath(const QString &path, bool *ok = nullptr); diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 6c4418a83b..d587e2bfd0 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -297,18 +297,8 @@ static QString readSymLink(const QFileSystemEntry &link) const wchar_t* PathBuffer = &rdb->SymbolicLinkReparseBuffer.PathBuffer[offset]; result = QString::fromWCharArray(PathBuffer, length); } - // cut-off "\\?\" and "\??\" - if (result.size() > 4 - && result.at(0) == QLatin1Char('\\') - && result.at(2) == QLatin1Char('?') - && result.at(3) == QLatin1Char('\\')) { - result = result.mid(4); - // cut off UNC in addition when the link points at a UNC share - // in which case we need to prepend another backslash to get \\server\share - if (QStringView{result}.left(3) == QLatin1String("UNC")) { - result.replace(0, 3, QLatin1Char('\\')); - } - } + // remove "\\?\", "\??\" or "\\?\UNC\" + result = QFileSystemEntry::removeUncOrLongPathPrefix(result); } free(rdb); CloseHandle(handle); diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp index c061f58e87..bb39a46642 100644 --- a/src/corelib/io/qfilesystementry.cpp +++ b/src/corelib/io/qfilesystementry.cpp @@ -288,6 +288,34 @@ bool QFileSystemEntry::isDriveRootPath(const QString &path) && path.at(0).isLetter() && path.at(1) == QLatin1Char(':') && path.at(2) == QLatin1Char('/')); } + +QString QFileSystemEntry::removeUncOrLongPathPrefix(QString path) +{ + constexpr qsizetype minPrefixSize = 4; + if (path.size() < minPrefixSize) + return path; + + auto data = path.data(); + const auto slash = path[0]; + if (slash != u'\\' && slash != u'/') + return path; + + // check for "//?/" or "/??/" + if (data[2] == u'?' && data[3] == slash && (data[1] == slash || data[1] == u'?')) { + path = path.sliced(minPrefixSize); + + // check for a possible "UNC/" prefix left-over + if (path.size() >= 4) { + data = path.data(); + if (data[0] == u'U' && data[1] == u'N' && data[2] == u'C' && data[3] == slash) { + data[2] = slash; + return path.sliced(2); + } + } + } + + return path; +} #endif // Q_OS_WIN bool QFileSystemEntry::isRootPath(const QString &path) diff --git a/src/corelib/io/qfilesystementry_p.h b/src/corelib/io/qfilesystementry_p.h index d6b1abf498..ba0c7812e9 100644 --- a/src/corelib/io/qfilesystementry_p.h +++ b/src/corelib/io/qfilesystementry_p.h @@ -91,6 +91,7 @@ public: #if defined(Q_OS_WIN) bool isDriveRoot() const; static bool isDriveRootPath(const QString &path); + static QString removeUncOrLongPathPrefix(QString path); #endif bool isRoot() const; |