Use bson in isolated-vm
This commit is contained in:
parent
2c95920f65
commit
a273276bd3
|
@ -14,7 +14,8 @@
|
|||
"postbuild": "copyfiles -f ../client/dist/budibase-client.js ../client/manifest.json client && copyfiles -f ../../yarn.lock ./dist/",
|
||||
"check:types": "tsc -p tsconfig.json --noEmit --paths null",
|
||||
"build:isolated-vm-lib:string-templates": "esbuild --minify --bundle src/jsRunner/bundles/index-helpers.ts --outfile=src/jsRunner/bundles/index-helpers.ivm.bundle.js --platform=node --format=esm --external:handlebars",
|
||||
"build:isolated-vm-libs": "yarn build:isolated-vm-lib:string-templates",
|
||||
"build:isolated-vm-lib:bson": "esbuild --minify --bundle src/jsRunner/bundles/bsonPackage.ts --outfile=src/jsRunner/bundles/bson.ivm.bundle.js --platform=node --format=esm",
|
||||
"build:isolated-vm-libs": "yarn build:isolated-vm-lib:string-templates && yarn build:isolated-vm-lib:bson",
|
||||
"build:dev": "yarn prebuild && tsc --build --watch --preserveWatchOutput",
|
||||
"debug": "yarn build && node --expose-gc --inspect=9222 dist/index.js",
|
||||
"jest": "NODE_OPTIONS=\"--no-node-snapshot $NODE_OPTIONS\" jest",
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
export { deserialize } from "bson"
|
|
@ -1,24 +1,27 @@
|
|||
import ivm from "isolated-vm"
|
||||
|
||||
import bson from "bson"
|
||||
|
||||
const JS_TIMEOUT_MS = 1000
|
||||
|
||||
class ScriptRunner {
|
||||
vm: IsolatedVM
|
||||
|
||||
constructor(script: string, context: any) {
|
||||
const code = `let fn = () => {\n${script}\n}; results.out = fn();`
|
||||
this.vm = new IsolatedVM({ memoryLimit: 8 })
|
||||
this.vm = new IsolatedVM({ memoryLimit: 64 })
|
||||
this.vm.context = {
|
||||
...context,
|
||||
data: bson.BSON.serialize({ data: context.data }),
|
||||
results: { out: "" },
|
||||
}
|
||||
|
||||
const code = `let fn = () => {data=deserialize(data).data;\n${script}\n}; cb(JSON.parse(JSON.stringify(fn())));`
|
||||
this.vm.code = code
|
||||
}
|
||||
|
||||
execute() {
|
||||
this.vm.runScript()
|
||||
const results = this.vm.getValue("results")
|
||||
return results.out
|
||||
const result = this.vm.runScript()
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,7 +29,8 @@ class IsolatedVM {
|
|||
isolate: ivm.Isolate
|
||||
vm: ivm.Context
|
||||
#jail: ivm.Reference
|
||||
script: any
|
||||
script: ivm.Module = undefined!
|
||||
#bsonModule: ivm.Module = undefined!
|
||||
|
||||
constructor({ memoryLimit }: { memoryLimit: number }) {
|
||||
this.isolate = new ivm.Isolate({ memoryLimit })
|
||||
|
@ -49,11 +53,38 @@ class IsolatedVM {
|
|||
}
|
||||
|
||||
set code(code: string) {
|
||||
this.script = this.isolate.compileScriptSync(code)
|
||||
const bsonSource = require("../jsRunner/bundles/bson.ivm.bundle.js")
|
||||
|
||||
this.#bsonModule = this.isolate.compileModuleSync(bsonSource)
|
||||
this.#bsonModule.instantiateSync(this.vm, specifier => {
|
||||
throw new Error(`No imports allowed. Required: ${specifier}`)
|
||||
})
|
||||
|
||||
this.script = this.isolate.compileModuleSync(
|
||||
`import {deserialize} from "compiled_module";${code}`
|
||||
)
|
||||
}
|
||||
|
||||
runScript() {
|
||||
this.script.runSync(this.vm, { timeout: JS_TIMEOUT_MS })
|
||||
this.script.instantiateSync(this.vm, specifier => {
|
||||
if (specifier === "compiled_module") {
|
||||
return this.#bsonModule
|
||||
}
|
||||
|
||||
throw new Error(`"${specifier}" import not allowed`)
|
||||
})
|
||||
|
||||
let result
|
||||
this.vm.global.setSync(
|
||||
"cb",
|
||||
new ivm.Callback((value: any) => {
|
||||
result = value
|
||||
})
|
||||
)
|
||||
|
||||
this.script.evaluateSync({ timeout: JS_TIMEOUT_MS })
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
copyRefToVm(value: Object): ivm.Copy<Object> {
|
||||
|
|
Loading…
Reference in New Issue