Don't scan ahead unnecessarily in wstrndup.
This commit is contained in:
+10
-6
@@ -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>()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user