Mercurial > octave
changeset 31185:84df79fb637d stable
canonicalize_file_name: Generalize check for mapped network drive (bug #62847).
* liboctave/system/file-ops.cc (canonicalize_file_name): Any directory on a
share (or the share itself) can be mapped to a drive letter on Windows.
Generalize checks when replacing mapped root with drive letter.
author | Markus Mützel <markus.muetzel@gmx.de> |
---|---|
date | Fri, 12 Aug 2022 15:56:50 +0200 |
parents | e217b44187a2 |
children | 07e3911e24c2 820d2c802247 |
files | liboctave/system/file-ops.cc |
diffstat | 1 files changed, 36 insertions(+), 49 deletions(-) [+] |
line wrap: on
line diff
--- a/liboctave/system/file-ops.cc Thu Aug 11 09:36:52 2022 +0200 +++ b/liboctave/system/file-ops.cc Fri Aug 12 15:56:50 2022 +0200 @@ -749,59 +749,46 @@ retval = retval.erase (2, 6); // If the initial path looked like a mapped network drive, replace - // "\\server\share" portion of path with drive root. - if (name[1] == ':') - { - // Find where "share" portion of UNC path ends. - std::size_t sep_pos - = retval.find_first_of (file_ops::dir_sep_chars (), 2); - if (sep_pos != std::string::npos) - sep_pos = retval.find_first_of (file_ops::dir_sep_chars (), - sep_pos + 1); + // portion of path that corresponds to mapped root with drive root. + if (name.size () < 2 || name[1] != ':') + return retval; - // Check if original drive letter was a map to this UNC share. - std::wstring orig_map = wname.substr (0, 2); - HANDLE h_map = CreateFileW (orig_map.c_str (), GENERIC_READ, - FILE_SHARE_READ, nullptr, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS - | FILE_FLAG_OPEN_REPARSE_POINT, - nullptr); - if (h_file != INVALID_HANDLE_VALUE) - { - unwind_action close_map_handle (CloseHandle, h_map); - len = GetFinalPathNameByHandleW (h_map, buffer, buf_size, - FILE_NAME_NORMALIZED); + // UNC path corresponding to original drive letter (mappped drive) + std::wstring orig_map = wname.substr (0, 2); + HANDLE h_map = CreateFileW (orig_map.c_str (), GENERIC_READ, + FILE_SHARE_READ, nullptr, OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS + | FILE_FLAG_OPEN_REPARSE_POINT, + nullptr); - std::string orig_dest - = u8_from_wstring (std::wstring (buffer, len)); + if (h_map == INVALID_HANDLE_VALUE) + // cannot determine common root + return retval; + + unwind_action close_map_handle (CloseHandle, h_map); + len = GetFinalPathNameByHandleW (h_map, buffer, buf_size, + FILE_NAME_NORMALIZED); - if (orig_dest.compare (0, 8, R"(\\?\UNC\)") == 0) - { - orig_dest = orig_dest.erase (2, 6); - // Find where "share" portion of UNC path ends. - std::size_t sep_pos_orig - = orig_dest.find_first_of (file_ops::dir_sep_chars (), - 2); - if (sep_pos_orig != std::string::npos) - sep_pos_orig - = retval.find_first_of (file_ops::dir_sep_chars (), - sep_pos_orig + 1); - if (retval.substr (0, sep_pos) - .compare (orig_dest.substr (0, sep_pos_orig))) - // share doesn't match mapped drive - return retval; - } - } + std::string orig_root + = u8_from_wstring (std::wstring (buffer, len)); + + if (orig_root.compare (0, 8, R"(\\?\UNC\)")) + // root was not a mapped share + return retval; - // File is on mapped share. - if (sep_pos != std::string::npos) - retval = retval.substr (sep_pos-2); - else - retval.resize (2); // no file component - retval[0] = std::toupper (name[0]); - retval[1] = ':'; - } + orig_root = orig_root.erase (2, 6); + if (retval.compare (0, orig_root.size (), orig_root)) + // start of UNC path doesn't match mapped drive root + return retval; + + // file is on mapped share + size_t sep_pos = orig_root.size (); + if (sep_pos != retval.size ()) + retval = retval.substr (sep_pos-2); + else + retval.resize (2); // no file component + retval[0] = std::toupper (name[0]); + retval[1] = ':'; } else if (retval.compare (0, 4, R"(\\?\)") == 0) retval = retval.erase (0, 4);