Skip to content

Commit 4b1e8c3

Browse files
committed
Use core::ffi::CStr and remove strlen
Currently we manually parse the C string pointer argument, the same can be achieved by using `CStr::from_ptr` followed by a call to `to_str`. Use the `core::ffi::CStr` type to parse C string argument and remove our custom `strlen` function, update safety section of docs accordingly.
1 parent 7e00f4b commit 4b1e8c3

File tree

1 file changed

+13
-43
lines changed

1 file changed

+13
-43
lines changed

secp256k1-sys/src/lib.rs

+13-43
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ pub mod types;
3838
#[cfg_attr(docsrs, doc(cfg(feature = "recovery")))]
3939
pub mod recovery;
4040

41-
use core::{slice, ptr};
41+
use core::ffi::CStr;
42+
use core::ptr;
4243
use types::*;
4344

4445
/// Flag for context to enable no precomputation
@@ -864,17 +865,17 @@ pub unsafe extern "C" fn rustsecp256k1_v0_6_1_context_destroy(ctx: *mut Context)
864865
///
865866
/// See also secp256k1_default_error_callback_fn.
866867
///
867-
///
868868
/// # Safety
869869
///
870-
/// For safety constraints see [`std::slice::from_raw_parts`] and [`std::str::from_utf8_unchecked`].
870+
/// `message` must point to a valid C string (see safety constraints on [`core::ffi::CStr::from_ptr`]).
871871
#[no_mangle]
872872
#[cfg(not(rust_secp_no_symbol_renaming))]
873873
pub unsafe extern "C" fn rustsecp256k1_v0_6_1_default_illegal_callback_fn(message: *const c_char, _data: *mut c_void) {
874-
use core::str;
875-
let msg_slice = slice::from_raw_parts(message as *const u8, strlen(message));
876-
let msg = str::from_utf8_unchecked(msg_slice);
877-
panic!("[libsecp256k1] illegal argument. {}", msg);
874+
let s = CStr::from_ptr(message);
875+
match s.to_str() {
876+
Ok(msg) => panic!("[libsecp256k1] illegal argument. {}", msg),
877+
Err(_) => panic!("[libsecp256k1] illegal argument (msg elided due to invalid UTF-8)"),
878+
}
878879
}
879880

880881
/// **This function is an override for the C function, this is the an edited version of the original description:**
@@ -893,33 +894,17 @@ pub unsafe extern "C" fn rustsecp256k1_v0_6_1_default_illegal_callback_fn(messag
893894
///
894895
/// # Safety
895896
///
896-
/// `message` must be valid pointer and point to a valid null terminated C string. For further
897-
/// safety constraints see [`std::slice::from_raw_parts`] and [`std::str::from_utf8_unchecked`].
897+
/// `message` must point to a valid C string (see safety constraints on [`core::ffi::CStr::from_ptr`]).
898898
#[no_mangle]
899899
#[cfg(not(rust_secp_no_symbol_renaming))]
900900
pub unsafe extern "C" fn rustsecp256k1_v0_6_1_default_error_callback_fn(message: *const c_char, _data: *mut c_void) {
901-
use core::str;
902-
let msg_slice = slice::from_raw_parts(message as *const u8, strlen(message));
903-
let msg = str::from_utf8_unchecked(msg_slice);
904-
panic!("[libsecp256k1] internal consistency check failed {}", msg);
905-
}
906-
907-
/// Returns the length of the `str_ptr` string.
908-
///
909-
/// # Safety
910-
///
911-
/// `str_ptr` must be valid pointer and point to a valid null terminated C string.
912-
#[cfg(not(rust_secp_no_symbol_renaming))]
913-
unsafe fn strlen(mut str_ptr: *const c_char) -> usize {
914-
let mut ctr = 0;
915-
while *str_ptr != '\0' as c_char {
916-
ctr += 1;
917-
str_ptr = str_ptr.offset(1);
901+
let s = CStr::from_ptr(message);
902+
match s.to_str() {
903+
Ok(msg) => panic!("[libsecp256k1] internal consistency check failed {}", msg),
904+
Err(_) => panic!("[libsecp256k1] internal consistency check failed (msg elided due to invalid UTF-8)"),
918905
}
919-
ctr
920906
}
921907

922-
923908
/// A trait for producing pointers that will always be valid in C (assuming NULL pointer is a valid
924909
/// no-op).
925910
///
@@ -1427,18 +1412,3 @@ mod fuzz_dummy {
14271412
#[cfg(fuzzing)]
14281413
pub use self::fuzz_dummy::*;
14291414

1430-
#[cfg(test)]
1431-
mod tests {
1432-
#[cfg(not(rust_secp_no_symbol_renaming))]
1433-
#[test]
1434-
fn test_strlen() {
1435-
use std::ffi::CString;
1436-
use super::strlen;
1437-
1438-
let orig = "test strlen \t \n";
1439-
let test = CString::new(orig).unwrap();
1440-
1441-
assert_eq!(orig.len(), unsafe {strlen(test.as_ptr())});
1442-
}
1443-
}
1444-

0 commit comments

Comments
 (0)