authorgravatar for johnnymarler@gmail.comJonathan Marler <johnnymarler@gmail.com> 2021-05-20 23:23:10-06:00
committergravatar for johnnymarler@gmail.comJonathan Marler <johnnymarler@gmail.com> 2021-05-21 01:29:40-06:00
logb0116afd8adbc73d820fee418ec74104f43bff6e
tree4df1fb91ca3f5a3709042edc75e6f309b387b895
parent59de5d0350f76933549e5402f090785351d9498d

handle relative paths with too many ".."


5 files changed, 36 insertions(+), 7 deletions(-)

lib/std/fs/test.zig+2-2
......@@ -95,8 +95,8 @@ test "openDirAbsolute" {
9595test "openDir cwd parent .." {
9696 if (builtin.os.tag == .wasi) return error.SkipZigTest;
9797
98 var cwd = try fs.cwd().openDir("..", .{});
99 defer cwd.close();
98 var dir = try fs.cwd().openDir("..", .{});
99 defer dir.close();
100100}
101101
102102test "readLinkAbsolute" {
lib/std/mem.zig+1-1
......@@ -2151,7 +2151,7 @@ pub fn collapseRepeats(comptime T: type, slice: []T, elem: T) []T {
21512151fn testCollapseRepeats(str: []const u8, elem: u8, expected: []const u8) !void {
21522152 const mutable = try std.testing.allocator.dupe(u8, str);
21532153 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));
21552155}
21562156test "collapseRepeats" {
21572157 try testCollapseRepeats("", '/', "");
lib/std/os/windows.zig+24-2
......@@ -1817,20 +1817,42 @@ pub fn sliceToPrefixedFileW(s: []const u8) !PathSpace {
18171817 else => {},
18181818 }
18191819 }
1820 const prefix_u16 = [_]u16{ '\\', '?', '?', '\\' };
18201821 const start_index = if (prefix_index > 0 or !std.fs.path.isAbsolute(s)) 0 else blk: {
1821 const prefix_u16 = [_]u16{ '\\', '?', '?', '\\' };
18221822 mem.copy(u16, path_space.data[0..], prefix_u16[0..]);
18231823 break :blk prefix_u16.len;
18241824 };
18251825 path_space.len = start_index + try std.unicode.utf8ToUtf16Le(path_space.data[start_index..], s);
18261826 if (path_space.len > path_space.data.len) return error.NameTooLong;
18271827 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 },
18291841 });
18301842 path_space.data[path_space.len] = 0;
18311843 return path_space;
18321844}
18331845
1846fn 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
18341856/// Assumes an absolute path.
18351857pub fn wToPrefixedFileW(s: []const u16) !PathSpace {
18361858 // TODO https://github.com/ziglang/zig/issues/2765
lib/std/os/windows/kernel32.zig+7
......@@ -136,6 +136,13 @@ pub extern "kernel32" fn GetFinalPathNameByHandleW(
136136 dwFlags: DWORD,
137137) callconv(WINAPI) DWORD;
138138
139pub 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
139146pub extern "kernel32" fn GetOverlappedResult(hFile: HANDLE, lpOverlapped: *OVERLAPPED, lpNumberOfBytesTransferred: *DWORD, bWait: BOOL) callconv(WINAPI) BOOL;
140147
141148pub 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 {
1414 const mutable = try testing.allocator.dupe(u8, str);
1515 defer testing.allocator.free(mutable);
1616 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));
1818}
1919fn testRemoveDotDirsError(err: anyerror, str: []const u8) !void {
2020 const mutable = try testing.allocator.dupe(u8, str);
2121 defer testing.allocator.free(mutable);
22 testing.expectError(err, windows.removeDotDirsSanitized(u8, mutable));
22 try testing.expectError(err, windows.removeDotDirsSanitized(u8, mutable));
2323}
2424test "removeDotDirs" {
2525 try testRemoveDotDirs("", "");