Skip to content

Commit d68ea4a

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

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

lib/std/os/windows.zig

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1825,12 +1825,35 @@ pub fn sliceToPrefixedFileW(s: []const u8) !PathSpace {
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 = try getFullPathNameW(&temp_path.data);
1835+
std.debug.assert(path_space.data[path_space.len] == 0);
1836+
return path_space;
1837+
}
1838+
return error.BadPathName;
1839+
},
18291840
});
18301841
path_space.data[path_space.len] = 0;
18311842
return path_space;
18321843
}
18331844

1845+
fn getFullPathNameW(path: [*:0]const u16) !PathSpace {
1846+
// TODO https://github.com/ziglang/zig/issues/2765
1847+
var path_space: PathSpace = undefined;
1848+
path_space.len = kernel32.GetFullPathNameW(path, path_space.data.len, &path_space.data, null);
1849+
if (path_space.len == 0) {
1850+
switch (kernel32.GetLastError()) {
1851+
else => |err| return unexpectedError(err),
1852+
}
1853+
}
1854+
return path_space;
1855+
}
1856+
18341857
/// Assumes an absolute path.
18351858
pub fn wToPrefixedFileW(s: []const u16) !PathSpace {
18361859
// 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;

0 commit comments

Comments
 (0)