|
| 1 | +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. |
| 2 | +// SPDX-License-Identifier: Apache-2.0 OR MIT |
| 3 | +// kani-flags: --unwind 5 |
| 4 | + |
| 5 | +//! This test case checks the usage of slices of slices (&[&[T]]). |
| 6 | +use std::mem::size_of_val; |
| 7 | + |
| 8 | +/// Structure with a raw string (i.e.: [char]). |
| 9 | +struct MyStr { |
| 10 | + header: u16, |
| 11 | + data: str, |
| 12 | +} |
| 13 | + |
| 14 | +impl MyStr { |
| 15 | + /// This creates a MyStr from a byte slice. |
| 16 | + fn new(original: &mut String) -> &mut Self { |
| 17 | + let buf = original.get_mut(..).unwrap(); |
| 18 | + assert!(size_of_val(buf) > 2, "This requires at least 2 bytes"); |
| 19 | + let unsized_len = buf.len() - 2; |
| 20 | + let ptr = std::ptr::slice_from_raw_parts_mut(buf.as_mut_ptr(), unsized_len); |
| 21 | + unsafe { &mut *(ptr as *mut Self) } |
| 22 | + } |
| 23 | +} |
| 24 | + |
| 25 | +#[kani::proof] |
| 26 | +fn sanity_check_my_str() { |
| 27 | + let mut buf = String::from("123456"); |
| 28 | + let my_str = MyStr::new(&mut buf); |
| 29 | + my_str.header = 0; |
| 30 | + |
| 31 | + assert_eq!(size_of_val(my_str), 6); |
| 32 | + assert_eq!(my_str.data.len(), 4); |
| 33 | + assert_eq!(my_str.data.chars().nth(0), Some('3')); |
| 34 | + assert_eq!(my_str.data.chars().nth(3), Some('6')); |
| 35 | +} |
| 36 | + |
| 37 | +#[kani::proof] |
| 38 | +fn check_slice_my_str() { |
| 39 | + let mut buf_0 = String::from("000"); |
| 40 | + let mut buf_1 = String::from("001"); |
| 41 | + let my_slice = &[MyStr::new(&mut buf_0), MyStr::new(&mut buf_1)]; |
| 42 | + assert_eq!(my_slice.len(), 2); |
| 43 | + |
| 44 | + assert_eq!(my_slice[0].data.len(), 1); |
| 45 | + assert_eq!(my_slice[1].data.len(), 1); |
| 46 | + |
| 47 | + assert_eq!(my_slice[0].data.chars().nth(0), Some('0')); |
| 48 | + assert_eq!(my_slice[1].data.chars().nth(0), Some('1')); |
| 49 | +} |
| 50 | + |
| 51 | +#[kani::proof] |
| 52 | +fn check_size_of_val() { |
| 53 | + let mut buf_0 = String::from("000"); |
| 54 | + let mut buf_1 = String::from("001"); |
| 55 | + let my_slice = &[MyStr::new(&mut buf_0), MyStr::new(&mut buf_1)]; |
| 56 | + assert_eq!(size_of_val(my_slice), 32); // Slice of 2 fat pointers. |
| 57 | + assert_eq!(size_of_val(my_slice[0]), 4); // Size of a fat pointer. |
| 58 | + assert_eq!(size_of_val(&my_slice[0].data), 1); // Size of str. |
| 59 | +} |
0 commit comments