pub trait MemoryLike {
// Required methods
fn fits_memory(&self, slice: MemSlice) -> Result<(), ()>;
fn view_memory(&self, slice: MemSlice) -> Result<Cow<'_, [u8]>, ()>;
fn read_memory(&self, offset: u64, buffer: &mut [u8]) -> Result<(), ()>;
fn write_memory(&mut self, offset: u64, buffer: &[u8]) -> Result<(), ()>;
}
Expand description
An abstraction over the memory of the smart contract.
Required Methods§
Sourcefn fits_memory(&self, slice: MemSlice) -> Result<(), ()>
fn fits_memory(&self, slice: MemSlice) -> Result<(), ()>
Returns success if the memory interval is completely inside smart contract’s memory.
You often don’t need to use this method since other methods will perform
the check, however it may be necessary to prevent potential denial of
service attacks. See Self::read_memory
for description.
Sourcefn view_memory(&self, slice: MemSlice) -> Result<Cow<'_, [u8]>, ()>
fn view_memory(&self, slice: MemSlice) -> Result<Cow<'_, [u8]>, ()>
Returns view of the content of the given memory interval.
Not all implementations support borrowing the memory directly. In those cases, the data is copied into a vector.
Sourcefn read_memory(&self, offset: u64, buffer: &mut [u8]) -> Result<(), ()>
fn read_memory(&self, offset: u64, buffer: &mut [u8]) -> Result<(), ()>
Reads the content of the given memory interval.
Returns error if the memory interval isn’t completely inside the smart contract memory.
§Potential denial of service
Note that improper use of this function may lead to denial of service attacks. For example, consider the following function:
fn read_vec(mem: &dyn MemoryLike, slice: MemSlice) -> Result<Vec<u8>, ()> {
let mut vec = vec![0; slice.len()?];
mem.read_memory(slice.ptr, &mut vec[..])?;
Ok(vec)
}
If attacker controls length argument, it may cause attempt at allocation
of arbitrarily-large buffer and crash the program. In situations like
this, it’s necessary to use Self::fits_memory
method to verify that
the length is valid. For example:
fn read_vec(mem: &dyn MemoryLike, slice: MemSlice) -> Result<Vec<u8>, ()> {
mem.fits_memory(slice)?;
let mut vec = vec![0; slice.len()?];
mem.read_memory(slice.ptr, &mut vec[..])?;
Ok(vec)
}