diff --git a/packages/server/src/jsRunner/vm/index.ts b/packages/server/src/jsRunner/vm/index.ts index 45e2ebcf09..6be00f0796 100644 --- a/packages/server/src/jsRunner/vm/index.ts +++ b/packages/server/src/jsRunner/vm/index.ts @@ -131,13 +131,16 @@ export class IsolatedVM implements VM { withContext(context: Record) { this.#addToContext(context) - this.#handleBsonData() + return this } - withParsingBson() { + withParsingBson(data: any) { this.#parseBson = true - this.#handleBsonData() + + this.#addToContext({ + bsonData: bson.BSON.serialize(data), + }) const bsonSource = loadBundle(BundleType.BSON) const bsonModule = this.#isolate.compileModuleSync(bsonSource) @@ -149,21 +152,6 @@ export class IsolatedVM implements VM { return this } - #handleBsonData() { - if (!this.#parseBson) { - return - } - - const data = this.#getFromContext("data") - if (!data) { - return - } - - this.#addToContext({ - data: bson.BSON.serialize({ data }), - }) - } - execute(code: string): string { const perRequestLimit = this.#perRequestLimit @@ -182,12 +170,11 @@ export class IsolatedVM implements VM { // 2. Deserialise the data within the isolate, to get the original data // 3. Process script // 4. Stringify the result in order to convert the result from BSON to json - code = `toJson( - (function(){ - data= deserialize(data).data; - return ${code}; - })() - );` + code = `(function(){ + const data= deserialize(bsonData); + const result = ${code} + return toJson(result); + })();` } code = `${this.#moduleHandler.generateImports()};results.out=${code};` diff --git a/packages/server/src/utilities/scriptRunner.ts b/packages/server/src/utilities/scriptRunner.ts index ed69d35186..c2add13eeb 100644 --- a/packages/server/src/utilities/scriptRunner.ts +++ b/packages/server/src/utilities/scriptRunner.ts @@ -13,8 +13,8 @@ class ScriptRunner { timeout: JS_TIMEOUT_MS, }).withContext(context) - if (parseBson) { - this.#vm = this.#vm.withParsingBson() + if (parseBson && context.data) { + this.#vm = this.#vm.withParsingBson(context.data) } } @@ -24,114 +24,4 @@ class ScriptRunner { } } -// <<<<<<< HEAD -// constructor(script: string, context: any, { parseBson = false } = {}) { -// this.vm = new IsolatedVM({ -// memoryLimit: env.JS_RUNNER_MEMORY_LIMIT, -// parseBson, -// context: { -// ...context, -// data: parseBson -// ? bson.BSON.serialize({ data: context.data }) -// : context.data, -// }, -// }) - -// if (parseBson) { -// // If we need to parse bson, we follow the next steps: -// // 1. Serialise the data from potential BSON to buffer before passing it to the isolate -// // 2. Deserialise the data within the isolate, to get the original data -// // 3. Process script -// // 4. Stringify the result in order to convert the result from BSON to json -// script = `return toJson((function(){data=deserialize(data, { validation: { utf8: true } }).data;${script}})());` -// } - -// this.vm.code = script -// } - -// execute() { -// this.vm.runScript() -// const result = this.vm.getResult() -// return result -// } -// } - -// class IsolatedVM { -// #isolate: ivm.Isolate -// #vm: ivm.Context -// #jail: ivm.Reference -// #script: ivm.Module = undefined! -// #bsonModule?: ivm.Module - -// readonly #resultKey = "results" - -// constructor({ -// memoryLimit, -// parseBson, -// context, -// }: { -// memoryLimit: number -// parseBson: boolean -// context: Record -// }) { -// this.#isolate = new ivm.Isolate({ memoryLimit }) -// this.#vm = this.#isolate.createContextSync() -// this.#jail = this.#vm.global -// this.#jail.setSync("global", this.#jail.derefInto()) - -// this.#addToContext(context) -// this.#addToContext({ -// [this.#resultKey]: { out: "" }, -// }) - -// if (parseBson) { -// const bsonSource = loadBundle(BundleType.BSON) -// this.#bsonModule = this.#isolate.compileModuleSync(bsonSource) -// this.#bsonModule.instantiateSync(this.#vm, specifier => { -// throw new Error(`No imports allowed. Required: ${specifier}`) -// }) -// } -// } - -// getResult() { -// const ref = this.#vm.global.getSync(this.#resultKey, { reference: true }) -// const result = ref.copySync() -// ref.release() -// return result.out -// } - -// #addToContext(context: Record) { -// for (let key in context) { -// this.#jail.setSync(key, this.#copyRefToVm(context[key])) -// } -// } - -// set code(code: string) { -// code = `const fn=function(){${code}};results.out=fn();` -// if (this.#bsonModule) { -// code = `import {deserialize, toJson} from "compiled_module";${code}` -// } -// this.#script = this.#isolate.compileModuleSync(code) -// } - -// runScript(): void { -// this.#script.instantiateSync(this.#vm, specifier => { -// if (specifier === "compiled_module" && this.#bsonModule) { -// return this.#bsonModule! -// } - -// throw new Error(`"${specifier}" import not allowed`) -// }) - -// this.#script.evaluateSync({ timeout: JS_TIMEOUT_MS }) -// } - -// #copyRefToVm(value: Object): ivm.Copy { -// return new ivm.ExternalCopy(value).copyInto({ release: true }) -// } -// ======= - -// >>>>>>> isolated-vm-wrapper -// } - export default ScriptRunner