Skip to content
This repository was archived by the owner on Sep 27, 2023. It is now read-only.

Commit 0194063

Browse files
Always call methods on references in a macro
The macro scope cannot be trusted to not contain trait implementations which try to break this crate. To avoid this, explicitly reference variables on which methods are called.
1 parent eb1d812 commit 0194063

File tree

2 files changed

+16
-3
lines changed

2 files changed

+16
-3
lines changed

src/lib.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ macro_rules! array {
7979
#[allow(unsafe_code)]
8080
fn create_arr<T>(mut callback: impl FnMut(usize) -> T) -> [T; COUNT] {
8181
let mut arr = $crate::__core::mem::MaybeUninit::uninit();
82-
let mut vec = $crate::__ArrayVec::<T>::new(arr.as_mut_ptr() as *mut T);
82+
let mut vec = $crate::__ArrayVec::<T>::new((&mut arr).as_mut_ptr() as *mut T);
8383
unsafe {
8484
// Loop invariant: vec[..vec.length] is valid
8585
for i in 0..COUNT {
@@ -90,8 +90,8 @@ macro_rules! array {
9090
//
9191
// The value is set before writing the value to avoid need to perform
9292
// addition by 1.
93-
*vec.length() = i;
94-
$crate::__core::ptr::write(vec.start().add(i), callback(i));
93+
*(&mut vec).length() = i;
94+
$crate::__core::ptr::write((&vec).start().add(i), callback(i));
9595
}
9696
// Loop escaped without panicking, avoid dropping elements.
9797
$crate::__core::mem::forget(vec);

tests/test.rs

+13
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,16 @@ fn array_of_void_panic_safety() {
108108
}
109109
internal(|| -> ! { panic!() });
110110
}
111+
112+
#[test]
113+
fn malicious_length() {
114+
trait Evil {
115+
fn length(&self) -> *mut usize;
116+
}
117+
impl<T> Evil for T {
118+
fn length(&self) -> *mut usize {
119+
42 as *mut usize
120+
}
121+
}
122+
assert_eq!(array![1; 3], [1, 1, 1]);
123+
}

0 commit comments

Comments
 (0)