From 01e5bbadacbb8302984a19a538f0ae4067adfce2 Mon Sep 17 00:00:00 2001 From: Andreu Botella Date: Mon, 30 May 2022 13:18:32 +0200 Subject: [PATCH] test(core): Test that sync ops return/throw objects in the right realm (#14750) This behavior was introduced in #14019 but wasn't properly tested in that PR. --- core/runtime.rs | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/core/runtime.rs b/core/runtime.rs index cf7980fb4d..3578b216ae 100644 --- a/core/runtime.rs +++ b/core/runtime.rs @@ -3400,4 +3400,52 @@ assertEquals(1, notify_return_value); let scope = &mut realm.handle_scope(&mut runtime); assert_eq!(ret, serde_v8::to_v8(scope, "Test").unwrap()); } + + #[test] + fn js_realm_sync_ops() { + // Test that returning a ZeroCopyBuf and throwing an exception from a sync + // op result in objects with prototypes from the right realm. Note that we + // don't test the result of returning structs, because they will be + // serialized to objects with null prototype. + + #[op] + fn op_test(fail: bool) -> Result { + if !fail { + Ok(ZeroCopyBuf::empty()) + } else { + Err(crate::error::type_error("Test")) + } + } + + let mut runtime = JsRuntime::new(RuntimeOptions { + extensions: vec![Extension::builder().ops(vec![op_test::decl()]).build()], + get_error_class_fn: Some(&|error| { + crate::error::get_custom_error_class(error).unwrap() + }), + ..Default::default() + }); + let new_realm = runtime.create_realm().unwrap(); + + // Test in both realms + for realm in [runtime.global_realm(), new_realm].into_iter() { + let ret = realm + .execute_script( + &mut runtime, + "", + r#" + const buf = Deno.core.opSync("op_test", false); + let err; + try { + Deno.core.opSync("op_test", true); + } catch(e) { + err = e; + } + buf instanceof Uint8Array && buf.byteLength === 0 && + err instanceof TypeError && err.message === "Test" + "#, + ) + .unwrap(); + assert!(ret.open(runtime.v8_isolate()).is_true()); + } + } }