From 3966b571ff54100923a479050a38ac906e0ed1e3 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Tue, 9 Jul 2019 16:50:15 +0200 Subject: [PATCH] QDir: strip Windows' long-path markers when converting from native Applications might receive paths with Windows' '\\?\' markers, which indicates a long path to Win32 APIs, when the application is opened by explorer via file association. Qt not ignoring those markers will fail to open such files. By stripping the marker in QDir::fromNativeSeparators, QFile, QFileInfo etc automatically are able to handle such paths. QDir::cleanPath is also documented to normalize separators, so it needs to be done there as well. [ChangeLog][QtCore][QDir] Remove Windows specific long path markers when handling file paths with native separators. Change-Id: I526a890614edee8c85b39fc12c98e7ddb6e0d793 Fixes: QTBUG-75117 Reviewed-by: Friedemann Kleint Reviewed-by: Oliver Wolff Reviewed-by: Edward Welbourne --- src/corelib/io/qdir.cpp | 11 +++++++++++ tests/auto/corelib/io/qdir/tst_qdir.cpp | 2 ++ 2 files changed, 13 insertions(+) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 62dae3577c..47fac66c4f 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -947,6 +947,12 @@ QString QDir::fromNativeSeparators(const QString &pathName) int i = pathName.indexOf(QLatin1Char('\\')); if (i != -1) { QString n(pathName); + if (n.startsWith(QLatin1String("\\\\?\\"))) { + n.remove(0, 4); + i = n.indexOf(QLatin1Char('\\')); + if (i == -1) + return n; + } QChar * const data = n.data(); data[i++] = QLatin1Char('/'); @@ -2339,6 +2345,11 @@ 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('/')); diff --git a/tests/auto/corelib/io/qdir/tst_qdir.cpp b/tests/auto/corelib/io/qdir/tst_qdir.cpp index 2aebc67dcf..52e7ebadb1 100644 --- a/tests/auto/corelib/io/qdir/tst_qdir.cpp +++ b/tests/auto/corelib/io/qdir/tst_qdir.cpp @@ -1268,6 +1268,7 @@ tst_QDir::cleanPath_data() QTest::newRow("drive-above-root") << "A:/.." << "A:/.."; QTest::newRow("unc-server-up") << "//server/path/.." << "//server"; QTest::newRow("unc-server-above-root") << "//server/.." << "//server/.."; + QTest::newRow("longpath") << "\\\\?\\d:\\" << "d:/"; #else QTest::newRow("data15") << "//c:/foo" << "/c:/foo"; #endif // non-windows @@ -1745,6 +1746,7 @@ void tst_QDir::nativeSeparators() QCOMPARE(QDir::toNativeSeparators(QLatin1String("\\")), QString("\\")); QCOMPARE(QDir::fromNativeSeparators(QLatin1String("/")), QString("/")); QCOMPARE(QDir::fromNativeSeparators(QLatin1String("\\")), QString("/")); + QCOMPARE(QDir::fromNativeSeparators(QLatin1String("\\\\?\\C:\\")), QString("C:/")); #else QCOMPARE(QDir::toNativeSeparators(QLatin1String("/")), QString("/")); QCOMPARE(QDir::toNativeSeparators(QLatin1String("\\")), QString("\\"));