diff --git a/soroban-env-host/src/test/hostile.rs b/soroban-env-host/src/test/hostile.rs index 10b759028..1374ba01a 100644 --- a/soroban-env-host/src/test/hostile.rs +++ b/soroban-env-host/src/test/hostile.rs @@ -116,3 +116,37 @@ fn hostile_objs_traps() -> Result<(), HostError> { )); Ok(()) } + +use soroban_synth_wasm::{Arity, ModEmitter, Operand}; + +fn wasm_module_with_mem_grow(n_pages: usize) -> Vec { + let mut fe = ModEmitter::new().func(Arity(0), 0); + fe.push(Operand::Const32(n_pages as i32)); + fe.memory_grow(); + // need to drop the return value on the stack because it's an i32 + // and the function needs an i64 return value. + fe.drop(); + fe.push(Symbol::try_from_small_str("pass").unwrap()); + fe.finish_and_export("test").finish() +} + +#[test] +fn excessive_memory_growth() -> Result<(), HostError> { + let wasm = wasm_module_with_mem_grow(32); + let host = Host::test_host_with_recording_footprint(); + let contract_id_obj = host.register_test_contract_wasm(wasm.as_slice()); + host.set_diagnostic_level(crate::DiagnosticLevel::Debug)?; + + // This one should just run out of memory + let res = host.call( + contract_id_obj, + Symbol::try_from_small_str("test")?, + host.add_host_object(HostVec::new())?, + ); + + assert!(HostError::result_matches_err( + res, + (ScErrorType::Budget, ScErrorCode::ExceededLimit) + )); + Ok(()) +}