From 8126181e180ef6a505b46eab3942a5899c8c5116 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: Mon, 7 Aug 2023 11:52:33 +0200 Subject: [PATCH] fix(editor): Avoid infinite loops when resolving the expression `{{ $parameter }}` (no-changelog) (#6855) Co-authored-by: Oleg Ivaniv --- cypress/e2e/11-inline-expression-editor.cy.ts | 4 ++-- packages/editor-ui/src/mixins/workflowHelpers.ts | 9 ++++++--- packages/workflow/src/WorkflowDataProxy.ts | 6 ++++++ 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/cypress/e2e/11-inline-expression-editor.cy.ts b/cypress/e2e/11-inline-expression-editor.cy.ts index e1fbb08f36..f7e192e06c 100644 --- a/cypress/e2e/11-inline-expression-editor.cy.ts +++ b/cypress/e2e/11-inline-expression-editor.cy.ts @@ -51,7 +51,7 @@ describe('Inline expression editor', () => { it('should resolve array resolvables', () => { WorkflowPage.getters.inlineExpressionEditorInput().clear(); WorkflowPage.getters.inlineExpressionEditorInput().type('{{'); - WorkflowPage.getters.inlineExpressionEditorInput().type('[1, 2, 3]', { timeout: 20000 }); + WorkflowPage.getters.inlineExpressionEditorInput().type('[1, 2, 3]'); WorkflowPage.getters.inlineExpressionEditorOutput().contains(/^\[Array: \[1,2,3\]\]$/); WorkflowPage.getters.inlineExpressionEditorInput().clear(); @@ -66,7 +66,7 @@ describe('Inline expression editor', () => { WorkflowPage.getters.inlineExpressionEditorInput().clear(); WorkflowPage.getters.inlineExpressionEditorInput().type('{{'); // Resolving $parameter is slow, especially on CI runner - WorkflowPage.getters.inlineExpressionEditorInput().type('$parameter["operation"]', { timeout: 35000 }); + WorkflowPage.getters.inlineExpressionEditorInput().type('$parameter["operation"]'); WorkflowPage.getters.inlineExpressionEditorOutput().contains(/^get$/); }); }); diff --git a/packages/editor-ui/src/mixins/workflowHelpers.ts b/packages/editor-ui/src/mixins/workflowHelpers.ts index 33867f0785..04ea11bc07 100644 --- a/packages/editor-ui/src/mixins/workflowHelpers.ts +++ b/packages/editor-ui/src/mixins/workflowHelpers.ts @@ -657,11 +657,14 @@ export const workflowHelpers = defineComponent({ return null; } - if (typeof returnData['__xxxxxxx__'] === 'object') { + const obj = returnData['__xxxxxxx__']; + if (typeof obj === 'object') { + const proxy = obj as { isProxy: boolean; toJSON?: () => unknown } | null; + if (proxy?.isProxy && proxy.toJSON) return JSON.stringify(proxy.toJSON()); const workflow = getCurrentWorkflow(); - return workflow.expression.convertObjectValueToString(returnData['__xxxxxxx__'] as object); + return workflow.expression.convertObjectValueToString(obj as object); } - return returnData['__xxxxxxx__']; + return obj; }, async updateWorkflow( diff --git a/packages/workflow/src/WorkflowDataProxy.ts b/packages/workflow/src/WorkflowDataProxy.ts index 2a044cfc91..a9d5002e26 100644 --- a/packages/workflow/src/WorkflowDataProxy.ts +++ b/packages/workflow/src/WorkflowDataProxy.ts @@ -27,6 +27,7 @@ import * as NodeHelpers from './NodeHelpers'; import { ExpressionError } from './ExpressionError'; import type { Workflow } from './Workflow'; import { augmentArray, augmentObject } from './AugmentObject'; +import { deepCopy } from './utils'; export function isResourceLocatorValue(value: unknown): value is INodeParameterResourceLocator { return Boolean( @@ -213,6 +214,8 @@ export class WorkflowDataProxy { }, get(target, name, receiver) { if (name === 'isProxy') return true; + if (name === 'toJSON') return () => deepCopy(target); + name = name.toString(); let returnValue: NodeParameterValueType; @@ -231,6 +234,9 @@ export class WorkflowDataProxy { returnValue = node.parameters[name]; } + // Avoid recursion + if (returnValue === `={{ $parameter.${name} }}`) return undefined; + if (isResourceLocatorValue(returnValue)) { if (returnValue.__regex && typeof returnValue.value === 'string') { const expr = new RegExp(returnValue.__regex);