Don't scan ahead unnecessarily in wstrndup.

This commit is contained in:
2025-12-08 12:40:33 -05:00
parent 927cc93e0a
commit dfd77b11a9
+10 -6
View File
@@ -20,18 +20,22 @@ pub unsafe extern "C" fn wstrdup(s: *const c_char) -> *mut c_char {
alloc_string(unsafe { CStr::from_ptr(s) })
}
/// Returns a `wmalloc`-managed C-style string of the first `n` bytes of
/// `s`, which cannot be null.
/// Returns a `wmalloc`-managed C-style string of the first `len` bytes of `s`,
/// which cannot be null.
///
/// If `n` exceeds the length of `s`, uses the lesser value.
/// If `len` exceeds the length of `s`, uses the lesser value.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn wstrndup(s: *const c_char, len: usize) -> *mut c_char {
assert!(!s.is_null());
let s = unsafe { CStr::from_ptr(s) };
let len = usize::min(len, s.count_bytes()) + 1;
let len = unsafe {
slice::from_raw_parts(s, len)
.into_iter()
.position(|p| *p == 0)
.unwrap_or(len)
};
let copy: *mut c_char = alloc_bytes(len + 1).cast(); // Implicitly zeroed.
unsafe {
ptr::copy_nonoverlapping(s.as_ptr(), copy, len);
ptr::copy_nonoverlapping(s, copy, len);
}
copy.cast::<c_char>()
}