Skip to content

Commit c87179e

Browse files
CasperNCasper Neo
and
Casper Neo
authored
Rust Remove SafeSliceAccess for Arrays, and fix miri. (#6592)
* Fix Miri flag passing and bump Rust version. * Fix Miri problems from Arrays PR. SafeSliceAccess was removed for Arrays. It's kind of unsound. It has two properties: 1. EndianSafe 2. Alignment 1 We only need 1. in create_vector_direct to memcpy data. We both 1. and 2. for accessing things with slices as buffers are built on &[u8] which is unaligned. Conditional compilation implements SafeSliceAccess for >1byte scalars (like f32) on LittleEndian machines which is wrong since they don't satisfy 2. This UB is still accessible for Vectors (though not exercised our tests) as it implements SafeSliceAccess. I'll fix this later by splitting SafeSliceAccess into its 2 properties. Co-authored-by: Casper Neo <[email protected]>
1 parent c24031c commit c87179e

File tree

5 files changed

+17
-21
lines changed

5 files changed

+17
-21
lines changed

rust/flatbuffers/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "flatbuffers"
3-
version = "0.8.4"
3+
version = "0.8.5"
44
edition = "2018"
55
authors = ["Robert Winslow <[email protected]>", "FlatBuffers Maintainers"]
66
license = "Apache-2.0"

rust/flatbuffers/src/array.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ impl<'a, T: 'a, const N: usize> Array<'a, T, N> {
5454
pub const fn len(&self) -> usize {
5555
N
5656
}
57+
pub fn as_ptr(&self) -> *const u8 {
58+
self.0.as_ptr()
59+
}
5760
}
5861

5962
impl<'a, T: Follow<'a> + 'a, const N: usize> Array<'a, T, N> {
@@ -77,14 +80,7 @@ impl<'a, T: Follow<'a> + Debug, const N: usize> Into<[T::Inner; N]> for Array<'a
7780
}
7881
}
7982

80-
impl<'a, T: SafeSliceAccess + 'a, const N: usize> Array<'a, T, N> {
81-
pub fn safe_slice(self) -> &'a [T] {
82-
let sz = size_of::<T>();
83-
debug_assert!(sz > 0);
84-
let ptr = self.0.as_ptr() as *const T;
85-
unsafe { from_raw_parts(ptr, N) }
86-
}
87-
}
83+
// TODO(caspern): Implement some future safe version of SafeSliceAccess.
8884

8985
/// Implement Follow for all possible Arrays that have Follow-able elements.
9086
impl<'a, T: Follow<'a> + 'a, const N: usize> Follow<'a> for Array<'a, T, N> {
@@ -100,12 +96,16 @@ pub fn emplace_scalar_array<T: EndianScalar, const N: usize>(
10096
loc: usize,
10197
src: &[T; N],
10298
) {
103-
let mut buf_ptr = buf[loc..].as_mut_ptr() as *mut T;
99+
let mut buf_ptr = buf[loc..].as_mut_ptr();
104100
for item in src.iter() {
105101
let item_le = item.to_little_endian();
106102
unsafe {
107-
buf_ptr.write(item_le);
108-
buf_ptr = buf_ptr.add(1);
103+
core::ptr::copy_nonoverlapping(
104+
&item_le as *const T as *const u8,
105+
buf_ptr,
106+
size_of::<T>(),
107+
);
108+
buf_ptr = buf_ptr.add(size_of::<T>());
109109
}
110110
}
111111
}

tests/RustTest.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,5 +63,5 @@ fi
6363
# RUST_NIGHTLY environment variable set in dockerfile.
6464
if [[ $RUST_NIGHTLY == 1 ]]; then
6565
rustup +nightly component add miri
66-
cargo +nightly miri test -- -Zmiri-disable-isolation
66+
MIRIFLAGS="-Zmiri-disable-isolation" cargo +nightly miri test
6767
fi

tests/rust_usage_test/tests/arrays_test.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -225,8 +225,8 @@ fn verify_struct_array_alignment() {
225225
let array_table = root_as_array_table(buf).unwrap();
226226
let array_struct = array_table.a().unwrap();
227227
let struct_start_ptr = array_struct.0.as_ptr() as usize;
228-
let b_start_ptr = array_struct.b().safe_slice().as_ptr() as usize;
229-
let d_start_ptr = array_struct.d().safe_slice().as_ptr() as usize;
228+
let b_start_ptr = array_struct.b().as_ptr() as usize;
229+
let d_start_ptr = array_struct.d().as_ptr() as usize;
230230
// The T type of b
231231
let b_aln = ::std::mem::align_of::<i32>();
232232
assert_eq!((b_start_ptr - struct_start_ptr) % b_aln, 0);
@@ -272,8 +272,6 @@ mod array_fuzz {
272272
let arr: flatbuffers::Array<$ty, ARRAY_SIZE> = flatbuffers::Array::follow(&test_buf, 0);
273273
let got: [$ty; ARRAY_SIZE] = arr.into();
274274
assert_eq!(got, xs.0);
275-
#[cfg(target_endian = "little")]
276-
assert_eq!(arr.safe_slice(), xs.0);
277275
}
278276
#[test]
279277
fn $test_name() {
@@ -317,13 +315,10 @@ mod array_fuzz {
317315
let arr: flatbuffers::Array<NestedStruct, ARRAY_SIZE> = flatbuffers::Array::follow(&test_buf, 0);
318316
let got: [&NestedStruct; ARRAY_SIZE] = arr.into();
319317
assert_eq!(got, native_struct_array);
320-
let arr_slice = arr.safe_slice();
321-
for i in 0..ARRAY_SIZE {
322-
assert_eq!(arr_slice[i], *native_struct_array[i]);
323-
}
324318
}
325319

326320
#[test]
321+
#[cfg(not(miri))] // slow.
327322
fn test_struct() {
328323
quickcheck::QuickCheck::new().max_tests(MAX_TESTS).quickcheck(prop_struct as fn(FakeArray<NestedStructWrapper, ARRAY_SIZE>));
329324
}

tests/rust_usage_test/tests/integration_test.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,6 +1115,7 @@ mod roundtrip_byteswap {
11151115
// fn fuzz_f64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_f64 as fn(f64)); }
11161116
}
11171117

1118+
#[cfg(not(miri))]
11181119
quickcheck! {
11191120
fn struct_of_structs(
11201121
a_id: u32,

0 commit comments

Comments
 (0)