This commit is contained in:
Adria Navarro 2024-02-13 16:36:21 +01:00
parent f03d9a0178
commit be69edffd7
3 changed files with 3819 additions and 29 deletions

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
import { EJSON } from "bson" export const bson = {
deserialize: require("bson").deserialize,
export { deserialize } from "bson" toJson: require("bson").EJSON.deserialize,
export const toJson = EJSON.deserialize }

View File

@ -115,9 +115,9 @@ export class IsolatedVM implements VM {
// 4. Stringify the result in order to convert the result from BSON to json // 4. Stringify the result in order to convert the result from BSON to json
this.codeWrapper = code => this.codeWrapper = code =>
`(function(){ `(function(){
const data = deserialize(bsonData, { validation: { utf8: false } }).data; const data = bson.deserialize(bsonData, { validation: { utf8: false } }).data;
const result = ${code} const result = ${code}
return toJson(result); return bson.toJson(result);
})();` })();`
const bsonSource = loadBundle(BundleType.BSON) const bsonSource = loadBundle(BundleType.BSON)
@ -137,7 +137,7 @@ export class IsolatedVM implements VM {
}) })
// "Polyfilling" text decoder. `bson.deserialize` requires decoding. We are creating a bridge function so we don't need to inject the full library // "Polyfilling" text decoder. `bson.deserialize` requires decoding. We are creating a bridge function so we don't need to inject the full library
const textDecoderPolyfill = class TextDecoder { const textDecoderPolyfill = class TextDecoderMock {
constructorArgs constructorArgs
constructor(...constructorArgs: any) { constructor(...constructorArgs: any) {
@ -151,19 +151,11 @@ export class IsolatedVM implements VM {
functionArgs: input, functionArgs: input,
}) })
} }
}.toString() }
const bsonModule = this.isolate.compileModuleSync( .toString()
`${textDecoderPolyfill};${bsonSource}` .replace(/TextDecoderMock/, "TextDecoder")
)
bsonModule.instantiateSync(this.vm, specifier => {
throw new Error(`No imports allowed. Required: ${specifier}`)
})
this.moduleHandler.registerModule( this.moduleHandler.registerModule(`${textDecoderPolyfill};${bsonSource}`)
bsonModule,
"{deserialize, toJson}",
"bson"
)
return this return this
} }
@ -178,13 +170,17 @@ export class IsolatedVM implements VM {
} }
} }
code = `${this.moduleHandler.generateImports()};${this.codeWrapper(code)};` code = `${this.moduleHandler.generateImports()};results.out=${this.codeWrapper(
code
)}`
const script = this.isolate.compileScriptSync(code) const script = this.isolate.compileScriptSync(code)
const result = script.runSync(this.vm, { timeout: this.invocationTimeout }) script.runSync(this.vm, { timeout: this.invocationTimeout })
return result // We can't rely on the script run result as it will not work for non-transferable values
const result = this.getFromContext(this.resultKey)
return result.out
} }
private registerCallbacks(functions: Record<string, any>) { private registerCallbacks(functions: Record<string, any>) {
@ -220,4 +216,11 @@ export class IsolatedVM implements VM {
) )
} }
} }
private getFromContext(key: string) {
const ref = this.vm.global.getSync(key, { reference: true })
const result = ref.copySync()
ref.release()
return result
}
} }