| author | |
| committer | |
| log | b0116afd8adbc73d820fee418ec74104f43bff6e |
| tree | 4df1fb91ca3f5a3709042edc75e6f309b387b895 |
| parent | 59de5d0350f76933549e5402f090785351d9498d |
5 files changed, 36 insertions(+), 7 deletions(-)
lib/std/fs/test.zig+2-2| ... | @@ -95,8 +95,8 @@ test "openDirAbsolute" { | ... | @@ -95,8 +95,8 @@ test "openDirAbsolute" { |
| 95 | test "openDir cwd parent .." { | 95 | test "openDir cwd parent .." { |
| 96 | if (builtin.os.tag == .wasi) return error.SkipZigTest; | 96 | if (builtin.os.tag == .wasi) return error.SkipZigTest; |
| 97 | 97 | ||
| 98 | var cwd = try fs.cwd().openDir("..", .{}); | 98 | var dir = try fs.cwd().openDir("..", .{}); |
| 99 | defer cwd.close(); | 99 | defer dir.close(); |
| 100 | } | 100 | } |
| 101 | 101 | ||
| 102 | test "readLinkAbsolute" { | 102 | test "readLinkAbsolute" { |
lib/std/mem.zig+1-1| ... | @@ -2151,7 +2151,7 @@ pub fn collapseRepeats(comptime T: type, slice: []T, elem: T) []T { | ... | @@ -2151,7 +2151,7 @@ pub fn collapseRepeats(comptime T: type, slice: []T, elem: T) []T { |
| 2151 | fn testCollapseRepeats(str: []const u8, elem: u8, expected: []const u8) !void { | 2151 | fn testCollapseRepeats(str: []const u8, elem: u8, expected: []const u8) !void { |
| 2152 | const mutable = try std.testing.allocator.dupe(u8, str); | 2152 | const mutable = try std.testing.allocator.dupe(u8, str); |
| 2153 | defer std.testing.allocator.free(mutable); | 2153 | defer std.testing.allocator.free(mutable); |
| 2154 | testing.expect(std.mem.eql(u8, collapseRepeats(u8, mutable, elem), expected)); | 2154 | try testing.expect(std.mem.eql(u8, collapseRepeats(u8, mutable, elem), expected)); |
| 2155 | } | 2155 | } |
| 2156 | test "collapseRepeats" { | 2156 | test "collapseRepeats" { |
| 2157 | try testCollapseRepeats("", '/', ""); | 2157 | try testCollapseRepeats("", '/', ""); |
lib/std/os/windows.zig+24-2| ... | @@ -1817,20 +1817,42 @@ pub fn sliceToPrefixedFileW(s: []const u8) !PathSpace { | ... | @@ -1817,20 +1817,42 @@ pub fn sliceToPrefixedFileW(s: []const u8) !PathSpace { |
| 1817 | else => {}, | 1817 | else => {}, |
| 1818 | } | 1818 | } |
| 1819 | } | 1819 | } |
| 1820 | const prefix_u16 = [_]u16{ '\\', '?', '?', '\\' }; | ||
| 1820 | const start_index = if (prefix_index > 0 or !std.fs.path.isAbsolute(s)) 0 else blk: { | 1821 | const start_index = if (prefix_index > 0 or !std.fs.path.isAbsolute(s)) 0 else blk: { |
| 1821 | const prefix_u16 = [_]u16{ '\\', '?', '?', '\\' }; | ||
| 1822 | mem.copy(u16, path_space.data[0..], prefix_u16[0..]); | 1822 | mem.copy(u16, path_space.data[0..], prefix_u16[0..]); |
| 1823 | break :blk prefix_u16.len; | 1823 | break :blk prefix_u16.len; |
| 1824 | }; | 1824 | }; |
| 1825 | path_space.len = start_index + try std.unicode.utf8ToUtf16Le(path_space.data[start_index..], s); | 1825 | path_space.len = start_index + try std.unicode.utf8ToUtf16Le(path_space.data[start_index..], s); |
| 1826 | if (path_space.len > path_space.data.len) return error.NameTooLong; | 1826 | if (path_space.len > path_space.data.len) return error.NameTooLong; |
| 1827 | path_space.len = start_index + (normalizePath(u16, path_space.data[start_index..path_space.len]) catch |err| switch (err) { | 1827 | path_space.len = start_index + (normalizePath(u16, path_space.data[start_index..path_space.len]) catch |err| switch (err) { |
| 1828 | error.TooManyParentDirs => return error.BadPathName, | 1828 | error.TooManyParentDirs => { |
| 1829 | if (!std.fs.path.isAbsolute(s)) { | ||
| 1830 | var temp_path: PathSpace = undefined; | ||
| 1831 | temp_path.len = try std.unicode.utf8ToUtf16Le(&temp_path.data, s); | ||
| 1832 | std.debug.assert(temp_path.len == path_space.len); | ||
| 1833 | temp_path.data[path_space.len] = 0; | ||
| 1834 | path_space.len = prefix_u16.len + try getFullPathNameW(&temp_path.data, path_space.data[prefix_u16.len..]); | ||
| 1835 | mem.copy(u16, &path_space.data, &prefix_u16); | ||
| 1836 | std.debug.assert(path_space.data[path_space.len] == 0); | ||
| 1837 | return path_space; | ||
| 1838 | } | ||
| 1839 | return error.BadPathName; | ||
| 1840 | }, | ||
| 1829 | }); | 1841 | }); |
| 1830 | path_space.data[path_space.len] = 0; | 1842 | path_space.data[path_space.len] = 0; |
| 1831 | return path_space; | 1843 | return path_space; |
| 1832 | } | 1844 | } |
| 1833 | 1845 | ||
| 1846 | fn getFullPathNameW(path: [*:0]const u16, out: []u16) !usize { | ||
| 1847 | const result= kernel32.GetFullPathNameW(path, @intCast(u32, out.len), std.meta.assumeSentinel(out.ptr, 0), null); | ||
| 1848 | if (result == 0) { | ||
| 1849 | switch (kernel32.GetLastError()) { | ||
| 1850 | else => |err| return unexpectedError(err), | ||
| 1851 | } | ||
| 1852 | } | ||
| 1853 | return result; | ||
| 1854 | } | ||
| 1855 | |||
| 1834 | /// Assumes an absolute path. | 1856 | /// Assumes an absolute path. |
| 1835 | pub fn wToPrefixedFileW(s: []const u16) !PathSpace { | 1857 | pub fn wToPrefixedFileW(s: []const u16) !PathSpace { |
| 1836 | // TODO https://github.com/ziglang/zig/issues/2765 | 1858 | // TODO https://github.com/ziglang/zig/issues/2765 |
lib/std/os/windows/kernel32.zig+7| ... | @@ -136,6 +136,13 @@ pub extern "kernel32" fn GetFinalPathNameByHandleW( | ... | @@ -136,6 +136,13 @@ pub extern "kernel32" fn GetFinalPathNameByHandleW( |
| 136 | dwFlags: DWORD, | 136 | dwFlags: DWORD, |
| 137 | ) callconv(WINAPI) DWORD; | 137 | ) callconv(WINAPI) DWORD; |
| 138 | 138 | ||
| 139 | pub extern "kernel32" fn GetFullPathNameW( | ||
| 140 | lpFileName: [*:0]const u16, | ||
| 141 | nBufferLength: u32, | ||
| 142 | lpBuffer: ?[*:0]u16, | ||
| 143 | lpFilePart: ?*?[*:0]u16, | ||
| 144 | ) callconv(@import("std").os.windows.WINAPI) u32; | ||
| 145 | |||
| 139 | pub extern "kernel32" fn GetOverlappedResult(hFile: HANDLE, lpOverlapped: *OVERLAPPED, lpNumberOfBytesTransferred: *DWORD, bWait: BOOL) callconv(WINAPI) BOOL; | 146 | pub extern "kernel32" fn GetOverlappedResult(hFile: HANDLE, lpOverlapped: *OVERLAPPED, lpNumberOfBytesTransferred: *DWORD, bWait: BOOL) callconv(WINAPI) BOOL; |
| 140 | 147 | ||
| 141 | pub extern "kernel32" fn GetProcessHeap() callconv(WINAPI) ?HANDLE; | 148 | pub extern "kernel32" fn GetProcessHeap() callconv(WINAPI) ?HANDLE; |
lib/std/os/windows/test.zig+2-2| ... | @@ -14,12 +14,12 @@ fn testRemoveDotDirs(str: []const u8, expected: []const u8) !void { | ... | @@ -14,12 +14,12 @@ fn testRemoveDotDirs(str: []const u8, expected: []const u8) !void { |
| 14 | const mutable = try testing.allocator.dupe(u8, str); | 14 | const mutable = try testing.allocator.dupe(u8, str); |
| 15 | defer testing.allocator.free(mutable); | 15 | defer testing.allocator.free(mutable); |
| 16 | const actual = mutable[0..try windows.removeDotDirsSanitized(u8, mutable)]; | 16 | const actual = mutable[0..try windows.removeDotDirsSanitized(u8, mutable)]; |
| 17 | testing.expect(mem.eql(u8, actual, expected)); | 17 | try testing.expect(mem.eql(u8, actual, expected)); |
| 18 | } | 18 | } |
| 19 | fn testRemoveDotDirsError(err: anyerror, str: []const u8) !void { | 19 | fn testRemoveDotDirsError(err: anyerror, str: []const u8) !void { |
| 20 | const mutable = try testing.allocator.dupe(u8, str); | 20 | const mutable = try testing.allocator.dupe(u8, str); |
| 21 | defer testing.allocator.free(mutable); | 21 | defer testing.allocator.free(mutable); |
| 22 | testing.expectError(err, windows.removeDotDirsSanitized(u8, mutable)); | 22 | try testing.expectError(err, windows.removeDotDirsSanitized(u8, mutable)); |
| 23 | } | 23 | } |
| 24 | test "removeDotDirs" { | 24 | test "removeDotDirs" { |
| 25 | try testRemoveDotDirs("", ""); | 25 | try testRemoveDotDirs("", ""); |