From ab870c5bd8fe41e0bc3ba3d3aabf736deac60624 Mon Sep 17 00:00:00 2001 From: Kai Tamkun Date: Thu, 24 Apr 2025 14:06:48 -0700 Subject: [PATCH] Add test-vm-codegen.js (currently modified pending clarification from JSC team) --- src/bun.js/bindings/NodeVM.cpp | 4 +- test/js/node/test/parallel/test-vm-codegen.js | 101 ++++++++++++++++++ 2 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 test/js/node/test/parallel/test-vm-codegen.js diff --git a/src/bun.js/bindings/NodeVM.cpp b/src/bun.js/bindings/NodeVM.cpp index 9b1627608d..85dee30bdc 100644 --- a/src/bun.js/bindings/NodeVM.cpp +++ b/src/bun.js/bindings/NodeVM.cpp @@ -164,8 +164,8 @@ Structure* NodeVMGlobalObject::createStructure(JSC::VM& vm, JSC::JSValue prototy void NodeVMGlobalObject::finishCreation(JSC::VM&, NodeVMContextOptions options) { Base::finishCreation(vm()); - setEvalEnabled(options.allowStrings, "TODO(@heimskr)"_s); - setWebAssemblyEnabled(options.allowWasm, "TODO(@heimskr)"_s); + setEvalEnabled(options.allowStrings, "Code generation from strings disallowed for this context"_s); + setWebAssemblyEnabled(options.allowWasm, "Wasm code generation disallowed by embedder"_s); } void NodeVMGlobalObject::destroy(JSCell* cell) diff --git a/test/js/node/test/parallel/test-vm-codegen.js b/test/js/node/test/parallel/test-vm-codegen.js new file mode 100644 index 0000000000..cda84c6432 --- /dev/null +++ b/test/js/node/test/parallel/test-vm-codegen.js @@ -0,0 +1,101 @@ +'use strict'; + +require('../common'); +const assert = require('assert'); + +const { createContext, runInContext, runInNewContext } = require('vm'); + +const WASM_BYTES = Buffer.from( + [0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00]); + +{ + const ctx = createContext({ WASM_BYTES }); + const test = 'eval(""); new WebAssembly.Module(WASM_BYTES);'; + runInContext(test, ctx); + + runInNewContext(test, { WASM_BYTES }, { + contextCodeGeneration: undefined, + }); +} + +{ + const ctx = createContext({}, { + codeGeneration: { + strings: false, + }, + }); + + const EvalError = runInContext('EvalError', ctx); + assert.throws(() => { + runInContext('eval("x")', ctx); + }, EvalError); +} + +{ + const ctx = createContext({ WASM_BYTES }, { + codeGeneration: { + wasm: false, + }, + }); + + const CompileError = runInContext('WebAssembly.CompileError', ctx); + assert.rejects(() => { + return runInContext('try { WebAssembly.instantiate(new WebAssembly.Module(WASM_BYTES)); } catch (e) { Promise.reject(e); }', ctx); + }, CompileError); +} + +assert.throws(() => { + runInNewContext('eval("x")', {}, { + contextCodeGeneration: { + strings: false, + }, + }); +}, { + name: 'EvalError' +}); + +assert.rejects(() => { + return runInNewContext('try { WebAssembly.instantiate(new WebAssembly.Module(WASM_BYTES)); } catch (e) { Promise.reject(e); }', { WASM_BYTES }, { + contextCodeGeneration: { + wasm: false, + }, + }); +}, { + name: 'CompileError' +}); + +assert.throws(() => { + createContext({}, { + codeGeneration: { + strings: 0, + }, + }); +}, { + code: 'ERR_INVALID_ARG_TYPE', +}); + +assert.throws(() => { + runInNewContext('eval("x")', {}, { + contextCodeGeneration: { + wasm: 1, + }, + }); +}, { + code: 'ERR_INVALID_ARG_TYPE' +}); + +assert.throws(() => { + createContext({}, { + codeGeneration: 1, + }); +}, { + code: 'ERR_INVALID_ARG_TYPE', +}); + +assert.throws(() => { + createContext({}, { + codeGeneration: null, + }); +}, { + code: 'ERR_INVALID_ARG_TYPE', +});