probably actually fix the wasi ptr array bug now

This commit is contained in:
Mark McCaskey 2019-06-06 16:19:15 -07:00
parent d7ea46bab7
commit 811acd7e68
2 changed files with 26 additions and 24 deletions

View File

@ -57,22 +57,23 @@ impl<T: Copy + ValueType> WasmPtr<T, Item> {
impl<T: Copy + ValueType> WasmPtr<T, Array> { impl<T: Copy + ValueType> WasmPtr<T, Array> {
#[inline] #[inline]
pub fn deref<'a>(self, memory: &'a Memory, index: u32, length: u32) -> Option<&'a [Cell<T>]> { pub fn deref<'a>(self, memory: &'a Memory, index: u32, length: u32) -> Option<&'a [Cell<T>]> {
if (self.offset as usize) + (mem::size_of::<T>() * ((index + length) as usize))
>= memory.size().bytes().0
{
return None;
}
// gets the size of the item in the array with padding added such that // gets the size of the item in the array with padding added such that
// for any index, we will always result an aligned memory access // for any index, we will always result an aligned memory access
let item_size = mem::size_of::<T>() + (mem::size_of::<T>() % mem::align_of::<T>()); let item_size = mem::size_of::<T>() + (mem::size_of::<T>() % mem::align_of::<T>());
let base_idx = (self.offset as usize) / item_size; let slice_full_len = index as usize + length as usize;
if (self.offset as usize) + (item_size * slice_full_len) >= memory.size().bytes().0 {
return None;
}
unsafe { unsafe {
let cell_ptrs = memory let cell_ptr = align_pointer(
.view::<T>() memory.view::<u8>().as_ptr().add(self.offset as usize) as usize,
.get_unchecked(base_idx + (index as usize)..base_idx + ((index + length) as usize)) mem::align_of::<T>(),
as *const _; ) as *const Cell<T>;
Some(&*cell_ptrs) let cell_ptrs = &std::slice::from_raw_parts(cell_ptr, slice_full_len)
[index as usize..length as usize];
Some(cell_ptrs)
} }
} }
} }

View File

@ -60,22 +60,23 @@ impl<T: Copy + ValueType> WasmPtr<T, Array> {
index: u32, index: u32,
length: u32, length: u32,
) -> Result<&'a [Cell<T>], __wasi_errno_t> { ) -> Result<&'a [Cell<T>], __wasi_errno_t> {
if (self.offset as usize) + (mem::size_of::<T>() * ((index + length) as usize))
>= memory.size().bytes().0
{
return Err(__WASI_EFAULT);
}
// gets the size of the item in the array with padding added such that // gets the size of the item in the array with padding added such that
// for any index, we will always result an aligned memory access // for any index, we will always result an aligned memory access
let item_size = mem::size_of::<T>() + (mem::size_of::<T>() % mem::align_of::<T>()); let item_size = mem::size_of::<T>() + (mem::size_of::<T>() % mem::align_of::<T>());
let base_idx = (self.offset as usize) / item_size; let slice_full_len = index as usize + length as usize;
if (self.offset as usize) + (item_size * slice_full_len) >= memory.size().bytes().0 {
return Err(__WASI_EFAULT);
}
unsafe { unsafe {
let cell_ptrs = memory let cell_ptr = align_pointer(
.view::<T>() memory.view::<u8>().as_ptr().add(self.offset as usize) as usize,
.get_unchecked(base_idx + (index as usize)..base_idx + ((index + length) as usize)) mem::align_of::<T>(),
as *const _; ) as *const Cell<T>;
Ok(&*cell_ptrs) let cell_ptrs = &std::slice::from_raw_parts(cell_ptr, slice_full_len)
[index as usize..length as usize];
Ok(cell_ptrs)
} }
} }
} }