Skip to content

Commit 7e8a03d

Browse files
authored
Harness for CStr::is_empty (#194)
Towards #150 ### Changes * Added a harness for `is_empty` * Added a small optimization for `arbitray_cstr` ### Verification Result ``` SUMMARY: ** 0 of 193 failed (5 unreachable) VERIFICATION:- SUCCESSFUL Verification Time: 51.462265s Complete - 1 successfully verified harnesses, 0 failures, 1 total. ```
1 parent 810d584 commit 7e8a03d

File tree

1 file changed

+18
-1
lines changed

1 file changed

+18
-1
lines changed

library/core/src/ffi/c_str.rs

+18-1
Original file line numberDiff line numberDiff line change
@@ -860,8 +860,11 @@ mod verify {
860860

861861
// Helper function
862862
fn arbitrary_cstr(slice: &[u8]) -> &CStr {
863+
// At a minimum, the slice has a null terminator to form a valid CStr.
864+
kani::assume(slice.len() > 0 && slice[slice.len() - 1] == 0);
863865
let result = CStr::from_bytes_until_nul(&slice);
864-
kani::assume(result.is_ok());
866+
// Given the assumption, from_bytes_until_nul should never fail
867+
assert!(result.is_ok());
865868
let c_str = result.unwrap();
866869
assert!(c_str.is_safe());
867870
c_str
@@ -939,4 +942,18 @@ mod verify {
939942
assert_eq!(bytes, &slice[..end_idx]);
940943
assert!(c_str.is_safe());
941944
}
945+
946+
#[kani::proof]
947+
#[kani::unwind(33)]
948+
fn check_is_empty() {
949+
const MAX_SIZE: usize = 32;
950+
let string: [u8; MAX_SIZE] = kani::any();
951+
let slice = kani::slice::any_slice_of_array(&string);
952+
let c_str = arbitrary_cstr(slice);
953+
954+
let bytes = c_str.to_bytes(); // does not include null terminator
955+
let expected_is_empty = bytes.len() == 0;
956+
assert_eq!(expected_is_empty, c_str.is_empty());
957+
assert!(c_str.is_safe());
958+
}
942959
}

0 commit comments

Comments
 (0)