authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-10-18 02:30:37-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-10-29 06:20:50-07:00
log2d7d98da0cd54e9dc12c5d4f97cdf2e7dac36446
tree3574da909b04785c6ac47592dde4402f178f4cce
parent97b9cc0adfee5b21079fccfde535b43391ac6233

std.fs: use BadPathName rather than InvalidWtf8 on Windows


12 files changed, 64 insertions(+), 105 deletions(-)

lib/compiler/translate-c/main.zig+5-1
......@@ -18,6 +18,10 @@ pub fn main() u8 {
1818 defer arena_instance.deinit();
1919 const arena = arena_instance.allocator();
2020
21 var threaded: std.Io.Threaded = .init(gpa);
22 defer threaded.deinit();
23 const io = threaded.io();
24
2125 var args = process.argsAlloc(arena) catch {
2226 std.debug.print("ran out of memory allocating arguments\n", .{});
2327 if (fast_exit) process.exit(1);
......@@ -42,7 +46,7 @@ pub fn main() u8 {
4246 };
4347 defer diagnostics.deinit();
4448
45 var comp = aro.Compilation.initDefault(gpa, arena, &diagnostics, std.fs.cwd()) catch |err| switch (err) {
49 var comp = aro.Compilation.initDefault(gpa, arena, io, &diagnostics, std.fs.cwd()) catch |err| switch (err) {
4650 error.OutOfMemory => {
4751 std.debug.print("ran out of memory initializing C compilation\n", .{});
4852 if (fast_exit) process.exit(1);
lib/std/Build/Cache/Path.zig+6-4
......@@ -1,5 +1,7 @@
11const Path = @This();
2
23const std = @import("../../std.zig");
4const Io = std.Io;
35const assert = std.debug.assert;
46const fs = std.fs;
57const Allocator = std.mem.Allocator;
......@@ -119,7 +121,7 @@ pub fn atomicFile(
119121 return p.root_dir.handle.atomicFile(joined_path, options);
120122}
121123
122pub fn access(p: Path, sub_path: []const u8, flags: fs.File.OpenFlags) !void {
124pub fn access(p: Path, sub_path: []const u8, flags: Io.Dir.AccessOptions) !void {
123125 var buf: [fs.max_path_bytes]u8 = undefined;
124126 const joined_path = if (p.sub_path.len == 0) sub_path else p: {
125127 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) {
151153 return .{ .data = path };
152154}
153155
154pub fn formatEscapeString(path: Path, writer: *std.Io.Writer) std.Io.Writer.Error!void {
156pub fn formatEscapeString(path: Path, writer: *Io.Writer) Io.Writer.Error!void {
155157 if (path.root_dir.path) |p| {
156158 try std.zig.stringEscape(p, writer);
157159 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) {
167169}
168170
169171/// Deprecated, use double quoted escape to print paths.
170pub fn formatEscapeChar(path: Path, writer: *std.Io.Writer) std.Io.Writer.Error!void {
172pub fn formatEscapeChar(path: Path, writer: *Io.Writer) Io.Writer.Error!void {
171173 if (path.root_dir.path) |p| {
172174 for (p) |byte| try std.zig.charEscape(byte, writer);
173175 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!
177179 }
178180}
179181
180pub fn format(self: Path, writer: *std.Io.Writer) std.Io.Writer.Error!void {
182pub fn format(self: Path, writer: *Io.Writer) Io.Writer.Error!void {
181183 if (std.fs.path.isAbsolute(self.sub_path)) {
182184 try writer.writeAll(self.sub_path);
183185 return;
lib/std/Thread.zig+1
......@@ -171,6 +171,7 @@ pub const SetNameError = error{
171171 NameTooLong,
172172 Unsupported,
173173 Unexpected,
174 InvalidWtf8,
174175} || posix.PrctlError || posix.WriteError || std.fs.File.OpenError || std.fmt.BufPrintError;
175176
176177pub fn setName(self: Thread, name: []const u8) SetNameError!void {
lib/std/debug/SelfInfo/Windows.zig+10-9
......@@ -20,11 +20,11 @@ pub fn deinit(si: *SelfInfo, gpa: Allocator) void {
2020 module_name_arena.deinit();
2121}
2222
23pub fn getSymbol(si: *SelfInfo, gpa: Allocator, address: usize) Error!std.debug.Symbol {
23pub fn getSymbol(si: *SelfInfo, gpa: Allocator, io: Io, address: usize) Error!std.debug.Symbol {
2424 si.mutex.lock();
2525 defer si.mutex.unlock();
2626 const module = try si.findModule(gpa, address);
27 const di = try module.getDebugInfo(gpa);
27 const di = try module.getDebugInfo(gpa, io);
2828 return di.getSymbol(gpa, address - module.base_address);
2929}
3030pub fn getModuleName(si: *SelfInfo, gpa: Allocator, address: usize) Error![]const u8 {
......@@ -190,6 +190,7 @@ const Module = struct {
190190
191191 const DebugInfo = struct {
192192 arena: std.heap.ArenaAllocator.State,
193 io: Io,
193194 coff_image_base: u64,
194195 mapped_file: ?MappedFile,
195196 dwarf: ?Dwarf,
......@@ -209,9 +210,10 @@ const Module = struct {
209210 };
210211
211212 fn deinit(di: *DebugInfo, gpa: Allocator) void {
213 const io = di.io;
212214 if (di.dwarf) |*dwarf| dwarf.deinit(gpa);
213215 if (di.pdb) |*pdb| {
214 pdb.file_reader.file.close();
216 pdb.file_reader.file.close(io);
215217 pdb.deinit();
216218 }
217219 if (di.mapped_file) |*mf| mf.deinit();
......@@ -277,11 +279,11 @@ const Module = struct {
277279 }
278280 };
279281
280 fn getDebugInfo(module: *Module, gpa: Allocator) Error!*DebugInfo {
281 if (module.di == null) module.di = loadDebugInfo(module, gpa);
282 fn getDebugInfo(module: *Module, gpa: Allocator, io: Io) Error!*DebugInfo {
283 if (module.di == null) module.di = loadDebugInfo(module, gpa, io);
282284 return if (module.di.?) |*di| di else |err| err;
283285 }
284 fn loadDebugInfo(module: *const Module, gpa: Allocator) Error!DebugInfo {
286 fn loadDebugInfo(module: *const Module, gpa: Allocator, io: Io) Error!DebugInfo {
285287 const mapped_ptr: [*]const u8 = @ptrFromInt(module.base_address);
286288 const mapped = mapped_ptr[0..module.size];
287289 var coff_obj = coff.Coff.init(mapped, true) catch return error.InvalidDebugInfo;
......@@ -306,6 +308,7 @@ const Module = struct {
306308 );
307309 if (len == 0) return error.MissingDebugInfo;
308310 const coff_file = fs.openFileAbsoluteW(name_buffer[0 .. len + 4 :0], .{}) catch |err| switch (err) {
311 error.Canceled => |e| return e,
309312 error.Unexpected => |e| return e,
310313 error.FileNotFound => return error.MissingDebugInfo,
311314
......@@ -314,8 +317,6 @@ const Module = struct {
314317 error.NotDir,
315318 error.SymLinkLoop,
316319 error.NameTooLong,
317 error.InvalidUtf8,
318 error.InvalidWtf8,
319320 error.BadPathName,
320321 => return error.InvalidDebugInfo,
321322
......@@ -435,7 +436,7 @@ const Module = struct {
435436 errdefer pdb_file.close();
436437
437438 const pdb_reader = try arena.create(Io.File.Reader);
438 pdb_reader.* = pdb_file.reader(try arena.alloc(u8, 4096));
439 pdb_reader.* = pdb_file.reader(io, try arena.alloc(u8, 4096));
439440
440441 var pdb = Pdb.init(gpa, pdb_reader) catch |err| switch (err) {
441442 error.OutOfMemory, error.ReadFailed, error.Unexpected => |e| return e,
lib/std/fs.zig+1-10
......@@ -500,7 +500,6 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {
500500
501501 var real_path_buf: [max_path_bytes]u8 = undefined;
502502 const real_path = std.posix.realpathZ(&symlink_path_buf, &real_path_buf) catch |err| switch (err) {
503 error.InvalidWtf8 => unreachable, // Windows-only
504503 error.NetworkNotFound => unreachable, // Windows-only
505504 else => |e| return e,
506505 };
......@@ -511,15 +510,11 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {
511510 }
512511 switch (native_os) {
513512 .linux, .serenity => return posix.readlinkZ("/proc/self/exe", out_buffer) catch |err| switch (err) {
514 error.InvalidUtf8 => unreachable, // WASI-only
515 error.InvalidWtf8 => unreachable, // Windows-only
516513 error.UnsupportedReparsePointType => unreachable, // Windows-only
517514 error.NetworkNotFound => unreachable, // Windows-only
518515 else => |e| return e,
519516 },
520517 .illumos => return posix.readlinkZ("/proc/self/path/a.out", out_buffer) catch |err| switch (err) {
521 error.InvalidUtf8 => unreachable, // WASI-only
522 error.InvalidWtf8 => unreachable, // Windows-only
523518 error.UnsupportedReparsePointType => unreachable, // Windows-only
524519 error.NetworkNotFound => unreachable, // Windows-only
525520 else => |e| return e,
......@@ -548,7 +543,6 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {
548543 // argv[0] is a path (relative or absolute): use realpath(3) directly
549544 var real_path_buf: [max_path_bytes]u8 = undefined;
550545 const real_path = posix.realpathZ(std.os.argv[0], &real_path_buf) catch |err| switch (err) {
551 error.InvalidWtf8 => unreachable, // Windows-only
552546 error.NetworkNotFound => unreachable, // Windows-only
553547 else => |e| return e,
554548 };
......@@ -591,10 +585,7 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {
591585 // that the symlink points to, though, so we need to get the realpath.
592586 var pathname_w = try windows.wToPrefixedFileW(null, image_path_name);
593587
594 const wide_slice = std.fs.cwd().realpathW2(pathname_w.span(), &pathname_w.data) catch |err| switch (err) {
595 error.InvalidWtf8 => unreachable,
596 else => |e| return e,
597 };
588 const wide_slice = try std.fs.cwd().realpathW2(pathname_w.span(), &pathname_w.data);
598589
599590 const len = std.unicode.calcWtf8Len(wide_slice);
600591 if (len > out_buffer.len)
lib/std/fs/Dir.zig+5-19
......@@ -1472,11 +1472,9 @@ pub const DeleteDirError = error{
14721472 NotDir,
14731473 SystemResources,
14741474 ReadOnlyFileSystem,
1475 /// WASI-only; file paths must be valid UTF-8.
1476 InvalidUtf8,
1477 /// Windows-only; file paths provided by the user must be valid WTF-8.
1475 /// WASI: file paths must be valid UTF-8.
1476 /// Windows: file paths provided by the user must be valid WTF-8.
14781477 /// https://wtf-8.codeberg.page/
1479 InvalidWtf8,
14801478 BadPathName,
14811479 /// On Windows, `\\server` or `\\server\share` was not found.
14821480 NetworkNotFound,
......@@ -1577,9 +1575,7 @@ pub fn symLink(
15771575 // when converting to an NT namespaced path. CreateSymbolicLink in
15781576 // symLinkW will handle the necessary conversion.
15791577 var target_path_w: windows.PathSpace = undefined;
1580 if (try std.unicode.checkWtf8ToWtf16LeOverflow(target_path, &target_path_w.data)) {
1581 return error.NameTooLong;
1582 }
1578 try std.unicode.checkWtf8ToWtf16LeOverflow(target_path, &target_path_w.data);
15831579 target_path_w.len = try std.unicode.wtf8ToWtf16Le(&target_path_w.data, target_path);
15841580 target_path_w.data[target_path_w.len] = 0;
15851581 // However, we need to canonicalize any path separators to `\`, since if
......@@ -1808,11 +1804,9 @@ pub const DeleteTreeError = error{
18081804 /// One of the path components was not a directory.
18091805 /// This error is unreachable if `sub_path` does not contain a path separator.
18101806 NotDir,
1811 /// WASI-only; file paths must be valid UTF-8.
1812 InvalidUtf8,
1813 /// Windows-only; file paths provided by the user must be valid WTF-8.
1807 /// WASI: file paths must be valid UTF-8.
1808 /// Windows: file paths provided by the user must be valid WTF-8.
18141809 /// https://wtf-8.codeberg.page/
1815 InvalidWtf8,
18161810 /// On Windows, file paths cannot contain these characters:
18171811 /// '/', '*', '?', '"', '<', '>', '|'
18181812 BadPathName,
......@@ -1913,8 +1907,6 @@ pub fn deleteTree(self: Dir, sub_path: []const u8) DeleteTreeError!void {
19131907
19141908 error.AccessDenied,
19151909 error.PermissionDenied,
1916 error.InvalidUtf8,
1917 error.InvalidWtf8,
19181910 error.SymLinkLoop,
19191911 error.NameTooLong,
19201912 error.SystemResources,
......@@ -1999,8 +1991,6 @@ pub fn deleteTree(self: Dir, sub_path: []const u8) DeleteTreeError!void {
19991991
20001992 error.AccessDenied,
20011993 error.PermissionDenied,
2002 error.InvalidUtf8,
2003 error.InvalidWtf8,
20041994 error.SymLinkLoop,
20051995 error.NameTooLong,
20061996 error.SystemResources,
......@@ -2112,8 +2102,6 @@ fn deleteTreeMinStackSizeWithKindHint(self: Dir, sub_path: []const u8, kind_hint
21122102
21132103 error.AccessDenied,
21142104 error.PermissionDenied,
2115 error.InvalidUtf8,
2116 error.InvalidWtf8,
21172105 error.SymLinkLoop,
21182106 error.NameTooLong,
21192107 error.SystemResources,
......@@ -2201,8 +2189,6 @@ fn deleteTreeOpenInitialSubpath(self: Dir, sub_path: []const u8, kind_hint: File
22012189
22022190 error.AccessDenied,
22032191 error.PermissionDenied,
2204 error.InvalidUtf8,
2205 error.InvalidWtf8,
22062192 error.SymLinkLoop,
22072193 error.NameTooLong,
22082194 error.SystemResources,
lib/std/fs/test.zig+2-2
......@@ -2019,8 +2019,8 @@ test "delete a setAsCwd directory on Windows" {
20192019
20202020test "invalid UTF-8/WTF-8 paths" {
20212021 const expected_err = switch (native_os) {
2022 .wasi => error.InvalidUtf8,
2023 .windows => error.InvalidWtf8,
2022 .wasi => error.BadPathName,
2023 .windows => error.BadPathName,
20242024 else => return error.SkipZigTest,
20252025 };
20262026
lib/std/os.zig-3
......@@ -137,8 +137,6 @@ pub fn getFdPath(fd: std.posix.fd_t, out_buffer: *[max_path_bytes]u8) std.posix.
137137 switch (err) {
138138 error.NotLink => unreachable,
139139 error.BadPathName => unreachable,
140 error.InvalidUtf8 => unreachable, // WASI-only
141 error.InvalidWtf8 => unreachable, // Windows-only
142140 error.UnsupportedReparsePointType => unreachable, // Windows-only
143141 error.NetworkNotFound => unreachable, // Windows-only
144142 else => |e| return e,
......@@ -153,7 +151,6 @@ pub fn getFdPath(fd: std.posix.fd_t, out_buffer: *[max_path_bytes]u8) std.posix.
153151 const target = posix.readlinkZ(proc_path, out_buffer) catch |err| switch (err) {
154152 error.UnsupportedReparsePointType => unreachable,
155153 error.NotLink => unreachable,
156 error.InvalidUtf8 => unreachable, // WASI-only
157154 else => |e| return e,
158155 };
159156 return target;
lib/std/os/windows.zig+4-2
......@@ -2425,7 +2425,7 @@ pub fn normalizePath(comptime T: type, path: []T) RemoveDotDirsError!usize {
24252425 return prefix_len + try removeDotDirsSanitized(T, path[prefix_len..new_len]);
24262426}
24272427
2428pub const Wtf8ToPrefixedFileWError = error{InvalidWtf8} || Wtf16ToPrefixedFileWError;
2428pub const Wtf8ToPrefixedFileWError = Wtf16ToPrefixedFileWError;
24292429
24302430/// Same as `sliceToPrefixedFileW` but accepts a pointer
24312431/// to a null-terminated WTF-8 encoded path.
......@@ -2438,7 +2438,9 @@ pub fn cStrToPrefixedFileW(dir: ?HANDLE, s: [*:0]const u8) Wtf8ToPrefixedFileWEr
24382438/// https://wtf-8.codeberg.page/
24392439pub fn sliceToPrefixedFileW(dir: ?HANDLE, path: []const u8) Wtf8ToPrefixedFileWError!PathSpace {
24402440 var temp_path: PathSpace = undefined;
2441 temp_path.len = try std.unicode.wtf8ToWtf16Le(&temp_path.data, path);
2441 temp_path.len = std.unicode.wtf8ToWtf16Le(&temp_path.data, path) catch |err| switch (err) {
2442 error.InvalidWtf8 => return error.BadPathName,
2443 };
24422444 temp_path.data[temp_path.len] = 0;
24432445 return wToPrefixedFileW(dir, temp_path.span());
24442446}
lib/std/posix.zig+23-47
......@@ -486,8 +486,8 @@ fn fchmodat2(dirfd: fd_t, path: []const u8, mode: mode_t, flags: u32) FChmodAtEr
486486 const stat = fstatatZ(pathfd, "", AT.EMPTY_PATH) catch |err| switch (err) {
487487 error.NameTooLong => unreachable,
488488 error.FileNotFound => unreachable,
489 error.InvalidUtf8 => unreachable,
490489 error.Streaming => unreachable,
490 error.BadPathName => return error.Unexpected,
491491 error.Canceled => return error.Canceled,
492492 else => |e| return e,
493493 };
......@@ -1914,14 +1914,9 @@ pub const SymLinkError = error{
19141914 ReadOnlyFileSystem,
19151915 NotDir,
19161916 NameTooLong,
1917
1918 /// WASI-only; file paths must be valid UTF-8.
1919 InvalidUtf8,
1920
1921 /// Windows-only; file paths provided by the user must be valid WTF-8.
1917 /// WASI: file paths must be valid UTF-8.
1918 /// Windows: file paths provided by the user must be valid WTF-8.
19221919 /// https://wtf-8.codeberg.page/
1923 InvalidWtf8,
1924
19251920 BadPathName,
19261921} || UnexpectedError;
19271922
......@@ -2210,14 +2205,10 @@ pub const UnlinkError = error{
22102205 SystemResources,
22112206 ReadOnlyFileSystem,
22122207
2213 /// WASI-only; file paths must be valid UTF-8.
2214 InvalidUtf8,
2215
2216 /// Windows-only; file paths provided by the user must be valid WTF-8.
2208 /// WASI: file paths must be valid UTF-8.
2209 /// Windows: file paths provided by the user must be valid WTF-8.
22172210 /// https://wtf-8.codeberg.page/
2218 InvalidWtf8,
2219
2220 /// On Windows, file paths cannot contain these characters:
2211 /// Windows: file paths cannot contain these characters:
22212212 /// '/', '*', '?', '"', '<', '>', '|'
22222213 BadPathName,
22232214
......@@ -2396,11 +2387,9 @@ pub const RenameError = error{
23962387 PathAlreadyExists,
23972388 ReadOnlyFileSystem,
23982389 RenameAcrossMountPoints,
2399 /// WASI-only; file paths must be valid UTF-8.
2400 InvalidUtf8,
2401 /// Windows-only; file paths provided by the user must be valid WTF-8.
2390 /// WASI: file paths must be valid UTF-8.
2391 /// Windows: file paths provided by the user must be valid WTF-8.
24022392 /// https://wtf-8.codeberg.page/
2403 InvalidWtf8,
24042393 BadPathName,
24052394 NoDevice,
24062395 SharingViolation,
......@@ -2839,11 +2828,9 @@ pub const DeleteDirError = error{
28392828 NotDir,
28402829 DirNotEmpty,
28412830 ReadOnlyFileSystem,
2842 /// WASI-only; file paths must be valid UTF-8.
2843 InvalidUtf8,
2844 /// Windows-only; file paths provided by the user must be valid WTF-8.
2831 /// WASI: file paths must be valid UTF-8.
2832 /// Windows: file paths provided by the user must be valid WTF-8.
28452833 /// https://wtf-8.codeberg.page/
2846 InvalidWtf8,
28472834 BadPathName,
28482835 /// On Windows, `\\server` or `\\server\share` was not found.
28492836 NetworkNotFound,
......@@ -2916,12 +2903,10 @@ pub const ChangeCurDirError = error{
29162903 FileNotFound,
29172904 SystemResources,
29182905 NotDir,
2919 BadPathName,
2920 /// WASI-only; file paths must be valid UTF-8.
2921 InvalidUtf8,
2922 /// Windows-only; file paths provided by the user must be valid WTF-8.
2906 /// WASI: file paths must be valid UTF-8.
2907 /// Windows: file paths provided by the user must be valid WTF-8.
29232908 /// https://wtf-8.codeberg.page/
2924 InvalidWtf8,
2909 BadPathName,
29252910} || UnexpectedError;
29262911
29272912/// Changes the current working directory of the calling process.
......@@ -2933,9 +2918,7 @@ pub fn chdir(dir_path: []const u8) ChangeCurDirError!void {
29332918 @compileError("WASI does not support os.chdir");
29342919 } else if (native_os == .windows) {
29352920 var wtf16_dir_path: [windows.PATH_MAX_WIDE]u16 = undefined;
2936 if (try std.unicode.checkWtf8ToWtf16LeOverflow(dir_path, &wtf16_dir_path)) {
2937 return error.NameTooLong;
2938 }
2921 try std.unicode.checkWtf8ToWtf16LeOverflow(dir_path, &wtf16_dir_path);
29392922 const len = try std.unicode.wtf8ToWtf16Le(&wtf16_dir_path, dir_path);
29402923 return chdirW(wtf16_dir_path[0..len]);
29412924 } else {
......@@ -2952,9 +2935,7 @@ pub fn chdirZ(dir_path: [*:0]const u8) ChangeCurDirError!void {
29522935 if (native_os == .windows) {
29532936 const dir_path_span = mem.span(dir_path);
29542937 var wtf16_dir_path: [windows.PATH_MAX_WIDE]u16 = undefined;
2955 if (try std.unicode.checkWtf8ToWtf16LeOverflow(dir_path_span, &wtf16_dir_path)) {
2956 return error.NameTooLong;
2957 }
2938 try std.unicode.checkWtf8ToWtf16LeOverflow(dir_path_span, &wtf16_dir_path);
29582939 const len = try std.unicode.wtf8ToWtf16Le(&wtf16_dir_path, dir_path_span);
29592940 return chdirW(wtf16_dir_path[0..len]);
29602941 } else if (native_os == .wasi and !builtin.link_libc) {
......@@ -3016,11 +2997,9 @@ pub const ReadLinkError = error{
30162997 SystemResources,
30172998 NotLink,
30182999 NotDir,
3019 /// WASI-only; file paths must be valid UTF-8.
3020 InvalidUtf8,
3021 /// Windows-only; file paths provided by the user must be valid WTF-8.
3000 /// WASI: file paths must be valid UTF-8.
3001 /// Windows: file paths provided by the user must be valid WTF-8.
30223002 /// https://wtf-8.codeberg.page/
3023 InvalidWtf8,
30243003 BadPathName,
30253004 /// Windows-only. This error may occur if the opened reparse point is
30263005 /// of unsupported type.
......@@ -4705,22 +4684,20 @@ pub const AccessError = error{
47054684 NameTooLong,
47064685 InputOutput,
47074686 SystemResources,
4708 BadPathName,
47094687 FileBusy,
47104688 SymLinkLoop,
47114689 ReadOnlyFileSystem,
4712 /// WASI-only; file paths must be valid UTF-8.
4713 InvalidUtf8,
4714 /// Windows-only; file paths provided by the user must be valid WTF-8.
4690 /// WASI: file paths must be valid UTF-8.
4691 /// Windows: file paths provided by the user must be valid WTF-8.
47154692 /// https://wtf-8.codeberg.page/
4716 InvalidWtf8,
4693 BadPathName,
47174694 Canceled,
47184695} || UnexpectedError;
47194696
47204697/// check user's permissions for a file
47214698///
47224699/// * On Windows, asserts `path` is valid [WTF-8](https://wtf-8.codeberg.page/).
4723/// * On WASI, invalid UTF-8 passed to `path` causes `error.InvalidUtf8`.
4700/// * On WASI, invalid UTF-8 passed to `path` causes `error.BadPathName`.
47244701/// * On other platforms, `path` is an opaque sequence of bytes with no particular encoding.
47254702///
47264703/// On Windows, `mode` is ignored. This is a POSIX API that is only partially supported by
......@@ -5154,16 +5131,15 @@ pub const RealPathError = error{
51545131 SystemResources,
51555132 NoSpaceLeft,
51565133 FileSystem,
5157 BadPathName,
51585134 DeviceBusy,
51595135 ProcessNotFound,
51605136
51615137 SharingViolation,
51625138 PipeBusy,
51635139
5164 /// Windows-only; file paths provided by the user must be valid WTF-8.
5140 /// Windows: file paths provided by the user must be valid WTF-8.
51655141 /// https://wtf-8.codeberg.page/
5166 InvalidWtf8,
5142 BadPathName,
51675143
51685144 /// On Windows, `\\server` or `\\server\share` was not found.
51695145 NetworkNotFound,
lib/std/unicode.zig+7-6
......@@ -1809,27 +1809,28 @@ pub fn wtf8ToWtf16Le(wtf16le: []u16, wtf8: []const u8) error{InvalidWtf8}!usize
18091809 return utf8ToUtf16LeImpl(wtf16le, wtf8, .can_encode_surrogate_half);
18101810}
18111811
1812fn checkUtf8ToUtf16LeOverflowImpl(utf8: []const u8, utf16le: []const u16, comptime surrogates: Surrogates) !bool {
1812fn checkUtf8ToUtf16LeOverflowImpl(utf8: []const u8, utf16le: []const u16, comptime surrogates: Surrogates) !void {
18131813 // Each u8 in UTF-8/WTF-8 correlates to at most one u16 in UTF-16LE/WTF-16LE.
1814 if (utf16le.len >= utf8.len) return false;
1814 if (utf16le.len >= utf8.len) return;
18151815 const utf16_len = calcUtf16LeLenImpl(utf8, surrogates) catch {
18161816 return switch (surrogates) {
18171817 .cannot_encode_surrogate_half => error.InvalidUtf8,
18181818 .can_encode_surrogate_half => error.InvalidWtf8,
18191819 };
18201820 };
1821 return utf16_len > utf16le.len;
1821 if (utf16_len > utf16le.len)
1822 return error.NameTooLong;
18221823}
18231824
18241825/// Checks if calling `utf8ToUtf16Le` would overflow. Might fail if utf8 is not
18251826/// valid UTF-8.
1826pub fn checkUtf8ToUtf16LeOverflow(utf8: []const u8, utf16le: []const u16) error{InvalidUtf8}!bool {
1827pub fn checkUtf8ToUtf16LeOverflow(utf8: []const u8, utf16le: []const u16) error{ InvalidUtf8, NameTooLong }!void {
18271828 return checkUtf8ToUtf16LeOverflowImpl(utf8, utf16le, .cannot_encode_surrogate_half);
18281829}
18291830
18301831/// Checks if calling `utf8ToUtf16Le` would overflow. Might fail if wtf8 is not
18311832/// valid WTF-8.
1832pub fn checkWtf8ToWtf16LeOverflow(wtf8: []const u8, wtf16le: []const u16) error{InvalidWtf8}!bool {
1833pub fn checkWtf8ToWtf16LeOverflow(wtf8: []const u8, wtf16le: []const u16) error{ InvalidWtf8, NameTooLong }!void {
18331834 return checkUtf8ToUtf16LeOverflowImpl(wtf8, wtf16le, .can_encode_surrogate_half);
18341835}
18351836
......@@ -2039,7 +2040,7 @@ fn testRoundtripWtf8(wtf8: []const u8) !void {
20392040 var wtf16_buf: [32]u16 = undefined;
20402041 const wtf16_len = try wtf8ToWtf16Le(&wtf16_buf, wtf8);
20412042 try testing.expectEqual(wtf16_len, calcWtf16LeLen(wtf8));
2042 try testing.expectEqual(false, checkWtf8ToWtf16LeOverflow(wtf8, &wtf16_buf));
2043 try checkWtf8ToWtf16LeOverflow(wtf8, &wtf16_buf);
20432044 const wtf16 = wtf16_buf[0..wtf16_len];
20442045
20452046 var roundtripped_buf: [32]u8 = undefined;
lib/std/zig/system.zig-2
......@@ -674,8 +674,6 @@ fn abiAndDynamicLinkerFromFile(
674674 var link_buf: [posix.PATH_MAX]u8 = undefined;
675675 const link_name = posix.readlink(dl_path, &link_buf) catch |err| switch (err) {
676676 error.NameTooLong => unreachable,
677 error.InvalidUtf8 => unreachable, // WASI only
678 error.InvalidWtf8 => unreachable, // Windows only
679677 error.BadPathName => unreachable, // Windows only
680678 error.UnsupportedReparsePointType => unreachable, // Windows only
681679 error.NetworkNotFound => unreachable, // Windows only