mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
std.fs: use BadPathName rather than InvalidWtf8 on Windows
This commit is contained in:
parent
97b9cc0adf
commit
2d7d98da0c
12 changed files with 64 additions and 105 deletions
|
|
@ -18,6 +18,10 @@ pub fn main() u8 {
|
||||||
defer arena_instance.deinit();
|
defer arena_instance.deinit();
|
||||||
const arena = arena_instance.allocator();
|
const arena = arena_instance.allocator();
|
||||||
|
|
||||||
|
var threaded: std.Io.Threaded = .init(gpa);
|
||||||
|
defer threaded.deinit();
|
||||||
|
const io = threaded.io();
|
||||||
|
|
||||||
var args = process.argsAlloc(arena) catch {
|
var args = process.argsAlloc(arena) catch {
|
||||||
std.debug.print("ran out of memory allocating arguments\n", .{});
|
std.debug.print("ran out of memory allocating arguments\n", .{});
|
||||||
if (fast_exit) process.exit(1);
|
if (fast_exit) process.exit(1);
|
||||||
|
|
@ -42,7 +46,7 @@ pub fn main() u8 {
|
||||||
};
|
};
|
||||||
defer diagnostics.deinit();
|
defer diagnostics.deinit();
|
||||||
|
|
||||||
var comp = aro.Compilation.initDefault(gpa, arena, &diagnostics, std.fs.cwd()) catch |err| switch (err) {
|
var comp = aro.Compilation.initDefault(gpa, arena, io, &diagnostics, std.fs.cwd()) catch |err| switch (err) {
|
||||||
error.OutOfMemory => {
|
error.OutOfMemory => {
|
||||||
std.debug.print("ran out of memory initializing C compilation\n", .{});
|
std.debug.print("ran out of memory initializing C compilation\n", .{});
|
||||||
if (fast_exit) process.exit(1);
|
if (fast_exit) process.exit(1);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
const Path = @This();
|
const Path = @This();
|
||||||
|
|
||||||
const std = @import("../../std.zig");
|
const std = @import("../../std.zig");
|
||||||
|
const Io = std.Io;
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
const fs = std.fs;
|
const fs = std.fs;
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
|
|
@ -119,7 +121,7 @@ pub fn atomicFile(
|
||||||
return p.root_dir.handle.atomicFile(joined_path, options);
|
return p.root_dir.handle.atomicFile(joined_path, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn access(p: Path, sub_path: []const u8, flags: fs.File.OpenFlags) !void {
|
pub fn access(p: Path, sub_path: []const u8, flags: Io.Dir.AccessOptions) !void {
|
||||||
var buf: [fs.max_path_bytes]u8 = undefined;
|
var buf: [fs.max_path_bytes]u8 = undefined;
|
||||||
const joined_path = if (p.sub_path.len == 0) sub_path else p: {
|
const joined_path = if (p.sub_path.len == 0) sub_path else p: {
|
||||||
break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{
|
break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{
|
||||||
|
|
@ -151,7 +153,7 @@ pub fn fmtEscapeString(path: Path) std.fmt.Alt(Path, formatEscapeString) {
|
||||||
return .{ .data = path };
|
return .{ .data = path };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn formatEscapeString(path: Path, writer: *std.Io.Writer) std.Io.Writer.Error!void {
|
pub fn formatEscapeString(path: Path, writer: *Io.Writer) Io.Writer.Error!void {
|
||||||
if (path.root_dir.path) |p| {
|
if (path.root_dir.path) |p| {
|
||||||
try std.zig.stringEscape(p, writer);
|
try std.zig.stringEscape(p, writer);
|
||||||
if (path.sub_path.len > 0) try std.zig.stringEscape(fs.path.sep_str, writer);
|
if (path.sub_path.len > 0) try std.zig.stringEscape(fs.path.sep_str, writer);
|
||||||
|
|
@ -167,7 +169,7 @@ pub fn fmtEscapeChar(path: Path) std.fmt.Alt(Path, formatEscapeChar) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deprecated, use double quoted escape to print paths.
|
/// Deprecated, use double quoted escape to print paths.
|
||||||
pub fn formatEscapeChar(path: Path, writer: *std.Io.Writer) std.Io.Writer.Error!void {
|
pub fn formatEscapeChar(path: Path, writer: *Io.Writer) Io.Writer.Error!void {
|
||||||
if (path.root_dir.path) |p| {
|
if (path.root_dir.path) |p| {
|
||||||
for (p) |byte| try std.zig.charEscape(byte, writer);
|
for (p) |byte| try std.zig.charEscape(byte, writer);
|
||||||
if (path.sub_path.len > 0) try writer.writeByte(fs.path.sep);
|
if (path.sub_path.len > 0) try writer.writeByte(fs.path.sep);
|
||||||
|
|
@ -177,7 +179,7 @@ pub fn formatEscapeChar(path: Path, writer: *std.Io.Writer) std.Io.Writer.Error!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn format(self: Path, writer: *std.Io.Writer) std.Io.Writer.Error!void {
|
pub fn format(self: Path, writer: *Io.Writer) Io.Writer.Error!void {
|
||||||
if (std.fs.path.isAbsolute(self.sub_path)) {
|
if (std.fs.path.isAbsolute(self.sub_path)) {
|
||||||
try writer.writeAll(self.sub_path);
|
try writer.writeAll(self.sub_path);
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -171,6 +171,7 @@ pub const SetNameError = error{
|
||||||
NameTooLong,
|
NameTooLong,
|
||||||
Unsupported,
|
Unsupported,
|
||||||
Unexpected,
|
Unexpected,
|
||||||
|
InvalidWtf8,
|
||||||
} || posix.PrctlError || posix.WriteError || std.fs.File.OpenError || std.fmt.BufPrintError;
|
} || posix.PrctlError || posix.WriteError || std.fs.File.OpenError || std.fmt.BufPrintError;
|
||||||
|
|
||||||
pub fn setName(self: Thread, name: []const u8) SetNameError!void {
|
pub fn setName(self: Thread, name: []const u8) SetNameError!void {
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,11 @@ pub fn deinit(si: *SelfInfo, gpa: Allocator) void {
|
||||||
module_name_arena.deinit();
|
module_name_arena.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getSymbol(si: *SelfInfo, gpa: Allocator, address: usize) Error!std.debug.Symbol {
|
pub fn getSymbol(si: *SelfInfo, gpa: Allocator, io: Io, address: usize) Error!std.debug.Symbol {
|
||||||
si.mutex.lock();
|
si.mutex.lock();
|
||||||
defer si.mutex.unlock();
|
defer si.mutex.unlock();
|
||||||
const module = try si.findModule(gpa, address);
|
const module = try si.findModule(gpa, address);
|
||||||
const di = try module.getDebugInfo(gpa);
|
const di = try module.getDebugInfo(gpa, io);
|
||||||
return di.getSymbol(gpa, address - module.base_address);
|
return di.getSymbol(gpa, address - module.base_address);
|
||||||
}
|
}
|
||||||
pub fn getModuleName(si: *SelfInfo, gpa: Allocator, address: usize) Error![]const u8 {
|
pub fn getModuleName(si: *SelfInfo, gpa: Allocator, address: usize) Error![]const u8 {
|
||||||
|
|
@ -190,6 +190,7 @@ const Module = struct {
|
||||||
|
|
||||||
const DebugInfo = struct {
|
const DebugInfo = struct {
|
||||||
arena: std.heap.ArenaAllocator.State,
|
arena: std.heap.ArenaAllocator.State,
|
||||||
|
io: Io,
|
||||||
coff_image_base: u64,
|
coff_image_base: u64,
|
||||||
mapped_file: ?MappedFile,
|
mapped_file: ?MappedFile,
|
||||||
dwarf: ?Dwarf,
|
dwarf: ?Dwarf,
|
||||||
|
|
@ -209,9 +210,10 @@ const Module = struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
fn deinit(di: *DebugInfo, gpa: Allocator) void {
|
fn deinit(di: *DebugInfo, gpa: Allocator) void {
|
||||||
|
const io = di.io;
|
||||||
if (di.dwarf) |*dwarf| dwarf.deinit(gpa);
|
if (di.dwarf) |*dwarf| dwarf.deinit(gpa);
|
||||||
if (di.pdb) |*pdb| {
|
if (di.pdb) |*pdb| {
|
||||||
pdb.file_reader.file.close();
|
pdb.file_reader.file.close(io);
|
||||||
pdb.deinit();
|
pdb.deinit();
|
||||||
}
|
}
|
||||||
if (di.mapped_file) |*mf| mf.deinit();
|
if (di.mapped_file) |*mf| mf.deinit();
|
||||||
|
|
@ -277,11 +279,11 @@ const Module = struct {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fn getDebugInfo(module: *Module, gpa: Allocator) Error!*DebugInfo {
|
fn getDebugInfo(module: *Module, gpa: Allocator, io: Io) Error!*DebugInfo {
|
||||||
if (module.di == null) module.di = loadDebugInfo(module, gpa);
|
if (module.di == null) module.di = loadDebugInfo(module, gpa, io);
|
||||||
return if (module.di.?) |*di| di else |err| err;
|
return if (module.di.?) |*di| di else |err| err;
|
||||||
}
|
}
|
||||||
fn loadDebugInfo(module: *const Module, gpa: Allocator) Error!DebugInfo {
|
fn loadDebugInfo(module: *const Module, gpa: Allocator, io: Io) Error!DebugInfo {
|
||||||
const mapped_ptr: [*]const u8 = @ptrFromInt(module.base_address);
|
const mapped_ptr: [*]const u8 = @ptrFromInt(module.base_address);
|
||||||
const mapped = mapped_ptr[0..module.size];
|
const mapped = mapped_ptr[0..module.size];
|
||||||
var coff_obj = coff.Coff.init(mapped, true) catch return error.InvalidDebugInfo;
|
var coff_obj = coff.Coff.init(mapped, true) catch return error.InvalidDebugInfo;
|
||||||
|
|
@ -306,6 +308,7 @@ const Module = struct {
|
||||||
);
|
);
|
||||||
if (len == 0) return error.MissingDebugInfo;
|
if (len == 0) return error.MissingDebugInfo;
|
||||||
const coff_file = fs.openFileAbsoluteW(name_buffer[0 .. len + 4 :0], .{}) catch |err| switch (err) {
|
const coff_file = fs.openFileAbsoluteW(name_buffer[0 .. len + 4 :0], .{}) catch |err| switch (err) {
|
||||||
|
error.Canceled => |e| return e,
|
||||||
error.Unexpected => |e| return e,
|
error.Unexpected => |e| return e,
|
||||||
error.FileNotFound => return error.MissingDebugInfo,
|
error.FileNotFound => return error.MissingDebugInfo,
|
||||||
|
|
||||||
|
|
@ -314,8 +317,6 @@ const Module = struct {
|
||||||
error.NotDir,
|
error.NotDir,
|
||||||
error.SymLinkLoop,
|
error.SymLinkLoop,
|
||||||
error.NameTooLong,
|
error.NameTooLong,
|
||||||
error.InvalidUtf8,
|
|
||||||
error.InvalidWtf8,
|
|
||||||
error.BadPathName,
|
error.BadPathName,
|
||||||
=> return error.InvalidDebugInfo,
|
=> return error.InvalidDebugInfo,
|
||||||
|
|
||||||
|
|
@ -435,7 +436,7 @@ const Module = struct {
|
||||||
errdefer pdb_file.close();
|
errdefer pdb_file.close();
|
||||||
|
|
||||||
const pdb_reader = try arena.create(Io.File.Reader);
|
const pdb_reader = try arena.create(Io.File.Reader);
|
||||||
pdb_reader.* = pdb_file.reader(try arena.alloc(u8, 4096));
|
pdb_reader.* = pdb_file.reader(io, try arena.alloc(u8, 4096));
|
||||||
|
|
||||||
var pdb = Pdb.init(gpa, pdb_reader) catch |err| switch (err) {
|
var pdb = Pdb.init(gpa, pdb_reader) catch |err| switch (err) {
|
||||||
error.OutOfMemory, error.ReadFailed, error.Unexpected => |e| return e,
|
error.OutOfMemory, error.ReadFailed, error.Unexpected => |e| return e,
|
||||||
|
|
|
||||||
|
|
@ -500,7 +500,6 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {
|
||||||
|
|
||||||
var real_path_buf: [max_path_bytes]u8 = undefined;
|
var real_path_buf: [max_path_bytes]u8 = undefined;
|
||||||
const real_path = std.posix.realpathZ(&symlink_path_buf, &real_path_buf) catch |err| switch (err) {
|
const real_path = std.posix.realpathZ(&symlink_path_buf, &real_path_buf) catch |err| switch (err) {
|
||||||
error.InvalidWtf8 => unreachable, // Windows-only
|
|
||||||
error.NetworkNotFound => unreachable, // Windows-only
|
error.NetworkNotFound => unreachable, // Windows-only
|
||||||
else => |e| return e,
|
else => |e| return e,
|
||||||
};
|
};
|
||||||
|
|
@ -511,15 +510,11 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {
|
||||||
}
|
}
|
||||||
switch (native_os) {
|
switch (native_os) {
|
||||||
.linux, .serenity => return posix.readlinkZ("/proc/self/exe", out_buffer) catch |err| switch (err) {
|
.linux, .serenity => return posix.readlinkZ("/proc/self/exe", out_buffer) catch |err| switch (err) {
|
||||||
error.InvalidUtf8 => unreachable, // WASI-only
|
|
||||||
error.InvalidWtf8 => unreachable, // Windows-only
|
|
||||||
error.UnsupportedReparsePointType => unreachable, // Windows-only
|
error.UnsupportedReparsePointType => unreachable, // Windows-only
|
||||||
error.NetworkNotFound => unreachable, // Windows-only
|
error.NetworkNotFound => unreachable, // Windows-only
|
||||||
else => |e| return e,
|
else => |e| return e,
|
||||||
},
|
},
|
||||||
.illumos => return posix.readlinkZ("/proc/self/path/a.out", out_buffer) catch |err| switch (err) {
|
.illumos => return posix.readlinkZ("/proc/self/path/a.out", out_buffer) catch |err| switch (err) {
|
||||||
error.InvalidUtf8 => unreachable, // WASI-only
|
|
||||||
error.InvalidWtf8 => unreachable, // Windows-only
|
|
||||||
error.UnsupportedReparsePointType => unreachable, // Windows-only
|
error.UnsupportedReparsePointType => unreachable, // Windows-only
|
||||||
error.NetworkNotFound => unreachable, // Windows-only
|
error.NetworkNotFound => unreachable, // Windows-only
|
||||||
else => |e| return e,
|
else => |e| return e,
|
||||||
|
|
@ -548,7 +543,6 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {
|
||||||
// argv[0] is a path (relative or absolute): use realpath(3) directly
|
// argv[0] is a path (relative or absolute): use realpath(3) directly
|
||||||
var real_path_buf: [max_path_bytes]u8 = undefined;
|
var real_path_buf: [max_path_bytes]u8 = undefined;
|
||||||
const real_path = posix.realpathZ(std.os.argv[0], &real_path_buf) catch |err| switch (err) {
|
const real_path = posix.realpathZ(std.os.argv[0], &real_path_buf) catch |err| switch (err) {
|
||||||
error.InvalidWtf8 => unreachable, // Windows-only
|
|
||||||
error.NetworkNotFound => unreachable, // Windows-only
|
error.NetworkNotFound => unreachable, // Windows-only
|
||||||
else => |e| return e,
|
else => |e| return e,
|
||||||
};
|
};
|
||||||
|
|
@ -591,10 +585,7 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {
|
||||||
// that the symlink points to, though, so we need to get the realpath.
|
// that the symlink points to, though, so we need to get the realpath.
|
||||||
var pathname_w = try windows.wToPrefixedFileW(null, image_path_name);
|
var pathname_w = try windows.wToPrefixedFileW(null, image_path_name);
|
||||||
|
|
||||||
const wide_slice = std.fs.cwd().realpathW2(pathname_w.span(), &pathname_w.data) catch |err| switch (err) {
|
const wide_slice = try std.fs.cwd().realpathW2(pathname_w.span(), &pathname_w.data);
|
||||||
error.InvalidWtf8 => unreachable,
|
|
||||||
else => |e| return e,
|
|
||||||
};
|
|
||||||
|
|
||||||
const len = std.unicode.calcWtf8Len(wide_slice);
|
const len = std.unicode.calcWtf8Len(wide_slice);
|
||||||
if (len > out_buffer.len)
|
if (len > out_buffer.len)
|
||||||
|
|
|
||||||
|
|
@ -1472,11 +1472,9 @@ pub const DeleteDirError = error{
|
||||||
NotDir,
|
NotDir,
|
||||||
SystemResources,
|
SystemResources,
|
||||||
ReadOnlyFileSystem,
|
ReadOnlyFileSystem,
|
||||||
/// WASI-only; file paths must be valid UTF-8.
|
/// WASI: file paths must be valid UTF-8.
|
||||||
InvalidUtf8,
|
/// Windows: file paths provided by the user must be valid WTF-8.
|
||||||
/// Windows-only; file paths provided by the user must be valid WTF-8.
|
|
||||||
/// https://wtf-8.codeberg.page/
|
/// https://wtf-8.codeberg.page/
|
||||||
InvalidWtf8,
|
|
||||||
BadPathName,
|
BadPathName,
|
||||||
/// On Windows, `\\server` or `\\server\share` was not found.
|
/// On Windows, `\\server` or `\\server\share` was not found.
|
||||||
NetworkNotFound,
|
NetworkNotFound,
|
||||||
|
|
@ -1577,9 +1575,7 @@ pub fn symLink(
|
||||||
// when converting to an NT namespaced path. CreateSymbolicLink in
|
// when converting to an NT namespaced path. CreateSymbolicLink in
|
||||||
// symLinkW will handle the necessary conversion.
|
// symLinkW will handle the necessary conversion.
|
||||||
var target_path_w: windows.PathSpace = undefined;
|
var target_path_w: windows.PathSpace = undefined;
|
||||||
if (try std.unicode.checkWtf8ToWtf16LeOverflow(target_path, &target_path_w.data)) {
|
try std.unicode.checkWtf8ToWtf16LeOverflow(target_path, &target_path_w.data);
|
||||||
return error.NameTooLong;
|
|
||||||
}
|
|
||||||
target_path_w.len = try std.unicode.wtf8ToWtf16Le(&target_path_w.data, target_path);
|
target_path_w.len = try std.unicode.wtf8ToWtf16Le(&target_path_w.data, target_path);
|
||||||
target_path_w.data[target_path_w.len] = 0;
|
target_path_w.data[target_path_w.len] = 0;
|
||||||
// However, we need to canonicalize any path separators to `\`, since if
|
// However, we need to canonicalize any path separators to `\`, since if
|
||||||
|
|
@ -1808,11 +1804,9 @@ pub const DeleteTreeError = error{
|
||||||
/// One of the path components was not a directory.
|
/// One of the path components was not a directory.
|
||||||
/// This error is unreachable if `sub_path` does not contain a path separator.
|
/// This error is unreachable if `sub_path` does not contain a path separator.
|
||||||
NotDir,
|
NotDir,
|
||||||
/// WASI-only; file paths must be valid UTF-8.
|
/// WASI: file paths must be valid UTF-8.
|
||||||
InvalidUtf8,
|
/// Windows: file paths provided by the user must be valid WTF-8.
|
||||||
/// Windows-only; file paths provided by the user must be valid WTF-8.
|
|
||||||
/// https://wtf-8.codeberg.page/
|
/// https://wtf-8.codeberg.page/
|
||||||
InvalidWtf8,
|
|
||||||
/// On Windows, file paths cannot contain these characters:
|
/// On Windows, file paths cannot contain these characters:
|
||||||
/// '/', '*', '?', '"', '<', '>', '|'
|
/// '/', '*', '?', '"', '<', '>', '|'
|
||||||
BadPathName,
|
BadPathName,
|
||||||
|
|
@ -1913,8 +1907,6 @@ pub fn deleteTree(self: Dir, sub_path: []const u8) DeleteTreeError!void {
|
||||||
|
|
||||||
error.AccessDenied,
|
error.AccessDenied,
|
||||||
error.PermissionDenied,
|
error.PermissionDenied,
|
||||||
error.InvalidUtf8,
|
|
||||||
error.InvalidWtf8,
|
|
||||||
error.SymLinkLoop,
|
error.SymLinkLoop,
|
||||||
error.NameTooLong,
|
error.NameTooLong,
|
||||||
error.SystemResources,
|
error.SystemResources,
|
||||||
|
|
@ -1999,8 +1991,6 @@ pub fn deleteTree(self: Dir, sub_path: []const u8) DeleteTreeError!void {
|
||||||
|
|
||||||
error.AccessDenied,
|
error.AccessDenied,
|
||||||
error.PermissionDenied,
|
error.PermissionDenied,
|
||||||
error.InvalidUtf8,
|
|
||||||
error.InvalidWtf8,
|
|
||||||
error.SymLinkLoop,
|
error.SymLinkLoop,
|
||||||
error.NameTooLong,
|
error.NameTooLong,
|
||||||
error.SystemResources,
|
error.SystemResources,
|
||||||
|
|
@ -2112,8 +2102,6 @@ fn deleteTreeMinStackSizeWithKindHint(self: Dir, sub_path: []const u8, kind_hint
|
||||||
|
|
||||||
error.AccessDenied,
|
error.AccessDenied,
|
||||||
error.PermissionDenied,
|
error.PermissionDenied,
|
||||||
error.InvalidUtf8,
|
|
||||||
error.InvalidWtf8,
|
|
||||||
error.SymLinkLoop,
|
error.SymLinkLoop,
|
||||||
error.NameTooLong,
|
error.NameTooLong,
|
||||||
error.SystemResources,
|
error.SystemResources,
|
||||||
|
|
@ -2201,8 +2189,6 @@ fn deleteTreeOpenInitialSubpath(self: Dir, sub_path: []const u8, kind_hint: File
|
||||||
|
|
||||||
error.AccessDenied,
|
error.AccessDenied,
|
||||||
error.PermissionDenied,
|
error.PermissionDenied,
|
||||||
error.InvalidUtf8,
|
|
||||||
error.InvalidWtf8,
|
|
||||||
error.SymLinkLoop,
|
error.SymLinkLoop,
|
||||||
error.NameTooLong,
|
error.NameTooLong,
|
||||||
error.SystemResources,
|
error.SystemResources,
|
||||||
|
|
|
||||||
|
|
@ -2019,8 +2019,8 @@ test "delete a setAsCwd directory on Windows" {
|
||||||
|
|
||||||
test "invalid UTF-8/WTF-8 paths" {
|
test "invalid UTF-8/WTF-8 paths" {
|
||||||
const expected_err = switch (native_os) {
|
const expected_err = switch (native_os) {
|
||||||
.wasi => error.InvalidUtf8,
|
.wasi => error.BadPathName,
|
||||||
.windows => error.InvalidWtf8,
|
.windows => error.BadPathName,
|
||||||
else => return error.SkipZigTest,
|
else => return error.SkipZigTest,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -137,8 +137,6 @@ pub fn getFdPath(fd: std.posix.fd_t, out_buffer: *[max_path_bytes]u8) std.posix.
|
||||||
switch (err) {
|
switch (err) {
|
||||||
error.NotLink => unreachable,
|
error.NotLink => unreachable,
|
||||||
error.BadPathName => unreachable,
|
error.BadPathName => unreachable,
|
||||||
error.InvalidUtf8 => unreachable, // WASI-only
|
|
||||||
error.InvalidWtf8 => unreachable, // Windows-only
|
|
||||||
error.UnsupportedReparsePointType => unreachable, // Windows-only
|
error.UnsupportedReparsePointType => unreachable, // Windows-only
|
||||||
error.NetworkNotFound => unreachable, // Windows-only
|
error.NetworkNotFound => unreachable, // Windows-only
|
||||||
else => |e| return e,
|
else => |e| return e,
|
||||||
|
|
@ -153,7 +151,6 @@ pub fn getFdPath(fd: std.posix.fd_t, out_buffer: *[max_path_bytes]u8) std.posix.
|
||||||
const target = posix.readlinkZ(proc_path, out_buffer) catch |err| switch (err) {
|
const target = posix.readlinkZ(proc_path, out_buffer) catch |err| switch (err) {
|
||||||
error.UnsupportedReparsePointType => unreachable,
|
error.UnsupportedReparsePointType => unreachable,
|
||||||
error.NotLink => unreachable,
|
error.NotLink => unreachable,
|
||||||
error.InvalidUtf8 => unreachable, // WASI-only
|
|
||||||
else => |e| return e,
|
else => |e| return e,
|
||||||
};
|
};
|
||||||
return target;
|
return target;
|
||||||
|
|
|
||||||
|
|
@ -2425,7 +2425,7 @@ pub fn normalizePath(comptime T: type, path: []T) RemoveDotDirsError!usize {
|
||||||
return prefix_len + try removeDotDirsSanitized(T, path[prefix_len..new_len]);
|
return prefix_len + try removeDotDirsSanitized(T, path[prefix_len..new_len]);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const Wtf8ToPrefixedFileWError = error{InvalidWtf8} || Wtf16ToPrefixedFileWError;
|
pub const Wtf8ToPrefixedFileWError = Wtf16ToPrefixedFileWError;
|
||||||
|
|
||||||
/// Same as `sliceToPrefixedFileW` but accepts a pointer
|
/// Same as `sliceToPrefixedFileW` but accepts a pointer
|
||||||
/// to a null-terminated WTF-8 encoded path.
|
/// to a null-terminated WTF-8 encoded path.
|
||||||
|
|
@ -2438,7 +2438,9 @@ pub fn cStrToPrefixedFileW(dir: ?HANDLE, s: [*:0]const u8) Wtf8ToPrefixedFileWEr
|
||||||
/// https://wtf-8.codeberg.page/
|
/// https://wtf-8.codeberg.page/
|
||||||
pub fn sliceToPrefixedFileW(dir: ?HANDLE, path: []const u8) Wtf8ToPrefixedFileWError!PathSpace {
|
pub fn sliceToPrefixedFileW(dir: ?HANDLE, path: []const u8) Wtf8ToPrefixedFileWError!PathSpace {
|
||||||
var temp_path: PathSpace = undefined;
|
var temp_path: PathSpace = undefined;
|
||||||
temp_path.len = try std.unicode.wtf8ToWtf16Le(&temp_path.data, path);
|
temp_path.len = std.unicode.wtf8ToWtf16Le(&temp_path.data, path) catch |err| switch (err) {
|
||||||
|
error.InvalidWtf8 => return error.BadPathName,
|
||||||
|
};
|
||||||
temp_path.data[temp_path.len] = 0;
|
temp_path.data[temp_path.len] = 0;
|
||||||
return wToPrefixedFileW(dir, temp_path.span());
|
return wToPrefixedFileW(dir, temp_path.span());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -486,8 +486,8 @@ fn fchmodat2(dirfd: fd_t, path: []const u8, mode: mode_t, flags: u32) FChmodAtEr
|
||||||
const stat = fstatatZ(pathfd, "", AT.EMPTY_PATH) catch |err| switch (err) {
|
const stat = fstatatZ(pathfd, "", AT.EMPTY_PATH) catch |err| switch (err) {
|
||||||
error.NameTooLong => unreachable,
|
error.NameTooLong => unreachable,
|
||||||
error.FileNotFound => unreachable,
|
error.FileNotFound => unreachable,
|
||||||
error.InvalidUtf8 => unreachable,
|
|
||||||
error.Streaming => unreachable,
|
error.Streaming => unreachable,
|
||||||
|
error.BadPathName => return error.Unexpected,
|
||||||
error.Canceled => return error.Canceled,
|
error.Canceled => return error.Canceled,
|
||||||
else => |e| return e,
|
else => |e| return e,
|
||||||
};
|
};
|
||||||
|
|
@ -1914,14 +1914,9 @@ pub const SymLinkError = error{
|
||||||
ReadOnlyFileSystem,
|
ReadOnlyFileSystem,
|
||||||
NotDir,
|
NotDir,
|
||||||
NameTooLong,
|
NameTooLong,
|
||||||
|
/// WASI: file paths must be valid UTF-8.
|
||||||
/// WASI-only; file paths must be valid UTF-8.
|
/// Windows: file paths provided by the user must be valid WTF-8.
|
||||||
InvalidUtf8,
|
|
||||||
|
|
||||||
/// Windows-only; file paths provided by the user must be valid WTF-8.
|
|
||||||
/// https://wtf-8.codeberg.page/
|
/// https://wtf-8.codeberg.page/
|
||||||
InvalidWtf8,
|
|
||||||
|
|
||||||
BadPathName,
|
BadPathName,
|
||||||
} || UnexpectedError;
|
} || UnexpectedError;
|
||||||
|
|
||||||
|
|
@ -2210,14 +2205,10 @@ pub const UnlinkError = error{
|
||||||
SystemResources,
|
SystemResources,
|
||||||
ReadOnlyFileSystem,
|
ReadOnlyFileSystem,
|
||||||
|
|
||||||
/// WASI-only; file paths must be valid UTF-8.
|
/// WASI: file paths must be valid UTF-8.
|
||||||
InvalidUtf8,
|
/// Windows: file paths provided by the user must be valid WTF-8.
|
||||||
|
|
||||||
/// Windows-only; file paths provided by the user must be valid WTF-8.
|
|
||||||
/// https://wtf-8.codeberg.page/
|
/// https://wtf-8.codeberg.page/
|
||||||
InvalidWtf8,
|
/// Windows: file paths cannot contain these characters:
|
||||||
|
|
||||||
/// On Windows, file paths cannot contain these characters:
|
|
||||||
/// '/', '*', '?', '"', '<', '>', '|'
|
/// '/', '*', '?', '"', '<', '>', '|'
|
||||||
BadPathName,
|
BadPathName,
|
||||||
|
|
||||||
|
|
@ -2396,11 +2387,9 @@ pub const RenameError = error{
|
||||||
PathAlreadyExists,
|
PathAlreadyExists,
|
||||||
ReadOnlyFileSystem,
|
ReadOnlyFileSystem,
|
||||||
RenameAcrossMountPoints,
|
RenameAcrossMountPoints,
|
||||||
/// WASI-only; file paths must be valid UTF-8.
|
/// WASI: file paths must be valid UTF-8.
|
||||||
InvalidUtf8,
|
/// Windows: file paths provided by the user must be valid WTF-8.
|
||||||
/// Windows-only; file paths provided by the user must be valid WTF-8.
|
|
||||||
/// https://wtf-8.codeberg.page/
|
/// https://wtf-8.codeberg.page/
|
||||||
InvalidWtf8,
|
|
||||||
BadPathName,
|
BadPathName,
|
||||||
NoDevice,
|
NoDevice,
|
||||||
SharingViolation,
|
SharingViolation,
|
||||||
|
|
@ -2839,11 +2828,9 @@ pub const DeleteDirError = error{
|
||||||
NotDir,
|
NotDir,
|
||||||
DirNotEmpty,
|
DirNotEmpty,
|
||||||
ReadOnlyFileSystem,
|
ReadOnlyFileSystem,
|
||||||
/// WASI-only; file paths must be valid UTF-8.
|
/// WASI: file paths must be valid UTF-8.
|
||||||
InvalidUtf8,
|
/// Windows: file paths provided by the user must be valid WTF-8.
|
||||||
/// Windows-only; file paths provided by the user must be valid WTF-8.
|
|
||||||
/// https://wtf-8.codeberg.page/
|
/// https://wtf-8.codeberg.page/
|
||||||
InvalidWtf8,
|
|
||||||
BadPathName,
|
BadPathName,
|
||||||
/// On Windows, `\\server` or `\\server\share` was not found.
|
/// On Windows, `\\server` or `\\server\share` was not found.
|
||||||
NetworkNotFound,
|
NetworkNotFound,
|
||||||
|
|
@ -2916,12 +2903,10 @@ pub const ChangeCurDirError = error{
|
||||||
FileNotFound,
|
FileNotFound,
|
||||||
SystemResources,
|
SystemResources,
|
||||||
NotDir,
|
NotDir,
|
||||||
BadPathName,
|
/// WASI: file paths must be valid UTF-8.
|
||||||
/// WASI-only; file paths must be valid UTF-8.
|
/// Windows: file paths provided by the user must be valid WTF-8.
|
||||||
InvalidUtf8,
|
|
||||||
/// Windows-only; file paths provided by the user must be valid WTF-8.
|
|
||||||
/// https://wtf-8.codeberg.page/
|
/// https://wtf-8.codeberg.page/
|
||||||
InvalidWtf8,
|
BadPathName,
|
||||||
} || UnexpectedError;
|
} || UnexpectedError;
|
||||||
|
|
||||||
/// Changes the current working directory of the calling process.
|
/// Changes the current working directory of the calling process.
|
||||||
|
|
@ -2933,9 +2918,7 @@ pub fn chdir(dir_path: []const u8) ChangeCurDirError!void {
|
||||||
@compileError("WASI does not support os.chdir");
|
@compileError("WASI does not support os.chdir");
|
||||||
} else if (native_os == .windows) {
|
} else if (native_os == .windows) {
|
||||||
var wtf16_dir_path: [windows.PATH_MAX_WIDE]u16 = undefined;
|
var wtf16_dir_path: [windows.PATH_MAX_WIDE]u16 = undefined;
|
||||||
if (try std.unicode.checkWtf8ToWtf16LeOverflow(dir_path, &wtf16_dir_path)) {
|
try std.unicode.checkWtf8ToWtf16LeOverflow(dir_path, &wtf16_dir_path);
|
||||||
return error.NameTooLong;
|
|
||||||
}
|
|
||||||
const len = try std.unicode.wtf8ToWtf16Le(&wtf16_dir_path, dir_path);
|
const len = try std.unicode.wtf8ToWtf16Le(&wtf16_dir_path, dir_path);
|
||||||
return chdirW(wtf16_dir_path[0..len]);
|
return chdirW(wtf16_dir_path[0..len]);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -2952,9 +2935,7 @@ pub fn chdirZ(dir_path: [*:0]const u8) ChangeCurDirError!void {
|
||||||
if (native_os == .windows) {
|
if (native_os == .windows) {
|
||||||
const dir_path_span = mem.span(dir_path);
|
const dir_path_span = mem.span(dir_path);
|
||||||
var wtf16_dir_path: [windows.PATH_MAX_WIDE]u16 = undefined;
|
var wtf16_dir_path: [windows.PATH_MAX_WIDE]u16 = undefined;
|
||||||
if (try std.unicode.checkWtf8ToWtf16LeOverflow(dir_path_span, &wtf16_dir_path)) {
|
try std.unicode.checkWtf8ToWtf16LeOverflow(dir_path_span, &wtf16_dir_path);
|
||||||
return error.NameTooLong;
|
|
||||||
}
|
|
||||||
const len = try std.unicode.wtf8ToWtf16Le(&wtf16_dir_path, dir_path_span);
|
const len = try std.unicode.wtf8ToWtf16Le(&wtf16_dir_path, dir_path_span);
|
||||||
return chdirW(wtf16_dir_path[0..len]);
|
return chdirW(wtf16_dir_path[0..len]);
|
||||||
} else if (native_os == .wasi and !builtin.link_libc) {
|
} else if (native_os == .wasi and !builtin.link_libc) {
|
||||||
|
|
@ -3016,11 +2997,9 @@ pub const ReadLinkError = error{
|
||||||
SystemResources,
|
SystemResources,
|
||||||
NotLink,
|
NotLink,
|
||||||
NotDir,
|
NotDir,
|
||||||
/// WASI-only; file paths must be valid UTF-8.
|
/// WASI: file paths must be valid UTF-8.
|
||||||
InvalidUtf8,
|
/// Windows: file paths provided by the user must be valid WTF-8.
|
||||||
/// Windows-only; file paths provided by the user must be valid WTF-8.
|
|
||||||
/// https://wtf-8.codeberg.page/
|
/// https://wtf-8.codeberg.page/
|
||||||
InvalidWtf8,
|
|
||||||
BadPathName,
|
BadPathName,
|
||||||
/// Windows-only. This error may occur if the opened reparse point is
|
/// Windows-only. This error may occur if the opened reparse point is
|
||||||
/// of unsupported type.
|
/// of unsupported type.
|
||||||
|
|
@ -4705,22 +4684,20 @@ pub const AccessError = error{
|
||||||
NameTooLong,
|
NameTooLong,
|
||||||
InputOutput,
|
InputOutput,
|
||||||
SystemResources,
|
SystemResources,
|
||||||
BadPathName,
|
|
||||||
FileBusy,
|
FileBusy,
|
||||||
SymLinkLoop,
|
SymLinkLoop,
|
||||||
ReadOnlyFileSystem,
|
ReadOnlyFileSystem,
|
||||||
/// WASI-only; file paths must be valid UTF-8.
|
/// WASI: file paths must be valid UTF-8.
|
||||||
InvalidUtf8,
|
/// Windows: file paths provided by the user must be valid WTF-8.
|
||||||
/// Windows-only; file paths provided by the user must be valid WTF-8.
|
|
||||||
/// https://wtf-8.codeberg.page/
|
/// https://wtf-8.codeberg.page/
|
||||||
InvalidWtf8,
|
BadPathName,
|
||||||
Canceled,
|
Canceled,
|
||||||
} || UnexpectedError;
|
} || UnexpectedError;
|
||||||
|
|
||||||
/// check user's permissions for a file
|
/// check user's permissions for a file
|
||||||
///
|
///
|
||||||
/// * On Windows, asserts `path` is valid [WTF-8](https://wtf-8.codeberg.page/).
|
/// * On Windows, asserts `path` is valid [WTF-8](https://wtf-8.codeberg.page/).
|
||||||
/// * On WASI, invalid UTF-8 passed to `path` causes `error.InvalidUtf8`.
|
/// * On WASI, invalid UTF-8 passed to `path` causes `error.BadPathName`.
|
||||||
/// * On other platforms, `path` is an opaque sequence of bytes with no particular encoding.
|
/// * On other platforms, `path` is an opaque sequence of bytes with no particular encoding.
|
||||||
///
|
///
|
||||||
/// On Windows, `mode` is ignored. This is a POSIX API that is only partially supported by
|
/// On Windows, `mode` is ignored. This is a POSIX API that is only partially supported by
|
||||||
|
|
@ -5154,16 +5131,15 @@ pub const RealPathError = error{
|
||||||
SystemResources,
|
SystemResources,
|
||||||
NoSpaceLeft,
|
NoSpaceLeft,
|
||||||
FileSystem,
|
FileSystem,
|
||||||
BadPathName,
|
|
||||||
DeviceBusy,
|
DeviceBusy,
|
||||||
ProcessNotFound,
|
ProcessNotFound,
|
||||||
|
|
||||||
SharingViolation,
|
SharingViolation,
|
||||||
PipeBusy,
|
PipeBusy,
|
||||||
|
|
||||||
/// Windows-only; file paths provided by the user must be valid WTF-8.
|
/// Windows: file paths provided by the user must be valid WTF-8.
|
||||||
/// https://wtf-8.codeberg.page/
|
/// https://wtf-8.codeberg.page/
|
||||||
InvalidWtf8,
|
BadPathName,
|
||||||
|
|
||||||
/// On Windows, `\\server` or `\\server\share` was not found.
|
/// On Windows, `\\server` or `\\server\share` was not found.
|
||||||
NetworkNotFound,
|
NetworkNotFound,
|
||||||
|
|
|
||||||
|
|
@ -1809,27 +1809,28 @@ pub fn wtf8ToWtf16Le(wtf16le: []u16, wtf8: []const u8) error{InvalidWtf8}!usize
|
||||||
return utf8ToUtf16LeImpl(wtf16le, wtf8, .can_encode_surrogate_half);
|
return utf8ToUtf16LeImpl(wtf16le, wtf8, .can_encode_surrogate_half);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn checkUtf8ToUtf16LeOverflowImpl(utf8: []const u8, utf16le: []const u16, comptime surrogates: Surrogates) !bool {
|
fn checkUtf8ToUtf16LeOverflowImpl(utf8: []const u8, utf16le: []const u16, comptime surrogates: Surrogates) !void {
|
||||||
// Each u8 in UTF-8/WTF-8 correlates to at most one u16 in UTF-16LE/WTF-16LE.
|
// Each u8 in UTF-8/WTF-8 correlates to at most one u16 in UTF-16LE/WTF-16LE.
|
||||||
if (utf16le.len >= utf8.len) return false;
|
if (utf16le.len >= utf8.len) return;
|
||||||
const utf16_len = calcUtf16LeLenImpl(utf8, surrogates) catch {
|
const utf16_len = calcUtf16LeLenImpl(utf8, surrogates) catch {
|
||||||
return switch (surrogates) {
|
return switch (surrogates) {
|
||||||
.cannot_encode_surrogate_half => error.InvalidUtf8,
|
.cannot_encode_surrogate_half => error.InvalidUtf8,
|
||||||
.can_encode_surrogate_half => error.InvalidWtf8,
|
.can_encode_surrogate_half => error.InvalidWtf8,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
return utf16_len > utf16le.len;
|
if (utf16_len > utf16le.len)
|
||||||
|
return error.NameTooLong;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if calling `utf8ToUtf16Le` would overflow. Might fail if utf8 is not
|
/// Checks if calling `utf8ToUtf16Le` would overflow. Might fail if utf8 is not
|
||||||
/// valid UTF-8.
|
/// valid UTF-8.
|
||||||
pub fn checkUtf8ToUtf16LeOverflow(utf8: []const u8, utf16le: []const u16) error{InvalidUtf8}!bool {
|
pub fn checkUtf8ToUtf16LeOverflow(utf8: []const u8, utf16le: []const u16) error{ InvalidUtf8, NameTooLong }!void {
|
||||||
return checkUtf8ToUtf16LeOverflowImpl(utf8, utf16le, .cannot_encode_surrogate_half);
|
return checkUtf8ToUtf16LeOverflowImpl(utf8, utf16le, .cannot_encode_surrogate_half);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if calling `utf8ToUtf16Le` would overflow. Might fail if wtf8 is not
|
/// Checks if calling `utf8ToUtf16Le` would overflow. Might fail if wtf8 is not
|
||||||
/// valid WTF-8.
|
/// valid WTF-8.
|
||||||
pub fn checkWtf8ToWtf16LeOverflow(wtf8: []const u8, wtf16le: []const u16) error{InvalidWtf8}!bool {
|
pub fn checkWtf8ToWtf16LeOverflow(wtf8: []const u8, wtf16le: []const u16) error{ InvalidWtf8, NameTooLong }!void {
|
||||||
return checkUtf8ToUtf16LeOverflowImpl(wtf8, wtf16le, .can_encode_surrogate_half);
|
return checkUtf8ToUtf16LeOverflowImpl(wtf8, wtf16le, .can_encode_surrogate_half);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2039,7 +2040,7 @@ fn testRoundtripWtf8(wtf8: []const u8) !void {
|
||||||
var wtf16_buf: [32]u16 = undefined;
|
var wtf16_buf: [32]u16 = undefined;
|
||||||
const wtf16_len = try wtf8ToWtf16Le(&wtf16_buf, wtf8);
|
const wtf16_len = try wtf8ToWtf16Le(&wtf16_buf, wtf8);
|
||||||
try testing.expectEqual(wtf16_len, calcWtf16LeLen(wtf8));
|
try testing.expectEqual(wtf16_len, calcWtf16LeLen(wtf8));
|
||||||
try testing.expectEqual(false, checkWtf8ToWtf16LeOverflow(wtf8, &wtf16_buf));
|
try checkWtf8ToWtf16LeOverflow(wtf8, &wtf16_buf);
|
||||||
const wtf16 = wtf16_buf[0..wtf16_len];
|
const wtf16 = wtf16_buf[0..wtf16_len];
|
||||||
|
|
||||||
var roundtripped_buf: [32]u8 = undefined;
|
var roundtripped_buf: [32]u8 = undefined;
|
||||||
|
|
|
||||||
|
|
@ -674,8 +674,6 @@ fn abiAndDynamicLinkerFromFile(
|
||||||
var link_buf: [posix.PATH_MAX]u8 = undefined;
|
var link_buf: [posix.PATH_MAX]u8 = undefined;
|
||||||
const link_name = posix.readlink(dl_path, &link_buf) catch |err| switch (err) {
|
const link_name = posix.readlink(dl_path, &link_buf) catch |err| switch (err) {
|
||||||
error.NameTooLong => unreachable,
|
error.NameTooLong => unreachable,
|
||||||
error.InvalidUtf8 => unreachable, // WASI only
|
|
||||||
error.InvalidWtf8 => unreachable, // Windows only
|
|
||||||
error.BadPathName => unreachable, // Windows only
|
error.BadPathName => unreachable, // Windows only
|
||||||
error.UnsupportedReparsePointType => unreachable, // Windows only
|
error.UnsupportedReparsePointType => unreachable, // Windows only
|
||||||
error.NetworkNotFound => unreachable, // Windows only
|
error.NetworkNotFound => unreachable, // Windows only
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue