diff --git a/lib/std/debug.zig b/lib/std/debug.zig index 99ddb266b6..3708c4fe81 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -978,7 +978,7 @@ pub fn readElfDebugInfo(allocator: mem.Allocator, elf_file: File) !ModuleDebugIn for (shdrs) |*shdr| { if (shdr.sh_type == elf.SHT_NULL) continue; - const name = std.mem.span(std.meta.assumeSentinel(header_strings[shdr.sh_name..].ptr, 0)); + const name = mem.sliceTo(header_strings[shdr.sh_name..], 0); if (mem.eql(u8, name, ".debug_info")) { opt_debug_info = try chopSlice(mapped_mem, shdr.sh_offset, shdr.sh_size); } else if (mem.eql(u8, name, ".debug_abbrev")) { diff --git a/lib/std/fs.zig b/lib/std/fs.zig index cc1b73acf2..15eeef4b09 100644 --- a/lib/std/fs.zig +++ b/lib/std/fs.zig @@ -2968,14 +2968,14 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 { var out_len: usize = out_buffer.len; try os.sysctl(&mib, out_buffer.ptr, &out_len, null, 0); // TODO could this slice from 0 to out_len instead? - return mem.sliceTo(std.meta.assumeSentinel(out_buffer.ptr, 0), 0); + return mem.sliceTo(out_buffer, 0); }, .netbsd => { var mib = [4]c_int{ os.CTL.KERN, os.KERN.PROC_ARGS, -1, os.KERN.PROC_PATHNAME }; var out_len: usize = out_buffer.len; try os.sysctl(&mib, out_buffer.ptr, &out_len, null, 0); // TODO could this slice from 0 to out_len instead? - return mem.sliceTo(std.meta.assumeSentinel(out_buffer.ptr, 0), 0); + return mem.sliceTo(out_buffer, 0); }, .openbsd, .haiku => { // OpenBSD doesn't support getting the path of a running process, so try to guess it diff --git a/lib/std/net.zig b/lib/std/net.zig index 4a567e0e8f..fa7c489b70 100644 --- a/lib/std/net.zig +++ b/lib/std/net.zig @@ -103,10 +103,10 @@ pub const Address = extern union { .path = undefined, }; - // this enables us to have the proper length of the socket in getOsSockLen - mem.set(u8, &sock_addr.path, 0); + // Add 1 to ensure a terminating 0 is present in the path array for maximum portability. + if (path.len + 1 > sock_addr.path.len) return error.NameTooLong; - if (path.len > sock_addr.path.len) return error.NameTooLong; + mem.set(u8, &sock_addr.path, 0); mem.copy(u8, &sock_addr.path, path); return Address{ .un = sock_addr }; @@ -179,9 +179,17 @@ pub const Address = extern union { unreachable; } - const path_len = std.mem.len(std.meta.assumeSentinel(&self.un.path, 0)); - return @intCast(os.socklen_t, @sizeOf(os.sockaddr.un) - self.un.path.len + path_len); + // Using the full length of the structure here is more portable than returning + // the number of bytes actually used by the currently stored path. + // This also is correct regardless if we are passing a socket address to the kernel + // (e.g. in bind, connect, sendto) since we ensure the path is 0 terminated in + // initUnix() or if we are receiving a socket address from the kernel and must + // provide the full buffer size (e.g. getsockname, getpeername, recvfrom, accept). + // + // To access the path, std.mem.sliceTo(&address.un.path, 0) should be used. + return @intCast(os.socklen_t, @sizeOf(os.sockaddr.un)); }, + else => unreachable, } } @@ -1687,7 +1695,7 @@ fn dnsParseCallback(ctx: dpc_ctx, rr: u8, data: []const u8, packet: []const u8) var tmp: [256]u8 = undefined; // Returns len of compressed name. strlen to get canon name. _ = try os.dn_expand(packet, data, &tmp); - const canon_name = mem.sliceTo(std.meta.assumeSentinel(&tmp, 0), 0); + const canon_name = mem.sliceTo(&tmp, 0); if (isValidHostName(canon_name)) { ctx.canon.items.len = 0; try ctx.canon.appendSlice(canon_name); diff --git a/lib/std/os.zig b/lib/std/os.zig index c10fe61aea..b71b17243d 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -1980,7 +1980,7 @@ pub fn getcwd(out_buffer: []u8) GetCwdError![]u8 { break :blk errno(system.getcwd(out_buffer.ptr, out_buffer.len)); }; switch (err) { - .SUCCESS => return mem.sliceTo(std.meta.assumeSentinel(out_buffer.ptr, 0), 0), + .SUCCESS => return mem.sliceTo(out_buffer, 0), .FAULT => unreachable, .INVAL => unreachable, .NOENT => return error.CurrentWorkingDirectoryUnlinked, @@ -5134,10 +5134,10 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 { return out_buffer[0..len]; }, .linux => { - var procfs_buf: ["/proc/self/fd/-2147483648".len:0]u8 = undefined; - const proc_path = std.fmt.bufPrint(procfs_buf[0..], "/proc/self/fd/{d}\x00", .{fd}) catch unreachable; + var procfs_buf: ["/proc/self/fd/-2147483648\x00".len]u8 = undefined; + const proc_path = std.fmt.bufPrintZ(procfs_buf[0..], "/proc/self/fd/{d}", .{fd}) catch unreachable; - const target = readlinkZ(std.meta.assumeSentinel(proc_path.ptr, 0), out_buffer) catch |err| { + const target = readlinkZ(proc_path, out_buffer) catch |err| { switch (err) { error.UnsupportedReparsePointType => unreachable, // Windows only, error.NotLink => unreachable, @@ -5147,7 +5147,7 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 { return target; }, .solaris => { - var procfs_buf: ["/proc/self/path/-2147483648".len:0]u8 = undefined; + var procfs_buf: ["/proc/self/path/-2147483648\x00".len]u8 = undefined; const proc_path = std.fmt.bufPrintZ(procfs_buf[0..], "/proc/self/path/{d}", .{fd}) catch unreachable; const target = readlinkZ(proc_path, out_buffer) catch |err| switch (err) { @@ -5564,7 +5564,7 @@ pub const GetHostNameError = error{PermissionDenied} || UnexpectedError; pub fn gethostname(name_buffer: *[HOST_NAME_MAX]u8) GetHostNameError![]u8 { if (builtin.link_libc) { switch (errno(system.gethostname(name_buffer, name_buffer.len))) { - .SUCCESS => return mem.sliceTo(std.meta.assumeSentinel(name_buffer, 0), 0), + .SUCCESS => return mem.sliceTo(name_buffer, 0), .FAULT => unreachable, .NAMETOOLONG => unreachable, // HOST_NAME_MAX prevents this .PERM => return error.PermissionDenied, @@ -5573,7 +5573,7 @@ pub fn gethostname(name_buffer: *[HOST_NAME_MAX]u8) GetHostNameError![]u8 { } if (builtin.os.tag == .linux) { const uts = uname(); - const hostname = mem.sliceTo(std.meta.assumeSentinel(&uts.nodename, 0), 0); + const hostname = mem.sliceTo(&uts.nodename, 0); mem.copy(u8, name_buffer, hostname); return name_buffer[0..hostname.len]; } diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index f838721370..394936e709 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -2010,7 +2010,7 @@ pub fn sliceToPrefixedFileW(s: []const u8) !PathSpace { } 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); + const result = kernel32.GetFullPathNameW(path, @intCast(u32, out.len), out.ptr, null); if (result == 0) { switch (kernel32.GetLastError()) { else => |err| return unexpectedError(err), diff --git a/lib/std/os/windows/kernel32.zig b/lib/std/os/windows/kernel32.zig index aca975cc09..d3bfeaaf2c 100644 --- a/lib/std/os/windows/kernel32.zig +++ b/lib/std/os/windows/kernel32.zig @@ -223,7 +223,7 @@ pub extern "kernel32" fn GetFinalPathNameByHandleW( pub extern "kernel32" fn GetFullPathNameW( lpFileName: [*:0]const u16, nBufferLength: u32, - lpBuffer: ?[*:0]u16, + lpBuffer: [*]u16, lpFilePart: ?*?[*:0]u16, ) callconv(@import("std").os.windows.WINAPI) u32; diff --git a/lib/std/pdb.zig b/lib/std/pdb.zig index ab712e2aff..287b65b59d 100644 --- a/lib/std/pdb.zig +++ b/lib/std/pdb.zig @@ -671,7 +671,7 @@ pub const Pdb = struct { const name_index = try reader.readIntLittle(u32); if (name_offset > name_bytes.len) return error.InvalidDebugInfo; - const name = mem.sliceTo(std.meta.assumeSentinel(name_bytes.ptr + name_offset, 0), 0); + const name = mem.sliceTo(name_bytes[name_offset..], 0); if (mem.eql(u8, name, "/names")) { break :str_tab_index name_index; } diff --git a/lib/std/zig/system/NativeTargetInfo.zig b/lib/std/zig/system/NativeTargetInfo.zig index 0648bb82ff..7e57cdda9b 100644 --- a/lib/std/zig/system/NativeTargetInfo.zig +++ b/lib/std/zig/system/NativeTargetInfo.zig @@ -533,8 +533,7 @@ fn glibcVerFromSoFile(file: fs.File) !std.builtin.Version { @alignCast(@alignOf(elf.Elf64_Shdr), &sh_buf[sh_buf_i]), ); const sh_name_off = elfInt(is_64, need_bswap, sh32.sh_name, sh64.sh_name); - // TODO this pointer cast should not be necessary - const sh_name = mem.sliceTo(std.meta.assumeSentinel(shstrtab[sh_name_off..].ptr, 0), 0); + const sh_name = mem.sliceTo(shstrtab[sh_name_off..], 0); if (mem.eql(u8, sh_name, ".dynstr")) { break :find_dyn_str .{ .offset = elfInt(is_64, need_bswap, sh32.sh_offset, sh64.sh_offset), @@ -789,8 +788,7 @@ pub fn abiAndDynamicLinkerFromFile( @alignCast(@alignOf(elf.Elf64_Shdr), &sh_buf[sh_buf_i]), ); const sh_name_off = elfInt(is_64, need_bswap, sh32.sh_name, sh64.sh_name); - // TODO this pointer cast should not be necessary - const sh_name = mem.sliceTo(std.meta.assumeSentinel(shstrtab[sh_name_off..].ptr, 0), 0); + const sh_name = mem.sliceTo(shstrtab[sh_name_off..], 0); if (mem.eql(u8, sh_name, ".dynstr")) { break :find_dyn_str .{ .offset = elfInt(is_64, need_bswap, sh32.sh_offset, sh64.sh_offset), @@ -812,7 +810,7 @@ pub fn abiAndDynamicLinkerFromFile( const strtab_read_len = try preadMin(file, &strtab_buf, rpoff_file, strtab_len); const strtab = strtab_buf[0..strtab_read_len]; - const rpath_list = mem.sliceTo(std.meta.assumeSentinel(strtab.ptr, 0), 0); + const rpath_list = mem.sliceTo(strtab, 0); var it = mem.tokenize(u8, rpath_list, ":"); while (it.next()) |rpath| { if (glibcVerFromRPath(rpath)) |ver| {