fluentbase_runtime/syscall_handler/host/
read_input.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_input_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_input_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_input_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.input.len() as u32 {
33 Ok(ctx.input[(offset as usize)..(offset as usize + length as usize)].to_vec())
34 } else {
35 Err(ExitCode::InputOutputOutOfBounds)
36 }
37}
38
39#[cfg(test)]
40mod tests {
41 use super::*;
42
43 #[test]
44 fn test_offset_overflow_causes_memory_out_of_bounds() {
45 let mut ctx = RuntimeContext::default();
46 let exit_code = syscall_read_input_impl(&mut ctx, u32::MAX, 100).unwrap_err();
47 assert_eq!(exit_code, ExitCode::InputOutputOutOfBounds);
48 }
49}