@@ -116,35 +116,43 @@ impl std::error::Error for MemoryAccessError {}
116
116
/// // First and foremost, any borrow can be invalidated at any time via the
117
117
/// // `Memory::grow` function. This can relocate memory which causes any
118
118
/// // previous pointer to be possibly invalid now.
119
- /// let pointer: &u8 = &*mem.data_ptr(&store);
120
- /// mem.grow(&mut *store, 1)?; // invalidates `pointer`!
121
- /// // println!("{}", *pointer); // FATAL: use-after-free
119
+ /// unsafe {
120
+ /// let pointer: &u8 = &*mem.data_ptr(&store);
121
+ /// mem.grow(&mut *store, 1)?; // invalidates `pointer`!
122
+ /// // println!("{}", *pointer); // FATAL: use-after-free
123
+ /// }
122
124
///
123
125
/// // Note that the use-after-free also applies to slices, whether they're
124
126
/// // slices of bytes or strings.
125
- /// let mem_slice = std::slice::from_raw_parts(
126
- /// mem.data_ptr(&store),
127
- /// mem.data_size(&store),
128
- /// );
129
- /// let slice: &[u8] = &mem_slice[0x100..0x102];
130
- /// mem.grow(&mut *store, 1)?; // invalidates `slice`!
131
- /// // println!("{:?}", slice); // FATAL: use-after-free
127
+ /// unsafe {
128
+ /// let mem_slice = std::slice::from_raw_parts(
129
+ /// mem.data_ptr(&store),
130
+ /// mem.data_size(&store),
131
+ /// );
132
+ /// let slice: &[u8] = &mem_slice[0x100..0x102];
133
+ /// mem.grow(&mut *store, 1)?; // invalidates `slice`!
134
+ /// // println!("{:?}", slice); // FATAL: use-after-free
135
+ /// }
132
136
///
133
137
/// // The `Memory` type may be stored in other locations, so if you hand
134
138
/// // off access to the `Store` then those locations may also call
135
139
/// // `Memory::grow` or similar, so it's not enough to just audit code for
136
140
/// // calls to `Memory::grow`.
137
- /// let pointer: &u8 = &*mem.data_ptr(&store);
138
- /// some_other_function(store); // may invalidate `pointer` through use of `store`
139
- /// // println!("{:?}", pointer); // FATAL: maybe a use-after-free
141
+ /// unsafe {
142
+ /// let pointer: &u8 = &*mem.data_ptr(&store);
143
+ /// some_other_function(store); // may invalidate `pointer` through use of `store`
144
+ /// // println!("{:?}", pointer); // FATAL: maybe a use-after-free
145
+ /// }
140
146
///
141
147
/// // An especially subtle aspect of accessing a wasm instance's memory is
142
148
/// // that you need to be extremely careful about aliasing. Anyone at any
143
149
/// // time can call `data_unchecked()` or `data_unchecked_mut()`, which
144
150
/// // means you can easily have aliasing mutable references:
145
- /// let ref1: &u8 = &*mem.data_ptr(&store).add(0x100);
146
- /// let ref2: &mut u8 = &mut *mem.data_ptr(&store).add(0x100);
147
- /// // *ref2 = *ref1; // FATAL: violates Rust's aliasing rules
151
+ /// unsafe {
152
+ /// let ref1: &u8 = &*mem.data_ptr(&store).add(0x100);
153
+ /// let ref2: &mut u8 = &mut *mem.data_ptr(&store).add(0x100);
154
+ /// // *ref2 = *ref1; // FATAL: violates Rust's aliasing rules
155
+ /// }
148
156
///
149
157
/// Ok(())
150
158
/// }
0 commit comments