diff options
Diffstat (limited to 'src/rust/protover/ffi.rs')
-rw-r--r-- | src/rust/protover/ffi.rs | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/src/rust/protover/ffi.rs b/src/rust/protover/ffi.rs index 3eb22c933e..5fefa8f7c0 100644 --- a/src/rust/protover/ffi.rs +++ b/src/rust/protover/ffi.rs @@ -137,18 +137,25 @@ pub extern "C" fn protocol_list_supports_protocol_or_later( /// Provide an interface for C to translate arguments and return types for /// protover::get_supported_protocols #[no_mangle] -pub extern "C" fn protover_get_supported_protocols() -> *mut c_char { - // Not handling errors when unwrapping as the content is controlled - // and is an empty string - let empty = CString::new("").unwrap(); - - let supported = get_supported_protocols(); - let c_supported = match CString::new(supported) { - Ok(n) => n, - Err(_) => return empty.into_raw(), - }; +pub extern "C" fn protover_get_supported_protocols() -> *const c_char { + let supported: &'static CStr; + + // If we're going to pass it to C, there cannot be any intermediate NUL + // bytes. An assert is okay here, since changing the const byte slice + // in protover.rs to contain a NUL byte somewhere in the middle would be a + // programming error. + assert!(!SUPPORTED_PROTOCOLS[..SUPPORTED_PROTOCOLS.len() - 1].contains(&0x00)); + assert!(SUPPORTED_PROTOCOLS[SUPPORTED_PROTOCOLS.len() - 1] == 0x00); + + // It's okay to call the "unchecked" version of the function because + // we can see that the bytes we're passing into it 1) are valid UTF-8, + // 2) have no intermediate NUL bytes, and 3) are terminated with a NUL + // byte. + unsafe { + supported = CStr::from_bytes_with_nul_unchecked(SUPPORTED_PROTOCOLS); + } - c_supported.into_raw() + supported.as_ptr() } /// Provide an interface for C to translate arguments and return types for |