mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Allow nested msg properties in msg/flow/global expressions (#2822)
* Allow nested msg properties in msg/flow/global expressions * Remove typo in RED.utils Co-authored-by: Nick O'Leary <knolleary@users.noreply.github.com>
This commit is contained in:
@@ -615,18 +615,25 @@ RED.utils = (function() {
|
||||
return element;
|
||||
}
|
||||
|
||||
function normalisePropertyExpression(str) {
|
||||
function createError(code, message) {
|
||||
var e = new Error(message);
|
||||
e.code = code;
|
||||
return e;
|
||||
}
|
||||
|
||||
function normalisePropertyExpression(str,msg) {
|
||||
// This must be kept in sync with validatePropertyExpression
|
||||
// in editor/js/ui/utils.js
|
||||
|
||||
var length = str.length;
|
||||
if (length === 0) {
|
||||
throw new Error("Invalid property expression: zero-length");
|
||||
throw createError("INVALID_EXPR","Invalid property expression: zero-length");
|
||||
}
|
||||
var parts = [];
|
||||
var start = 0;
|
||||
var inString = false;
|
||||
var inBox = false;
|
||||
var boxExpression = false;
|
||||
var quoteChar;
|
||||
var v;
|
||||
for (var i=0;i<length;i++) {
|
||||
@@ -634,14 +641,14 @@ RED.utils = (function() {
|
||||
if (!inString) {
|
||||
if (c === "'" || c === '"') {
|
||||
if (i != start) {
|
||||
throw new Error("Invalid property expression: unexpected "+c+" at position "+i);
|
||||
throw createError("INVALID_EXPR","Invalid property expression: unexpected "+c+" at position "+i);
|
||||
}
|
||||
inString = true;
|
||||
quoteChar = c;
|
||||
start = i+1;
|
||||
} else if (c === '.') {
|
||||
if (i===0) {
|
||||
throw new Error("Invalid property expression: unexpected . at position 0");
|
||||
throw createError("INVALID_EXPR","Invalid property expression: unexpected . at position 0");
|
||||
}
|
||||
if (start != i) {
|
||||
v = str.substring(start,i);
|
||||
@@ -652,57 +659,99 @@ RED.utils = (function() {
|
||||
}
|
||||
}
|
||||
if (i===length-1) {
|
||||
throw new Error("Invalid property expression: unterminated expression");
|
||||
throw createError("INVALID_EXPR","Invalid property expression: unterminated expression");
|
||||
}
|
||||
// Next char is first char of an identifier: a-z 0-9 $ _
|
||||
if (!/[a-z0-9\$\_]/i.test(str[i+1])) {
|
||||
throw new Error("Invalid property expression: unexpected "+str[i+1]+" at position "+(i+1));
|
||||
throw createError("INVALID_EXPR","Invalid property expression: unexpected "+str[i+1]+" at position "+(i+1));
|
||||
}
|
||||
start = i+1;
|
||||
} else if (c === '[') {
|
||||
if (i === 0) {
|
||||
throw new Error("Invalid property expression: unexpected "+c+" at position "+i);
|
||||
throw createError("INVALID_EXPR","Invalid property expression: unexpected "+c+" at position "+i);
|
||||
}
|
||||
if (start != i) {
|
||||
parts.push(str.substring(start,i));
|
||||
}
|
||||
if (i===length-1) {
|
||||
throw new Error("Invalid property expression: unterminated expression");
|
||||
throw createError("INVALID_EXPR","Invalid property expression: unterminated expression");
|
||||
}
|
||||
// Next char is either a quote or a number
|
||||
if (!/["'\d]/.test(str[i+1])) {
|
||||
throw new Error("Invalid property expression: unexpected "+str[i+1]+" at position "+(i+1));
|
||||
// Start of a new expression. If it starts with msg it is a nested expression
|
||||
// Need to scan ahead to find the closing bracket
|
||||
if (/^msg[.\[]/.test(str.substring(i+1))) {
|
||||
var depth = 1;
|
||||
var inLocalString = false;
|
||||
var localStringQuote;
|
||||
for (var j=i+1;j<length;j++) {
|
||||
if (/["']/.test(str[j])) {
|
||||
if (inLocalString) {
|
||||
if (str[j] === localStringQuote) {
|
||||
inLocalString = false
|
||||
}
|
||||
} else {
|
||||
inLocalString = true;
|
||||
localStringQuote = str[j]
|
||||
}
|
||||
}
|
||||
if (str[j] === '[') {
|
||||
depth++;
|
||||
} else if (str[j] === ']') {
|
||||
depth--;
|
||||
}
|
||||
if (depth === 0) {
|
||||
try {
|
||||
if (msg) {
|
||||
parts.push(getMessageProperty(msg, str.substring(i+1,j)))
|
||||
} else {
|
||||
parts.push(normalisePropertyExpression(str.substring(i+1,j), msg));
|
||||
}
|
||||
inBox = false;
|
||||
i = j;
|
||||
start = j+1;
|
||||
break;
|
||||
} catch(err) {
|
||||
throw createError("INVALID_EXPR","Invalid expression started at position "+(i+1))
|
||||
}
|
||||
}
|
||||
}
|
||||
if (depth > 0) {
|
||||
throw createError("INVALID_EXPR","Invalid property expression: unmatched '[' at position "+i);
|
||||
}
|
||||
continue;
|
||||
} else if (!/["'\d]/.test(str[i+1])) {
|
||||
// Next char is either a quote or a number
|
||||
throw createError("INVALID_EXPR","Invalid property expression: unexpected "+str[i+1]+" at position "+(i+1));
|
||||
}
|
||||
start = i+1;
|
||||
inBox = true;
|
||||
} else if (c === ']') {
|
||||
if (!inBox) {
|
||||
throw new Error("Invalid property expression: unexpected "+c+" at position "+i);
|
||||
throw createError("INVALID_EXPR","Invalid property expression: unexpected "+c+" at position "+i);
|
||||
}
|
||||
if (start != i) {
|
||||
v = str.substring(start,i);
|
||||
if (/^\d+$/.test(v)) {
|
||||
parts.push(parseInt(v));
|
||||
} else {
|
||||
throw new Error("Invalid property expression: unexpected array expression at position "+start);
|
||||
throw createError("INVALID_EXPR","Invalid property expression: unexpected array expression at position "+start);
|
||||
}
|
||||
}
|
||||
start = i+1;
|
||||
inBox = false;
|
||||
} else if (c === ' ') {
|
||||
throw new Error("Invalid property expression: unexpected ' ' at position "+i);
|
||||
throw createError("INVALID_EXPR","Invalid property expression: unexpected ' ' at position "+i);
|
||||
}
|
||||
} else {
|
||||
if (c === quoteChar) {
|
||||
if (i-start === 0) {
|
||||
throw new Error("Invalid property expression: zero-length string at position "+start);
|
||||
throw createError("INVALID_EXPR","Invalid property expression: zero-length string at position "+start);
|
||||
}
|
||||
parts.push(str.substring(start,i));
|
||||
// If inBox, next char must be a ]. Otherwise it may be [ or .
|
||||
if (inBox && !/\]/.test(str[i+1])) {
|
||||
throw new Error("Invalid property expression: unexpected array expression at position "+start);
|
||||
throw createError("INVALID_EXPR","Invalid property expression: unexpected array expression at position "+start);
|
||||
} else if (!inBox && i+1!==length && !/[\[\.]/.test(str[i+1])) {
|
||||
throw new Error("Invalid property expression: unexpected "+str[i+1]+" expression at position "+(i+1));
|
||||
throw createError("INVALID_EXPR","Invalid property expression: unexpected "+str[i+1]+" expression at position "+(i+1));
|
||||
}
|
||||
start = i+1;
|
||||
inString = false;
|
||||
@@ -711,7 +760,7 @@ RED.utils = (function() {
|
||||
|
||||
}
|
||||
if (inBox || inString) {
|
||||
throw new Error("Invalid property expression: unterminated expression");
|
||||
throw new createError("INVALID_EXPR","Invalid property expression: unterminated expression");
|
||||
}
|
||||
if (start < length) {
|
||||
parts.push(str.substring(start));
|
||||
|
Reference in New Issue
Block a user