diff --git a/packages/server/src/jsRunner/bundles/bson-polyfills.ivm.bundle.js b/packages/server/src/jsRunner/bundles/bson-polyfills.ivm.bundle.js new file mode 100644 index 0000000000..e8147c63da --- /dev/null +++ b/packages/server/src/jsRunner/bundles/bson-polyfills.ivm.bundle.js @@ -0,0 +1,6 @@ +function atob(...args){ + return atobCB(...args) +} +function btoa(...args){ + return btoaCB(...args) +} diff --git a/packages/server/src/jsRunner/bundles/index.ts b/packages/server/src/jsRunner/bundles/index.ts index b62adac1cc..3a00ee96cc 100644 --- a/packages/server/src/jsRunner/bundles/index.ts +++ b/packages/server/src/jsRunner/bundles/index.ts @@ -5,6 +5,7 @@ export const enum BundleType { BSON = "bson", SNIPPETS = "snippets", BUFFER = "buffer", + BSON_POLYFILLS = "bson_polyfills", } const bundleSourceFile: Record = { @@ -12,6 +13,7 @@ const bundleSourceFile: Record = { [BundleType.BSON]: "./bson.ivm.bundle.js", [BundleType.SNIPPETS]: "./snippets.ivm.bundle.js", [BundleType.BUFFER]: "./buffer.ivm.bundle.js", + [BundleType.BSON_POLYFILLS]: "./bson-polyfills.ivm.bundle.js", } const bundleSourceCode: Partial> = {} diff --git a/packages/server/src/jsRunner/vm/isolated-vm.ts b/packages/server/src/jsRunner/vm/isolated-vm.ts index 3863be742d..65a2615ed7 100644 --- a/packages/server/src/jsRunner/vm/isolated-vm.ts +++ b/packages/server/src/jsRunner/vm/isolated-vm.ts @@ -173,30 +173,21 @@ export class IsolatedVM implements VM { return result } ), + atobCB: new ivm.Callback((...args: Parameters) => { + const result = atob(...args) + return result + }), + btoaCB: new ivm.Callback((...args: Parameters) => { + const result = btoa(...args) + return result + }), }) - // "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 TextDecoderMock { - constructorArgs - - constructor(...constructorArgs: any) { - this.constructorArgs = constructorArgs - } - - decode(...input: any) { - // @ts-expect-error - this is going to run in the isolate, where this function will be available - // eslint-disable-next-line no-undef - return textDecoderCb({ - constructorArgs: this.constructorArgs, - functionArgs: input, - }) - } - } - .toString() - .replace(/TextDecoderMock/, "TextDecoder") + // "Polyfilling" text decoder and other utils. `bson.deserialize` requires decoding. We are creating a bridge function so we don't need to inject the full library + const bsonPolyfills = loadBundle(BundleType.BSON_POLYFILLS) const script = this.isolate.compileScriptSync( - `${textDecoderPolyfill};${bsonSource}` + `${bsonPolyfills};${bsonSource}` ) script.runSync(this.vm, { timeout: this.invocationTimeout, release: false }) new Promise(() => {