From 96da8e5ed4e5b58aaf68e0cde36f15e8f418d66d Mon Sep 17 00:00:00 2001 From: auronandace Date: Wed, 24 Dec 2025 11:02:15 +0000 Subject: [PATCH 1/5] fix memccpy, copy correct amount of bytes and still copy if c not found --- src/header/string/mod.rs | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/header/string/mod.rs b/src/header/string/mod.rs index b4e27d80c3..315df2a770 100644 --- a/src/header/string/mod.rs +++ b/src/header/string/mod.rs @@ -20,20 +20,23 @@ use crate::{ /// See . #[unsafe(no_mangle)] pub unsafe extern "C" fn memccpy( - dest: *mut c_void, - src: *const c_void, + s1: *mut c_void, + s2: *const c_void, c: c_int, n: size_t, ) -> *mut c_void { - let to = memchr(src, c, n); + let to = unsafe {memchr(s2, c, n)}; + let dist = if to.is_null() { + n + } else { + ((to as usize) - (s2 as usize)) + 1 + }; + unsafe {memcpy(s1, s2, dist)}; if to.is_null() { - return to; + ptr::null_mut() + } else { + unsafe {(s1 as *mut u8).add(dist) as *mut c_void} } - let dist = (to as usize) - (src as usize); - if memcpy(dest, src, dist).is_null() { - return ptr::null_mut(); - } - (dest as *mut u8).add(dist + 1) as *mut c_void } /// See . @@ -53,7 +56,6 @@ pub unsafe extern "C" fn memchr( /// See . #[unsafe(no_mangle)] -#[unsafe(no_mangle)] pub unsafe extern "C" fn memcmp(s1: *const c_void, s2: *const c_void, n: usize) -> c_int { let (div, rem) = (n / mem::size_of::(), n % mem::size_of::()); let mut a = s1 as *const usize; From 4e744c3f55e2c299f86f06ed85303c57504f539a Mon Sep 17 00:00:00 2001 From: auronandace Date: Wed, 24 Dec 2025 11:05:12 +0000 Subject: [PATCH 2/5] only import the needed types --- src/header/string/mod.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/header/string/mod.rs b/src/header/string/mod.rs index 315df2a770..a4ac5c5f2f 100644 --- a/src/header/string/mod.rs +++ b/src/header/string/mod.rs @@ -13,7 +13,10 @@ use cbitset::BitSet256; use crate::{ header::{errno::*, signal}, iter::{NulTerminated, NulTerminatedInclusive, SrcDstPtrIter}, - platform::{self, types::*}, + platform::{ + self, + types::{c_char, c_int, c_void, size_t}, + }, raw_cell::RawCell, }; @@ -25,17 +28,17 @@ pub unsafe extern "C" fn memccpy( c: c_int, n: size_t, ) -> *mut c_void { - let to = unsafe {memchr(s2, c, n)}; + let to = unsafe { memchr(s2, c, n) }; let dist = if to.is_null() { n } else { ((to as usize) - (s2 as usize)) + 1 }; - unsafe {memcpy(s1, s2, dist)}; + unsafe { memcpy(s1, s2, dist) }; if to.is_null() { ptr::null_mut() } else { - unsafe {(s1 as *mut u8).add(dist) as *mut c_void} + unsafe { (s1 as *mut u8).add(dist) as *mut c_void } } } From 16f1f71acba1c1cbfce56df016ea0a9a333ae78d Mon Sep 17 00:00:00 2001 From: auronandace Date: Wed, 24 Dec 2025 12:42:28 +0000 Subject: [PATCH 3/5] ensure internal memcpy does not copy past src or dest len --- src/header/string/mod.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/header/string/mod.rs b/src/header/string/mod.rs index a4ac5c5f2f..084a635953 100644 --- a/src/header/string/mod.rs +++ b/src/header/string/mod.rs @@ -30,7 +30,15 @@ pub unsafe extern "C" fn memccpy( ) -> *mut c_void { let to = unsafe { memchr(s2, c, n) }; let dist = if to.is_null() { - n + let dest_len = unsafe { strlen(s1 as *const i8) }; + let src_len = unsafe { strlen(s2 as *const i8) }; + if n < dest_len && n < src_len { + n + } else if dest_len < src_len { + dest_len + } else { + src_len + } } else { ((to as usize) - (s2 as usize)) + 1 }; From d4d82843ded50db7f09782fbe4e70297a32128b7 Mon Sep 17 00:00:00 2001 From: auronandace Date: Wed, 24 Dec 2025 12:56:30 +0000 Subject: [PATCH 4/5] fix type --- src/header/string/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/header/string/mod.rs b/src/header/string/mod.rs index 084a635953..ca9f18b3a7 100644 --- a/src/header/string/mod.rs +++ b/src/header/string/mod.rs @@ -30,8 +30,8 @@ pub unsafe extern "C" fn memccpy( ) -> *mut c_void { let to = unsafe { memchr(s2, c, n) }; let dist = if to.is_null() { - let dest_len = unsafe { strlen(s1 as *const i8) }; - let src_len = unsafe { strlen(s2 as *const i8) }; + let dest_len = unsafe { strlen(s1 as *const c_char) }; + let src_len = unsafe { strlen(s2 as *const c_char) }; if n < dest_len && n < src_len { n } else if dest_len < src_len { From 98d90ac580f6f6f5c0bcc53366840836c60fe04c Mon Sep 17 00:00:00 2001 From: auronandace Date: Wed, 24 Dec 2025 14:32:08 +0000 Subject: [PATCH 5/5] revert previous 2 changes and add Safety note --- src/header/string/mod.rs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/header/string/mod.rs b/src/header/string/mod.rs index ca9f18b3a7..ecd897015e 100644 --- a/src/header/string/mod.rs +++ b/src/header/string/mod.rs @@ -21,6 +21,11 @@ use crate::{ }; /// See . +/// +/// # Safety +/// The caller must ensure that: +/// - `n` is not longer than the memory area pointed to by `s1`, and +/// - `n` is not longer than the memory area pointed to by `s2`. #[unsafe(no_mangle)] pub unsafe extern "C" fn memccpy( s1: *mut c_void, @@ -30,15 +35,7 @@ pub unsafe extern "C" fn memccpy( ) -> *mut c_void { let to = unsafe { memchr(s2, c, n) }; let dist = if to.is_null() { - let dest_len = unsafe { strlen(s1 as *const c_char) }; - let src_len = unsafe { strlen(s2 as *const c_char) }; - if n < dest_len && n < src_len { - n - } else if dest_len < src_len { - dest_len - } else { - src_len - } + n } else { ((to as usize) - (s2 as usize)) + 1 };