mirror of
https://github.com/ziglang/zig.git
synced 2024-11-16 17:15:37 +00:00
handle relative paths with too many ".."
This commit is contained in:
parent
59de5d0350
commit
b0116afd8a
@ -95,8 +95,8 @@ test "openDirAbsolute" {
|
||||
test "openDir cwd parent .." {
|
||||
if (builtin.os.tag == .wasi) return error.SkipZigTest;
|
||||
|
||||
var cwd = try fs.cwd().openDir("..", .{});
|
||||
defer cwd.close();
|
||||
var dir = try fs.cwd().openDir("..", .{});
|
||||
defer dir.close();
|
||||
}
|
||||
|
||||
test "readLinkAbsolute" {
|
||||
|
@ -2151,7 +2151,7 @@ pub fn collapseRepeats(comptime T: type, slice: []T, elem: T) []T {
|
||||
fn testCollapseRepeats(str: []const u8, elem: u8, expected: []const u8) !void {
|
||||
const mutable = try std.testing.allocator.dupe(u8, str);
|
||||
defer std.testing.allocator.free(mutable);
|
||||
testing.expect(std.mem.eql(u8, collapseRepeats(u8, mutable, elem), expected));
|
||||
try testing.expect(std.mem.eql(u8, collapseRepeats(u8, mutable, elem), expected));
|
||||
}
|
||||
test "collapseRepeats" {
|
||||
try testCollapseRepeats("", '/', "");
|
||||
|
@ -1817,20 +1817,42 @@ pub fn sliceToPrefixedFileW(s: []const u8) !PathSpace {
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
const prefix_u16 = [_]u16{ '\\', '?', '?', '\\' };
|
||||
const start_index = if (prefix_index > 0 or !std.fs.path.isAbsolute(s)) 0 else blk: {
|
||||
const prefix_u16 = [_]u16{ '\\', '?', '?', '\\' };
|
||||
mem.copy(u16, path_space.data[0..], prefix_u16[0..]);
|
||||
break :blk prefix_u16.len;
|
||||
};
|
||||
path_space.len = start_index + try std.unicode.utf8ToUtf16Le(path_space.data[start_index..], s);
|
||||
if (path_space.len > path_space.data.len) return error.NameTooLong;
|
||||
path_space.len = start_index + (normalizePath(u16, path_space.data[start_index..path_space.len]) catch |err| switch (err) {
|
||||
error.TooManyParentDirs => return error.BadPathName,
|
||||
error.TooManyParentDirs => {
|
||||
if (!std.fs.path.isAbsolute(s)) {
|
||||
var temp_path: PathSpace = undefined;
|
||||
temp_path.len = try std.unicode.utf8ToUtf16Le(&temp_path.data, s);
|
||||
std.debug.assert(temp_path.len == path_space.len);
|
||||
temp_path.data[path_space.len] = 0;
|
||||
path_space.len = prefix_u16.len + try getFullPathNameW(&temp_path.data, path_space.data[prefix_u16.len..]);
|
||||
mem.copy(u16, &path_space.data, &prefix_u16);
|
||||
std.debug.assert(path_space.data[path_space.len] == 0);
|
||||
return path_space;
|
||||
}
|
||||
return error.BadPathName;
|
||||
},
|
||||
});
|
||||
path_space.data[path_space.len] = 0;
|
||||
return path_space;
|
||||
}
|
||||
|
||||
fn getFullPathNameW(path: [*:0]const u16, out: []u16) !usize {
|
||||
const result= kernel32.GetFullPathNameW(path, @intCast(u32, out.len), std.meta.assumeSentinel(out.ptr, 0), null);
|
||||
if (result == 0) {
|
||||
switch (kernel32.GetLastError()) {
|
||||
else => |err| return unexpectedError(err),
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Assumes an absolute path.
|
||||
pub fn wToPrefixedFileW(s: []const u16) !PathSpace {
|
||||
// TODO https://github.com/ziglang/zig/issues/2765
|
||||
|
@ -136,6 +136,13 @@ pub extern "kernel32" fn GetFinalPathNameByHandleW(
|
||||
dwFlags: DWORD,
|
||||
) callconv(WINAPI) DWORD;
|
||||
|
||||
pub extern "kernel32" fn GetFullPathNameW(
|
||||
lpFileName: [*:0]const u16,
|
||||
nBufferLength: u32,
|
||||
lpBuffer: ?[*:0]u16,
|
||||
lpFilePart: ?*?[*:0]u16,
|
||||
) callconv(@import("std").os.windows.WINAPI) u32;
|
||||
|
||||
pub extern "kernel32" fn GetOverlappedResult(hFile: HANDLE, lpOverlapped: *OVERLAPPED, lpNumberOfBytesTransferred: *DWORD, bWait: BOOL) callconv(WINAPI) BOOL;
|
||||
|
||||
pub extern "kernel32" fn GetProcessHeap() callconv(WINAPI) ?HANDLE;
|
||||
|
@ -14,12 +14,12 @@ fn testRemoveDotDirs(str: []const u8, expected: []const u8) !void {
|
||||
const mutable = try testing.allocator.dupe(u8, str);
|
||||
defer testing.allocator.free(mutable);
|
||||
const actual = mutable[0..try windows.removeDotDirsSanitized(u8, mutable)];
|
||||
testing.expect(mem.eql(u8, actual, expected));
|
||||
try testing.expect(mem.eql(u8, actual, expected));
|
||||
}
|
||||
fn testRemoveDotDirsError(err: anyerror, str: []const u8) !void {
|
||||
const mutable = try testing.allocator.dupe(u8, str);
|
||||
defer testing.allocator.free(mutable);
|
||||
testing.expectError(err, windows.removeDotDirsSanitized(u8, mutable));
|
||||
try testing.expectError(err, windows.removeDotDirsSanitized(u8, mutable));
|
||||
}
|
||||
test "removeDotDirs" {
|
||||
try testRemoveDotDirs("", "");
|
||||
|
Loading…
Reference in New Issue
Block a user