From f6c0d045e9683cd04ee849f37b96697097c5b41d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=A4=95=E0=A4=BE=E0=A4=B0=E0=A4=A4=E0=A5=8B=E0=A4=AB?= =?UTF-8?q?=E0=A5=8D=E0=A4=AB=E0=A5=87=E0=A4=B2=E0=A4=B8=E0=A5=8D=E0=A4=95?= =?UTF-8?q?=E0=A5=8D=E0=A4=B0=E0=A4=BF=E0=A4=AA=E0=A5=8D=E0=A4=9F=E2=84=A2?= Date: Wed, 27 Nov 2024 12:08:16 +0100 Subject: [PATCH] fix(core): Don't use unbound context methods in code sandboxes (#11914) --- .../nodes-langchain/nodes/code/Code.node.ts | 29 ++++++------------- .../nodes/AiTransform/AiTransform.node.ts | 2 +- packages/nodes-base/nodes/Code/Code.node.ts | 2 +- packages/nodes-base/nodes/Code/Sandbox.ts | 4 +-- .../nodes/Function/Function.node.ts | 6 ++-- .../nodes/FunctionItem/FunctionItem.node.ts | 6 ++-- 6 files changed, 19 insertions(+), 30 deletions(-) diff --git a/packages/@n8n/nodes-langchain/nodes/code/Code.node.ts b/packages/@n8n/nodes-langchain/nodes/code/Code.node.ts index 8708e0c7ea..d73d6d3268 100644 --- a/packages/@n8n/nodes-langchain/nodes/code/Code.node.ts +++ b/packages/@n8n/nodes-langchain/nodes/code/Code.node.ts @@ -81,31 +81,20 @@ function getSandbox( const workflowMode = this.getMode(); const context = getSandboxContext.call(this, itemIndex); - // eslint-disable-next-line @typescript-eslint/unbound-method - context.addInputData = this.addInputData; - // eslint-disable-next-line @typescript-eslint/unbound-method - context.addOutputData = this.addOutputData; - // eslint-disable-next-line @typescript-eslint/unbound-method - context.getInputConnectionData = this.getInputConnectionData; - // eslint-disable-next-line @typescript-eslint/unbound-method - context.getInputData = this.getInputData; - // eslint-disable-next-line @typescript-eslint/unbound-method - context.getNode = this.getNode; - // eslint-disable-next-line @typescript-eslint/unbound-method - context.getExecutionCancelSignal = this.getExecutionCancelSignal; - // eslint-disable-next-line @typescript-eslint/unbound-method - context.getNodeOutputs = this.getNodeOutputs; - // eslint-disable-next-line @typescript-eslint/unbound-method - context.executeWorkflow = this.executeWorkflow; - // eslint-disable-next-line @typescript-eslint/unbound-method - context.getWorkflowDataProxy = this.getWorkflowDataProxy; - // eslint-disable-next-line @typescript-eslint/unbound-method + context.addInputData = this.addInputData.bind(this); + context.addOutputData = this.addOutputData.bind(this); + context.getInputConnectionData = this.getInputConnectionData.bind(this); + context.getInputData = this.getInputData.bind(this); + context.getNode = this.getNode.bind(this); + context.getExecutionCancelSignal = this.getExecutionCancelSignal.bind(this); + context.getNodeOutputs = this.getNodeOutputs.bind(this); + context.executeWorkflow = this.executeWorkflow.bind(this); + context.getWorkflowDataProxy = this.getWorkflowDataProxy.bind(this); context.logger = this.logger; if (options?.addItems) { context.items = context.$input.all(); } - // eslint-disable-next-line @typescript-eslint/unbound-method const sandbox = new JavaScriptSandbox(context, code, this.helpers, { resolver: vmResolver, diff --git a/packages/nodes-base/nodes/AiTransform/AiTransform.node.ts b/packages/nodes-base/nodes/AiTransform/AiTransform.node.ts index bd3e677a2d..59b4618d88 100644 --- a/packages/nodes-base/nodes/AiTransform/AiTransform.node.ts +++ b/packages/nodes-base/nodes/AiTransform/AiTransform.node.ts @@ -121,7 +121,7 @@ export class AiTransform implements INodeType { sandbox.on( 'output', workflowMode === 'manual' - ? this.sendMessageToUI + ? this.sendMessageToUI.bind(this) : CODE_ENABLE_STDOUT === 'true' ? (...args) => console.log(`[Workflow "${this.getWorkflow().id}"][Node "${node.name}"]`, ...args) diff --git a/packages/nodes-base/nodes/Code/Code.node.ts b/packages/nodes-base/nodes/Code/Code.node.ts index 65028f037e..a887bcee20 100644 --- a/packages/nodes-base/nodes/Code/Code.node.ts +++ b/packages/nodes-base/nodes/Code/Code.node.ts @@ -133,7 +133,7 @@ export class Code implements INodeType { sandbox.on( 'output', workflowMode === 'manual' - ? this.sendMessageToUI + ? this.sendMessageToUI.bind(this) : CODE_ENABLE_STDOUT === 'true' ? (...args) => console.log(`[Workflow "${this.getWorkflow().id}"][Node "${node.name}"]`, ...args) diff --git a/packages/nodes-base/nodes/Code/Sandbox.ts b/packages/nodes-base/nodes/Code/Sandbox.ts index 917de0ecc1..e11a078f54 100644 --- a/packages/nodes-base/nodes/Code/Sandbox.ts +++ b/packages/nodes-base/nodes/Code/Sandbox.ts @@ -35,8 +35,8 @@ export function getSandboxContext( }; return { // from NodeExecuteFunctions - $getNodeParameter: this.getNodeParameter, - $getWorkflowStaticData: this.getWorkflowStaticData, + $getNodeParameter: this.getNodeParameter.bind(this), + $getWorkflowStaticData: this.getWorkflowStaticData.bind(this), helpers, // to bring in all $-prefixed vars and methods from WorkflowDataProxy diff --git a/packages/nodes-base/nodes/Function/Function.node.ts b/packages/nodes-base/nodes/Function/Function.node.ts index 6f2955e754..4819e27642 100644 --- a/packages/nodes-base/nodes/Function/Function.node.ts +++ b/packages/nodes-base/nodes/Function/Function.node.ts @@ -92,8 +92,8 @@ return items;`, // Define the global objects for the custom function const sandbox = { - getNodeParameter: this.getNodeParameter, - getWorkflowStaticData: this.getWorkflowStaticData, + getNodeParameter: this.getNodeParameter.bind(this), + getWorkflowStaticData: this.getWorkflowStaticData.bind(this), helpers: this.helpers, items, // To be able to access data of other items @@ -157,7 +157,7 @@ return items;`, const vm = new NodeVM(options); if (mode === 'manual') { - vm.on('console.log', this.sendMessageToUI); + vm.on('console.log', this.sendMessageToUI.bind(this)); } // Get the code to execute diff --git a/packages/nodes-base/nodes/FunctionItem/FunctionItem.node.ts b/packages/nodes-base/nodes/FunctionItem/FunctionItem.node.ts index 9bc3be35d1..9f08f05c8e 100644 --- a/packages/nodes-base/nodes/FunctionItem/FunctionItem.node.ts +++ b/packages/nodes-base/nodes/FunctionItem/FunctionItem.node.ts @@ -113,8 +113,8 @@ return item;`, } item.binary = data; }, - getNodeParameter: this.getNodeParameter, - getWorkflowStaticData: this.getWorkflowStaticData, + getNodeParameter: this.getNodeParameter.bind(this), + getWorkflowStaticData: this.getWorkflowStaticData.bind(this), helpers: this.helpers, item: item.json, getBinaryDataAsync: async (): Promise => { @@ -165,7 +165,7 @@ return item;`, const vm = new NodeVM(options as unknown as NodeVMOptions); if (mode === 'manual') { - vm.on('console.log', this.sendMessageToUI); + vm.on('console.log', this.sendMessageToUI.bind(this)); } // Get the code to execute