Skip to content

Commit

Permalink
fix(ext/node): promise rejection in VM contexts (#23305)
Browse files Browse the repository at this point in the history
Fixes #23297

`docusaurus build` works!

```
$ deno run -A repro.js 
fish: Job 1, 'deno run -A ../../littledivy/fs…' terminated by signal SIGSEGV (Address
 boundary error)
$ denod run -A repro.js
error: Uncaught (in promise) Error: rejected
```

Depends on denoland/deno_core#693
  • Loading branch information
littledivy authored Apr 13, 2024
1 parent 720e45d commit 402d59e
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 3 deletions.
14 changes: 11 additions & 3 deletions ext/node/ops/vm_internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use deno_core::error::type_error;
use deno_core::error::AnyError;
use deno_core::v8;
use deno_core::v8::MapFnTo;
use std::rc::Rc;

pub const PRIVATE_SYMBOL_NAME: v8::OneByteConst =
v8::String::create_external_onebyte_const(b"node:contextify:context");
Expand Down Expand Up @@ -75,13 +76,19 @@ impl ContextifyContext {
Self::from_context(scope, context, sandbox_obj);
}

pub fn from_context(
fn from_context(
scope: &mut v8::HandleScope,
v8_context: v8::Local<v8::Context>,
sandbox_obj: v8::Local<v8::Object>,
) {
let main_context = scope.get_current_context();
let context_state = main_context
.get_slot::<Rc<deno_core::ContextState>>(scope)
.unwrap()
.clone();

v8_context.set_security_token(main_context.get_security_token(scope));
v8_context.set_slot(scope, context_state);

let context = v8::Global::new(scope, v8_context);
let sandbox = v8::Global::new(scope, sandbox_obj);
Expand All @@ -95,7 +102,7 @@ impl ContextifyContext {
// lives longer than the execution context, so this should be safe.
unsafe {
v8_context.set_aligned_pointer_in_embedder_data(
0,
1,
ptr as *const ContextifyContext as _,
);
}
Expand Down Expand Up @@ -157,7 +164,7 @@ impl ContextifyContext {
) -> Option<&'c ContextifyContext> {
let context = object.get_creation_context(scope)?;

let context_ptr = context.get_aligned_pointer_from_embedder_data(0);
let context_ptr = context.get_aligned_pointer_from_embedder_data(1);
// SAFETY: We are storing a pointer to the ContextifyContext
// in the embedder data of the v8::Context during creation.
Some(unsafe { &*(context_ptr as *const ContextifyContext) })
Expand Down Expand Up @@ -228,6 +235,7 @@ fn init_global_template_inner(scope: &mut v8::HandleScope) {
let global_func_template =
v8::FunctionTemplate::builder_raw(c_noop).build(scope);
let global_object_template = global_func_template.instance_template(scope);
global_object_template.set_internal_field_count(2);

let named_property_handler_config = {
let mut config = v8::NamedPropertyHandlerConfiguration::new()
Expand Down
16 changes: 16 additions & 0 deletions tests/unit_node/vm_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,19 @@ Deno.test({
assertEquals(isContext(sandbox), false);
},
});

// https://github.com/denoland/deno/issues/23297
Deno.test({
name: "vm context promise rejection",
fn() {
const code = `
function reject() {
return Promise.reject(new Error('rejected'));
}
reject().catch(() => {})
`;

const script = new Script(code);
script.runInNewContext();
},
});

0 comments on commit 402d59e

Please sign in to comment.