From e50c7b2e2f6e655440ff940df22c145baa2deb00 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 15 Apr 2022 00:12:22 +0100 Subject: [PATCH 1/3] Add GetDOSPath() helper to wxFileName unit test No real changes. --- tests/filename/filenametest.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/tests/filename/filenametest.cpp b/tests/filename/filenametest.cpp index 03ab862a3e..980e8fcbc1 100644 --- a/tests/filename/filenametest.cpp +++ b/tests/filename/filenametest.cpp @@ -545,15 +545,21 @@ TEST_CASE("wxFileName::ShortLongPath", "[filename]") #endif // __WINDOWS__ +// Small helper to make things slightly less verbose in the tests below. +static wxString GetDOSPath(const wxFileName& fn) +{ + return fn.GetPath(wxPATH_NO_SEPARATOR, wxPATH_DOS); +} + TEST_CASE("wxFileName::UNC", "[filename]") { wxFileName fn("//share/path/name.ext", wxPATH_DOS); CHECK( fn.GetVolume() == "\\\\share" ); - CHECK( fn.GetPath(wxPATH_NO_SEPARATOR, wxPATH_DOS) == "\\path" ); + CHECK( GetDOSPath(fn) == "\\path" ); fn.Assign("\\\\share2\\path2\\name.ext", wxPATH_DOS); CHECK( fn.GetVolume() == "\\\\share2" ); - CHECK( fn.GetPath(wxPATH_NO_SEPARATOR, wxPATH_DOS) == "\\path2" ); + CHECK( GetDOSPath(fn) == "\\path2" ); #ifdef __WINDOWS__ // Check that doubled backslashes in the beginning of the path are not @@ -574,13 +580,13 @@ TEST_CASE("wxFileName::VolumeUniqueName", "[filename]") wxFileName fn("\\\\?\\Volume{8089d7d7-d0ac-11db-9dd0-806d6172696f}\\", wxPATH_DOS); CHECK( fn.GetVolume() == "\\\\?\\Volume{8089d7d7-d0ac-11db-9dd0-806d6172696f}" ); - CHECK( fn.GetPath(wxPATH_NO_SEPARATOR, wxPATH_DOS) == "\\" ); + CHECK( GetDOSPath(fn) == "\\" ); CHECK( fn.GetFullPath(wxPATH_DOS) == "\\\\?\\Volume{8089d7d7-d0ac-11db-9dd0-806d6172696f}\\" ); fn.Assign("\\\\?\\Volume{8089d7d7-d0ac-11db-9dd0-806d6172696f}\\" "Program Files\\setup.exe", wxPATH_DOS); CHECK( fn.GetVolume() == "\\\\?\\Volume{8089d7d7-d0ac-11db-9dd0-806d6172696f}" ); - CHECK( fn.GetPath(wxPATH_NO_SEPARATOR, wxPATH_DOS) == "\\Program Files" ); + CHECK( GetDOSPath(fn) == "\\Program Files" ); CHECK( fn.GetFullPath(wxPATH_DOS) == "\\\\?\\Volume{8089d7d7-d0ac-11db-9dd0-806d6172696f}\\Program Files\\setup.exe" ); } From 35d08e6a877eac75519ca462802a04f9fe2834ad Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 14 Apr 2022 22:51:23 +0100 Subject: [PATCH 2/3] Don't corrupt UNC paths when normalizing with wxPATH_NORM_LONG After the fixes to UNC paths handling, Normalize(wxPATH_NORM_LONG) started adding an extra colon after the UNC paths. Fix this by using wxGetVolumeString() instead of constructing this thing manually and add a unit test checking for this. Closes #22275. --- src/common/filename.cpp | 3 +-- tests/filename/filenametest.cpp | 8 ++++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/common/filename.cpp b/src/common/filename.cpp index a57816daf0..3185e39cba 100644 --- a/src/common/filename.cpp +++ b/src/common/filename.cpp @@ -2240,8 +2240,7 @@ wxString wxFileName::GetLongPath() const HANDLE hFind; if ( HasVolume() ) - pathOut = GetVolume() + - GetVolumeSeparator(wxPATH_DOS) + + pathOut = wxGetVolumeString(GetVolume(), wxPATH_DOS) + GetPathSeparator(wxPATH_DOS); else pathOut.clear(); diff --git a/tests/filename/filenametest.cpp b/tests/filename/filenametest.cpp index 980e8fcbc1..4bc97850b5 100644 --- a/tests/filename/filenametest.cpp +++ b/tests/filename/filenametest.cpp @@ -561,6 +561,14 @@ TEST_CASE("wxFileName::UNC", "[filename]") CHECK( fn.GetVolume() == "\\\\share2" ); CHECK( GetDOSPath(fn) == "\\path2" ); + fn.SetPath("\\\\server\\volume\\path", wxPATH_DOS); + fn.AppendDir("subdir"); + CHECK( fn.GetFullPath(wxPATH_DOS) == "\\\\server\\volume\\path\\subdir\\name.ext" ); + + // Check for a bug with normalization breaking the path (#22275). + fn.Normalize(wxPATH_NORM_LONG); + CHECK( fn.GetFullPath(wxPATH_DOS) == "\\\\server\\volume\\path\\subdir\\name.ext" ); + #ifdef __WINDOWS__ // Check that doubled backslashes in the beginning of the path are not // misinterpreted as UNC volume when we have a drive letter in the From d6c3344c6ff124bbf2e0cd054eb050157bae4776 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 14 Apr 2022 22:52:39 +0100 Subject: [PATCH 3/3] Don't try finding the long form of non-existent paths This is at best useless and at worst harmful, as shown by the bug fixed in the previous commit, so just don't do it if GetLongPathName() has already determined that the path doesn't exist. --- src/common/filename.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/common/filename.cpp b/src/common/filename.cpp index 3185e39cba..13629a51af 100644 --- a/src/common/filename.cpp +++ b/src/common/filename.cpp @@ -2232,8 +2232,20 @@ wxString wxFileName::GetLongPath() const return pathOut; } } + else // GetLongPathName() failed. + { + // The error returned for non-existent UNC paths is different, to make + // things more interesting. + const DWORD err = ::GetLastError(); + if ( err == ERROR_FILE_NOT_FOUND || err == ERROR_BAD_NETPATH ) + { + // No need to try to do anything else, we're not going to be able + // to find a long path form of a non-existent path anyhow. + return path; + } + } - // Some other error occured. + // File exists, but some other error occurred. // We need to call FindFirstFile on each component in turn. WIN32_FIND_DATA findFileData;