Skip to content

Commit b0116af

Browse files
committed
handle relative paths with too many ".."
1 parent 59de5d0 commit b0116af

File tree

5 files changed

+36
-7
lines changed

5 files changed

+36
-7
lines changed

lib/std/fs/test.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ test "openDirAbsolute" {
9595
test "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

102102
test "readLinkAbsolute" {

lib/std/mem.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2151,7 +2151,7 @@ pub fn collapseRepeats(comptime T: type, slice: []T, elem: T) []T {
21512151
fn 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
}
21562156
test "collapseRepeats" {
21572157
try testCollapseRepeats("", '/', "");

lib/std/os/windows.zig

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

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+
18341856
/// Assumes an absolute path.
18351857
pub fn wToPrefixedFileW(s: []const u16) !PathSpace {
18361858
// TODO https://github.com/ziglang/zig/issues/2765

lib/std/os/windows/kernel32.zig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,13 @@ pub extern "kernel32" fn GetFinalPathNameByHandleW(
136136
dwFlags: DWORD,
137137
) callconv(WINAPI) DWORD;
138138

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+
139146
pub extern "kernel32" fn GetOverlappedResult(hFile: HANDLE, lpOverlapped: *OVERLAPPED, lpNumberOfBytesTransferred: *DWORD, bWait: BOOL) callconv(WINAPI) BOOL;
140147

141148
pub extern "kernel32" fn GetProcessHeap() callconv(WINAPI) ?HANDLE;

lib/std/os/windows/test.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}
1919
fn 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
}
2424
test "removeDotDirs" {
2525
try testRemoveDotDirs("", "");

0 commit comments

Comments
 (0)