diff options
| author | Jeroen van Rijn <Kelimion@users.noreply.github.com> | 2025-05-11 15:35:52 +0200 |
|---|---|---|
| committer | Jeroen van Rijn <Kelimion@users.noreply.github.com> | 2025-05-11 15:35:52 +0200 |
| commit | 30388cada3d2bee633285516344d8d5a88308eb0 (patch) | |
| tree | adb48b3c5e50b22d9d4025235058782cd96b9f94 /core/os | |
| parent | ecd0655ba253397de9aabc5b1010f4999d7805e6 (diff) | |
Fix os2.clean_path on Windows
Diffstat (limited to 'core/os')
| -rw-r--r-- | core/os/os2/path_windows.odin | 6 | ||||
| -rw-r--r-- | core/os/os2/stat_windows.odin | 80 |
2 files changed, 58 insertions, 28 deletions
diff --git a/core/os/os2/path_windows.odin b/core/os/os2/path_windows.odin index 9c0fec9b9..c2e51040f 100644 --- a/core/os/os2/path_windows.odin +++ b/core/os/os2/path_windows.odin @@ -187,7 +187,6 @@ init_long_path_support :: proc() { if value == 1 { can_use_long_paths = true } - } @(require_results) @@ -271,6 +270,11 @@ _clean_path_handle_start :: proc(path: string, buffer: []u8) -> (rooted: bool, s start += 1 } copy(buffer, path[:start]) + for n in 0..<start { + if _is_path_separator(buffer[n]) { + buffer[n] = _Path_Separator + } + } } return } diff --git a/core/os/os2/stat_windows.odin b/core/os/os2/stat_windows.odin index 918c86f76..af84e1443 100644 --- a/core/os/os2/stat_windows.odin +++ b/core/os/os2/stat_windows.odin @@ -329,42 +329,68 @@ _is_reserved_name :: proc(path: string) -> bool { return false } -_is_UNC :: proc(path: string) -> bool { - return _volume_name_len(path) > 2 -} - -_volume_name_len :: proc(path: string) -> int { +_volume_name_len :: proc(path: string) -> (length: int) { if len(path) < 2 { return 0 } - c := path[0] + if path[1] == ':' { - switch c { + switch path[0] { case 'a'..='z', 'A'..='Z': return 2 } } - // URL: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx - if l := len(path); l >= 5 && _is_path_separator(path[0]) && _is_path_separator(path[1]) && - !_is_path_separator(path[2]) && path[2] != '.' { - for n := 3; n < l-1; n += 1 { - if _is_path_separator(path[n]) { - n += 1 - if !_is_path_separator(path[n]) { - if path[n] == '.' { - break - } - } - for ; n < l; n += 1 { - if _is_path_separator(path[n]) { - break - } - } - return n + /* + See: URL: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx + Further allowed paths can be of the form of: + - \\server\share or \\server\share\more\path + - \\?\C:\... + - \\.\PhysicalDriveX + */ + // Any remaining kind of path has to start with two slashes. + if !_is_path_separator(path[0]) || !_is_path_separator(path[1]) { + return 0 + } + + // Device path. The volume name is the whole string + if len(path) >= 5 && path[2] == '.' && _is_path_separator(path[3]) { + return len(path) + } + + // We're a UNC share `\\host\share`, file namespace `\\?\C:` or UNC in file namespace `\\?\\host\share` + prefix := 2 + + // File namespace. + if len(path) >= 5 && path[2] == '?' && _is_path_separator(path[3]) { + if _is_path_separator(path[4]) { + // `\\?\\` UNC path in file namespace + prefix = 5 + } + + if len(path) >= 6 && path[5] == ':' { + switch path[4] { + case 'a'..='z', 'A'..='Z': + return 6 + case: + return 0 } - break } } - return 0 -} + + // UNC path, minimum version of the volume is `\\h\s` for host, share. + // Can also contain an IP address in the host position. + slash_count := 0 + for i in prefix..<len(path) { + // Host needs to be at least 1 character + if _is_path_separator(path[i]) && i > 0 { + slash_count += 1 + + if slash_count == 2 { + return i + } + } + } + + return len(path) +}
\ No newline at end of file |