summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/io/qdir.cpp33
-rw-r--r--src/corelib/io/qfilesystementry.cpp6
-rw-r--r--src/corelib/io/qtemporaryfile.cpp2
-rw-r--r--tests/auto/corelib/io/qdir/tst_qdir.cpp4
-rw-r--r--tests/auto/corelib/io/qfilesystementry/tst_qfilesystementry.cpp13
-rw-r--r--tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp6
-rw-r--r--tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp6
7 files changed, 45 insertions, 25 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;
diff --git a/tests/auto/corelib/io/qdir/tst_qdir.cpp b/tests/auto/corelib/io/qdir/tst_qdir.cpp
index 304020d1f3..ca6c650d7c 100644
--- a/tests/auto/corelib/io/qdir/tst_qdir.cpp
+++ b/tests/auto/corelib/io/qdir/tst_qdir.cpp
@@ -1267,6 +1267,8 @@ tst_QDir::cleanPath_data()
QTest::newRow("unc-server-up") << "//server/path/.." << "//server";
QTest::newRow("unc-server-above-root") << "//server/.." << "//server/..";
QTest::newRow("longpath") << "\\\\?\\d:\\" << "d:/";
+ QTest::newRow("unc-network-share") << "\\\\?\\UNC\\localhost\\c$\\tmp.txt"
+ << "//localhost/c$/tmp.txt";
#else
QTest::newRow("data15") << "//c:/foo" << "/c:/foo";
#endif // non-windows
@@ -1742,6 +1744,8 @@ void tst_QDir::nativeSeparators()
QCOMPARE(QDir::fromNativeSeparators(QLatin1String("/")), QString("/"));
QCOMPARE(QDir::fromNativeSeparators(QLatin1String("\\")), QString("/"));
QCOMPARE(QDir::fromNativeSeparators(QLatin1String("\\\\?\\C:\\")), QString("C:/"));
+ QCOMPARE(QDir::fromNativeSeparators(QLatin1String(R"(\\?\UNC\localhost\c$\tmp.txt)")),
+ QString("//localhost/c$/tmp.txt"));
#else
QCOMPARE(QDir::toNativeSeparators(QLatin1String("/")), QString("/"));
QCOMPARE(QDir::toNativeSeparators(QLatin1String("\\")), QString("\\"));
diff --git a/tests/auto/corelib/io/qfilesystementry/tst_qfilesystementry.cpp b/tests/auto/corelib/io/qfilesystementry/tst_qfilesystementry.cpp
index aed4895a47..b542aea60a 100644
--- a/tests/auto/corelib/io/qfilesystementry/tst_qfilesystementry.cpp
+++ b/tests/auto/corelib/io/qfilesystementry/tst_qfilesystementry.cpp
@@ -104,6 +104,17 @@ void tst_QFileSystemEntry::getSetCheck_data()
<< QString("A:dir\\without\\leading\\backslash.bat")
<< absPrefix + QString("A:\\dir\\without\\leading\\backslash.bat")
<< "A:dir/without/leading/backslash.bat" << "backslash.bat" << "backslash" << "backslash" << "bat" << "bat" << false << false;
+
+ QTest::newRow("longpath")
+ << QString("\\\\?\\D:\\")
+ << absPrefix + QString("D:\\")
+ << "D:/" << "" << "" << "" << "" << "" << true << false;
+
+ QTest::newRow("uncprefix")
+ << QString("\\\\?\\UNC\\localhost\\C$\\tmp.txt")
+ << absPrefix + QString("UNC\\localhost\\C$\\tmp.txt")
+ << "//localhost/C$/tmp.txt" << "tmp.txt" << "tmp" << "tmp" << "txt" << "txt" << true
+ << false;
}
void tst_QFileSystemEntry::getSetCheck()
@@ -137,7 +148,7 @@ void tst_QFileSystemEntry::getSetCheck()
QCOMPARE(entry2.isRelative(), relative);
QCOMPARE(entry2.filePath(), filepath);
// Since this entry was created using the native path,
- // the object shouldnot change nativeFilePath.
+ // the object shouldn't change nativeFilePath.
QCOMPARE(entry2.nativeFilePath(), nativeFilePath);
QCOMPARE(entry2.fileName(), filename);
QCOMPARE(entry2.baseName(), baseName);
diff --git a/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp b/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp
index 40582eba1b..395cd9458c 100644
--- a/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp
+++ b/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp
@@ -157,6 +157,12 @@ void tst_QTemporaryDir::fileTemplate_data()
prefix = "qt_" + hanTestText();
QTest::newRow("Chinese") << (prefix + "XXXXXX" + umlautTestText()) << prefix << umlautTestText();
}
+
+#ifdef Q_OS_WIN
+ const auto tmp = QDir::toNativeSeparators(QDir::tempPath()).sliced(QDir::rootPath().size());
+ QTest::newRow("UNC") << "\\\\localhost\\C$\\" + tmp + "\\UNC.XXXXXX.tmpDir"
+ << "UNC." << ".tmpDir";
+#endif
}
void tst_QTemporaryDir::fileTemplate()
diff --git a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp
index ef04bfdd2b..4896463ac2 100644
--- a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp
+++ b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp
@@ -201,6 +201,12 @@ void tst_QTemporaryFile::fileTemplate_data()
prefix = "qt_" + hanTestText();
QTest::newRow("Chinese characters") << (prefix + "XXXXXX") << prefix << QString() << QString();
}
+
+#ifdef Q_OS_WIN
+ const auto tmp = QDir::toNativeSeparators(QDir::tempPath()).sliced(QDir::rootPath().size());
+ QTest::newRow("UNC") << "\\\\localhost\\C$\\" + tmp + "\\QTBUG-74291.XXXXXX.tmpFile"
+ << "QTBUG-74291." << ".tmpFile" << "";
+#endif
}
void tst_QTemporaryFile::fileTemplate()