Windows supports (since Vista) creating symbolic link from local filesystem to network share. QDir::canonicalPath() fails to provide correct path for this.
I created a test application:
#include <QtCore>
inline QTextStream& qStdout() {
static QTextStream s(stdout);
return s;
}
int main(int argc, char *argv[]) {
QDir cd(QDir::current());
qStdout() << "current : " << cd.path() << endl;
qStdout() << "absolute : " << cd.absolutePath() << endl;
qStdout() << "canonical : " << cd.canonicalPath() << endl;
return 0;
}
Then I created a symbolic link to network share:
C:\test>mklink /d temp \\helfile01\temp symbolic link created for temp <<===>> \\helfile01\temp
This is the output of the program compiled with Qt 5.4.2:
C:\test\temp>test.exe current : C:/test/temp absolute : C:/test/temp canonical : C:/test/UNC/helfile01/temp
As you can see, the symbolic link is resolved incorrectly and then used as relative path and appended to the canonical path.
With my fix, this is the output:
C:\test\temp>test.exe current : C:/test/temp absolute : C:/test/temp canonical : //helfile01/temp
Here is the patch:
--- a/qtbase/src/corelib/io/qfilesystemengine_win.cpp
+++ b/qtbase/src/corelib/io/qfilesystemengine_win.cpp
@@ -338,8 +338,12 @@ static QString readSymLink(const QFileSystemEntry &link)
result = QString::fromWCharArray(PathBuffer, length);
}
// cut-off "//?/" and "/??/"
- if (result.size() > 4 && result.at(0) == QLatin1Char('\\') && result.at(2) == QLatin1Char('?') && result.at(3) == QLatin1Char('\\'))
+ if (result.size() > 4 && result.at(0) == QLatin1Char('\\') && result.at(2) == QLatin1Char('?') && result.at(3) == QLatin1Char('\\')) {
result = result.mid(4);
+ // "//?/UNC/server/share" -> "//server/share"
+ if (result.size() > 3 && result.at(0) == QLatin1Char('U') && result.at(1) == QLatin1Char('N') && result.at(2) == QLatin1Char('C'))
+ result.replace(0, 3, QLatin1Char('\\'));
+ }
}
free(rdb);
CloseHandle(handle);
- tests
-
QTBUG-73688 Qt doesn't treat UNC paths and NTFS symbolic links correctly
-
- Closed
-