Skip to content

Commit 31c1d02

Browse files
committed
Fix from_bytes_until_nul harness
1 parent 5db0f1b commit 31c1d02

File tree

1 file changed

+13
-45
lines changed

1 file changed

+13
-45
lines changed

library/core/src/ffi/c_str.rs

+13-45
Original file line numberDiff line numberDiff line change
@@ -863,51 +863,19 @@ mod verify {
863863
use super::*;
864864

865865
// pub const fn from_bytes_until_nul(bytes: &[u8]) -> Result<&CStr, FromBytesUntilNulError>
866-
// Check 1: A random index in a u8 array is guaranteed to be a null byte
867-
// Check 2: Only the last byte of a u8 array is a null byte
868-
// Check 3: The first byte of a u8 array is a null byte
869-
//
870-
// Proofs are bounded (kani::unwind) by the length of the input array.
871-
// Check 1: 2.08 sec when 32; 7.49 sec when 40
872-
// Check 2: 6.72 sec when 32; 9.2 sec when 40
873-
// Check 3: 0.33 sec when 8; 2.06 sec when 16
874866
#[kani::proof]
875-
#[kani::unwind(32)]
876-
fn check_from_bytes_until_nul_random_nul_byte() {
877-
const ARR_LEN: usize = 32;
878-
let mut string: [u8; ARR_LEN] = kani::any();
879-
880-
// ensure that there is at least one null byte
881-
let idx: usize = kani::any_where(|x: &usize| *x >= 0 && *x < ARR_LEN);
882-
string[idx] = 0;
883-
884-
let c_str = CStr::from_bytes_until_nul(&string).unwrap();
885-
assert!(c_str.is_safe());
886-
}
887-
888-
#[kani::proof]
889-
#[kani::unwind(32)]
890-
fn check_from_bytes_until_nul_single_nul_byte_end() {
891-
const ARR_LEN: usize = 32;
892-
// ensure that the string does not have intermediate null bytes
893-
// TODO: there might be a better way
894-
let mut string: [u8; ARR_LEN] = kani::any_where(|x: &[u8; ARR_LEN]| !x[..ARR_LEN-1].contains(&0));
895-
// ensure that the string is properly null-terminated
896-
string[ARR_LEN - 1] = 0;
897-
898-
let c_str = CStr::from_bytes_until_nul(&string).unwrap();
899-
assert!(c_str.is_safe());
900-
}
901-
902-
#[kani::proof]
903-
#[kani::unwind(16)]
904-
fn check_from_bytes_until_nul_single_nul_byte_head() {
905-
const ARR_LEN: usize = 16;
906-
let mut string: [u8; ARR_LEN] = kani::any();
907-
// The first byte is a null byte should result in an empty CStr.
908-
string[0] = 0;
909-
910-
let c_str = CStr::from_bytes_until_nul(&string).unwrap();
911-
assert!(c_str.is_safe());
867+
#[kani::unwind(16)] // 7.3 seconds when 16; 33.1 seconds when 32
868+
fn check_from_bytes_until_nul() {
869+
const MAX_SIZE: usize = 16;
870+
let string: [u8; MAX_SIZE] = kani::any();
871+
// Covers the case of a single null byte at the end, no null bytes, as
872+
// well as intermediate null bytes
873+
let slice = kani::slice::any_slice_of_array(&string);
874+
875+
let result = CStr::from_bytes_until_nul(slice);
876+
if result.is_ok() {
877+
let c_str = result.unwrap();
878+
assert!(c_str.is_safe());
879+
}
912880
}
913881
}

0 commit comments

Comments
 (0)