fluentbase_runtime/syscall_handler/host/
read_output.rs1use crate::syscall_handler::syscall_process_exit_code;
3use crate::RuntimeContext;
4use fluentbase_types::ExitCode;
5use rwasm::{StoreTr, TrapCode, Value};
6
7pub fn syscall_read_output_handler(
9 ctx: &mut impl StoreTr<RuntimeContext>,
10 params: &[Value],
11 _result: &mut [Value],
12) -> Result<(), TrapCode> {
13 let (target_ptr, offset, length) = (
14 params[0].i32().unwrap() as usize,
15 params[1].i32().unwrap() as u32,
16 params[2].i32().unwrap() as u32,
17 );
18 let input = syscall_read_output_impl(ctx.data_mut(), offset, length)
19 .map_err(|exit_code| syscall_process_exit_code(ctx, exit_code))?;
20 ctx.memory_write(target_ptr, &input)?;
21 Ok(())
22}
23
24pub fn syscall_read_output_impl(
25 ctx: &mut RuntimeContext,
26 offset: u32,
27 length: u32,
28) -> Result<Vec<u8>, ExitCode> {
29 let offset_length = offset
30 .checked_add(length)
31 .ok_or(ExitCode::InputOutputOutOfBounds)?;
32 if offset_length <= ctx.execution_result.return_data.len() as u32 {
33 Ok(
34 ctx.execution_result.return_data
35 [(offset as usize)..(offset as usize + length as usize)]
36 .to_vec(),
37 )
38 } else {
39 Err(ExitCode::InputOutputOutOfBounds)
40 }
41}
42
43#[cfg(test)]
44mod tests {
45 use super::*;
46
47 #[test]
48 fn test_offset_overflow_causes_memory_out_of_bounds() {
49 let mut ctx = RuntimeContext::default();
50 let exit_code = syscall_read_output_impl(&mut ctx, u32::MAX, 100).unwrap_err();
51 assert_eq!(exit_code, ExitCode::InputOutputOutOfBounds);
52 }
53}