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/",
|
"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",
|
"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-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",
|
"build:dev": "yarn prebuild && tsc --build --watch --preserveWatchOutput",
|
||||||
"debug": "yarn build && node --expose-gc --inspect=9222 dist/index.js",
|
"debug": "yarn build && node --expose-gc --inspect=9222 dist/index.js",
|
||||||
"jest": "NODE_OPTIONS=\"--no-node-snapshot $NODE_OPTIONS\" jest",
|
"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 ivm from "isolated-vm"
|
||||||
|
|
||||||
|
import bson from "bson"
|
||||||
|
|
||||||
const JS_TIMEOUT_MS = 1000
|
const JS_TIMEOUT_MS = 1000
|
||||||
|
|
||||||
class ScriptRunner {
|
class ScriptRunner {
|
||||||
vm: IsolatedVM
|
vm: IsolatedVM
|
||||||
|
|
||||||
constructor(script: string, context: any) {
|
constructor(script: string, context: any) {
|
||||||
const code = `let fn = () => {\n${script}\n}; results.out = fn();`
|
this.vm = new IsolatedVM({ memoryLimit: 64 })
|
||||||
this.vm = new IsolatedVM({ memoryLimit: 8 })
|
|
||||||
this.vm.context = {
|
this.vm.context = {
|
||||||
...context,
|
...context,
|
||||||
|
data: bson.BSON.serialize({ data: context.data }),
|
||||||
results: { out: "" },
|
results: { out: "" },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const code = `let fn = () => {data=deserialize(data).data;\n${script}\n}; cb(JSON.parse(JSON.stringify(fn())));`
|
||||||
this.vm.code = code
|
this.vm.code = code
|
||||||
}
|
}
|
||||||
|
|
||||||
execute() {
|
execute() {
|
||||||
this.vm.runScript()
|
const result = this.vm.runScript()
|
||||||
const results = this.vm.getValue("results")
|
return result
|
||||||
return results.out
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +29,8 @@ class IsolatedVM {
|
||||||
isolate: ivm.Isolate
|
isolate: ivm.Isolate
|
||||||
vm: ivm.Context
|
vm: ivm.Context
|
||||||
#jail: ivm.Reference
|
#jail: ivm.Reference
|
||||||
script: any
|
script: ivm.Module = undefined!
|
||||||
|
#bsonModule: ivm.Module = undefined!
|
||||||
|
|
||||||
constructor({ memoryLimit }: { memoryLimit: number }) {
|
constructor({ memoryLimit }: { memoryLimit: number }) {
|
||||||
this.isolate = new ivm.Isolate({ memoryLimit })
|
this.isolate = new ivm.Isolate({ memoryLimit })
|
||||||
|
@ -49,11 +53,38 @@ class IsolatedVM {
|
||||||
}
|
}
|
||||||
|
|
||||||
set code(code: string) {
|
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() {
|
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> {
|
copyRefToVm(value: Object): ivm.Copy<Object> {
|
||||||
|
|
Loading…
Reference in New Issue