From ee6c6266cc7dab8f436cc3370871a552245475e6 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Wed, 20 Mar 2019 13:37:33 +0000 Subject: [PATCH] Avoid env var reference loops and support $parent. prefix Fixes #2099 --- .../@node-red/runtime/lib/nodes/flows/Flow.js | 14 +++++++ .../runtime/lib/nodes/flows/Subflow.js | 40 ++++++++++++++----- 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/packages/node_modules/@node-red/runtime/lib/nodes/flows/Flow.js b/packages/node_modules/@node-red/runtime/lib/nodes/flows/Flow.js index 151ba62ef..8b0341463 100644 --- a/packages/node_modules/@node-red/runtime/lib/nodes/flows/Flow.js +++ b/packages/node_modules/@node-red/runtime/lib/nodes/flows/Flow.js @@ -68,6 +68,20 @@ class Flow { }) } + /** + * Log an error-level message from this flow + * @param {[type]} msg [description] + * @return {[type]} [description] + */ + error(msg) { + Log.log({ + id: this.id||"global", + level: Log.ERROR, + type:this.TYPE, + msg:msg + }) + } + /** * Log a info-level message from this flow * @param {[type]} msg [description] diff --git a/packages/node_modules/@node-red/runtime/lib/nodes/flows/Subflow.js b/packages/node_modules/@node-red/runtime/lib/nodes/flows/Subflow.js index 96bdfaa57..2bf9e9e16 100644 --- a/packages/node_modules/@node-red/runtime/lib/nodes/flows/Subflow.js +++ b/packages/node_modules/@node-red/runtime/lib/nodes/flows/Subflow.js @@ -263,17 +263,37 @@ class Subflow extends Flow { * @return {Object} val value of env var */ getSetting(name) { - var env = this.env; - if (env && env.hasOwnProperty(name)) { - var val = env[name]; - try { - var ret = redUtil.evaluateNodeProperty(val.value, val.type, this.node, null, null); - return ret; - } - catch (e) { - this.error(e); - return undefined; + this.trace("getSetting:"+name); + if (!/^\$parent\./.test(name)) { + var env = this.env; + if (env && env.hasOwnProperty(name)) { + var val = env[name]; + // If this is an env type property we need to be careful not + // to get into lookup loops. + // 1. if the value to lookup is the same as this one, go straight to parent + // 2. otherwise, check if it is a compound env var ("foo $(bar)") + // and if so, substitute any instances of `name` with $parent.name + // See https://github.com/node-red/node-red/issues/2099 + if (val.type !== 'env' || val.value !== name) { + let value = val.value; + if (val.type === 'env') { + value = value.replace(new RegExp("\\${"+name+"}","g"),"${$parent."+name+"}"); + } + try { + var ret = redUtil.evaluateNodeProperty(value, val.type, this.node, null, null); + return ret; + } + catch (e) { + this.error(e); + return undefined; + } + } else { + // This _is_ an env property pointing at itself - go to parent + } } + } else { + // name starts $parent. ... so delegate to parent automatically + name = name.substring(8); } var parent = this.parent; if (parent) {