diff options
author | Karsten Heimrich <karsten.heimrich@qt.io> | 2021-05-03 14:40:53 +0200 |
---|---|---|
committer | Karsten Heimrich <karsten.heimrich@qt.io> | 2021-05-17 20:02:32 +0200 |
commit | 9d0be7b1a920cd9d7ae949bc3dc14774a439b3d0 (patch) | |
tree | d40637b8964d60897f8344c70c460f04df816e64 /src/corelib/io | |
parent | a1ad1f35a9a2553174cb7e86762b5494622c4639 (diff) |
Fix QSaveFile and QTemporaryFile issues with windows network shares
The commit amends commit 3966b571 to take UNC prefix into account as
well. Fixes the weird file name output as reported in QTBUG-74291 and
QTBUG-83365. Replace manual separator normalizing in qt_cleanPath(),
this is another spot where UNC prefix handling needs to be applied.
Also make QTemporaryFile operate on '/' as file separators to fix
creating both file types with native path separators on network shares.
Fixes: QTBUG-74291
Fixes: QTBUG-76228
Fixes: QTBUG-83365
Change-Id: Iff8d26b994bf4194c074cd5c996cda3934297fa5
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit ec9e85656339dbc9e6918a1369c981cece7bc97d)
Diffstat (limited to 'src/corelib/io')
-rw-r--r-- | src/corelib/io/qdir.cpp | 33 | ||||
-rw-r--r-- | src/corelib/io/qfilesystementry.cpp | 6 | ||||
-rw-r--r-- | src/corelib/io/qtemporaryfile.cpp | 2 |
3 files changed, 17 insertions, 24 deletions
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 7da824d9c6..a033f89230 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -952,22 +952,29 @@ QString QDir::toNativeSeparators(const QString &pathName) QString QDir::fromNativeSeparators(const QString &pathName) { #if defined(Q_OS_WIN) - int i = pathName.indexOf(QLatin1Char('\\')); + const QChar nativeSeparator = u'\\'; + int i = pathName.indexOf(nativeSeparator); if (i != -1) { QString n(pathName); - if (n.startsWith(QLatin1String("\\\\?\\"))) { - n.remove(0, 4); - i = n.indexOf(QLatin1Char('\\')); - if (i == -1) + 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++] = QLatin1Char('/'); + data[i++] = u'/'; for (; i < n.length(); ++i) { - if (data[i] == QLatin1Char('\\')) - data[i] = QLatin1Char('/'); + if (data[i] == nativeSeparator) + data[i] = u'/'; } return n; @@ -2312,16 +2319,8 @@ static QString qt_cleanPath(const QString &path, bool *ok) { if (path.isEmpty()) return path; - QString name = path; -#if defined (Q_OS_WIN) - if (name.startsWith(QLatin1String("\\\\?\\"))) - name.remove(0, 4); -#endif - - QChar dir_separator = QDir::separator(); - if (dir_separator != QLatin1Char('/')) - name.replace(dir_separator, QLatin1Char('/')); + QString name = QDir::fromNativeSeparators(path); QString ret = qt_normalizePathSegments(name, OSSupportsUncPaths ? QDirPrivate::AllowUncPaths : QDirPrivate::DefaultNormalization, ok); // Strip away last slash except for root directories diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp index 9b474b25b1..83f8a86439 100644 --- a/src/corelib/io/qfilesystementry.cpp +++ b/src/corelib/io/qfilesystementry.cpp @@ -142,12 +142,6 @@ void QFileSystemEntry::resolveFilePath() const if (m_filePath.isEmpty() && !m_nativeFilePath.isEmpty()) { #if defined(QFILESYSTEMENTRY_NATIVE_PATH_IS_UTF16) m_filePath = QDir::fromNativeSeparators(m_nativeFilePath); -#ifdef Q_OS_WIN - if (m_filePath.startsWith(QLatin1String("//?/UNC/"))) - m_filePath = m_filePath.remove(2,6); - if (m_filePath.startsWith(QLatin1String("//?/"))) - m_filePath = m_filePath.remove(0,4); -#endif #else m_filePath = QDir::fromNativeSeparators(QFile::decodeName(m_nativeFilePath)); #endif diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index bdd128a88c..1e7e67b625 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -78,7 +78,7 @@ typedef int NativeFileHandle; QTemporaryFileName::QTemporaryFileName(const QString &templateName) { // Ensure there is a placeholder mask - QString qfilename = templateName; + QString qfilename = QDir::fromNativeSeparators(templateName); uint phPos = qfilename.length(); uint phLength = 0; |