diff --git a/native/src/base/files.rs b/native/src/base/files.rs index 60e40b14f..75d28aee5 100644 --- a/native/src/base/files.rs +++ b/native/src/base/files.rs @@ -7,10 +7,11 @@ use crate::{bfmt_cstr, errno, xopen}; mod unsafe_impl { use std::ffi::CStr; - use std::slice; use libc::c_char; + use crate::slice_from_ptr_mut; + #[no_mangle] pub unsafe extern "C" fn read_link(path: *const c_char, buf: *mut u8, bufsz: usize) -> isize { let r = libc::readlink(path, buf.cast(), bufsz - 1); @@ -22,7 +23,7 @@ mod unsafe_impl { #[no_mangle] unsafe extern "C" fn canonical_path(path: *const c_char, buf: *mut u8, bufsz: usize) -> isize { - super::canonical_path(CStr::from_ptr(path), slice::from_raw_parts_mut(buf, bufsz)) + super::canonical_path(CStr::from_ptr(path), slice_from_ptr_mut(buf, bufsz)) } } diff --git a/native/src/base/misc.rs b/native/src/base/misc.rs index 08f08bf6e..e809339ff 100644 --- a/native/src/base/misc.rs +++ b/native/src/base/misc.rs @@ -1,7 +1,7 @@ use std::cmp::min; use std::ffi::CStr; -use std::fmt; use std::fmt::Arguments; +use std::{fmt, slice}; struct BufFmtWriter<'a> { buf: &'a mut [u8], @@ -118,3 +118,23 @@ pub fn errno() -> &'static mut i32 { pub fn error_str() -> &'static str { unsafe { ptr_to_str(libc::strerror(*errno())) } } + +// When len is 0, don't care whether buf is null or not +#[inline] +pub unsafe fn slice_from_ptr<'a, T>(buf: *const T, len: usize) -> &'a [T] { + if len == 0 { + &[] + } else { + slice::from_raw_parts(buf, len) + } +} + +// When len is 0, don't care whether buf is null or not +#[inline] +pub unsafe fn slice_from_ptr_mut<'a, T>(buf: *mut T, len: usize) -> &'a mut [T] { + if len == 0 { + &mut [] + } else { + slice::from_raw_parts_mut(buf, len) + } +} diff --git a/native/src/base/xwrap.rs b/native/src/base/xwrap.rs index d0a71d192..910796003 100644 --- a/native/src/base/xwrap.rs +++ b/native/src/base/xwrap.rs @@ -12,36 +12,35 @@ use crate::{canonical_path, cstr, errno, error, mkdirs, perror, ptr_to_str, read mod unsafe_impl { use std::ffi::CStr; use std::os::unix::io::RawFd; - use std::slice; use cfg_if::cfg_if; use libc::{c_char, nfds_t, off_t, pollfd}; - use crate::{perror, ptr_to_str}; + use crate::{perror, ptr_to_str, slice_from_ptr, slice_from_ptr_mut}; #[no_mangle] unsafe extern "C" fn xwrite(fd: RawFd, buf: *const u8, bufsz: usize) -> isize { - super::xwrite(fd, slice::from_raw_parts(buf, bufsz)) + super::xwrite(fd, slice_from_ptr(buf, bufsz)) } #[no_mangle] unsafe extern "C" fn xread(fd: RawFd, buf: *mut u8, bufsz: usize) -> isize { - super::xread(fd, slice::from_raw_parts_mut(buf, bufsz)) + super::xread(fd, slice_from_ptr_mut(buf, bufsz)) } #[no_mangle] unsafe extern "C" fn xxread(fd: RawFd, buf: *mut u8, bufsz: usize) -> isize { - super::xxread(fd, slice::from_raw_parts_mut(buf, bufsz)) + super::xxread(fd, slice_from_ptr_mut(buf, bufsz)) } #[no_mangle] unsafe extern "C" fn xcanonical_path(path: *const c_char, buf: *mut u8, bufsz: usize) -> isize { - super::xcanonical_path(CStr::from_ptr(path), slice::from_raw_parts_mut(buf, bufsz)) + super::xcanonical_path(CStr::from_ptr(path), slice_from_ptr_mut(buf, bufsz)) } #[no_mangle] unsafe extern "C" fn xreadlink(path: *const c_char, buf: *mut u8, bufsz: usize) -> isize { - super::xreadlink(CStr::from_ptr(path), slice::from_raw_parts_mut(buf, bufsz)) + super::xreadlink(CStr::from_ptr(path), slice_from_ptr_mut(buf, bufsz)) } #[no_mangle]