1
0
mirror of https://github.com/node-red/node-red.git synced 2023-10-10 13:36:53 +02:00

Add full ast parsing in Function node to spot node.done calls

Fixes #2998
This commit is contained in:
Nick O'Leary 2021-06-02 12:32:44 +01:00
parent 3e6a55f78e
commit 12698dc347
No known key found for this signature in database
GPG Key ID: 4F2157149161A6C9
3 changed files with 26 additions and 7 deletions

View File

@ -26,6 +26,8 @@
}
],
"dependencies": {
"acorn": "8.3.0",
"acorn-walk": "8.1.0",
"ajv": "6.12.6",
"async-mutex": "0.3.1",
"basic-auth": "2.0.1",

View File

@ -19,6 +19,8 @@ module.exports = function(RED) {
var util = require("util");
var vm = require("vm");
var acorn = require("acorn");
var acornWalk = require("acorn-walk");
function sendResults(node,send,_msgid,msgs,cloneFirstMessage) {
if (msgs == null) {
@ -102,14 +104,7 @@ module.exports = function(RED) {
throw new Error(RED._("function.error.externalModuleNotAllowed"));
}
var handleNodeDoneCall = true;
// Check to see if the Function appears to call `node.done()`. If so,
// we will assume it is well written and does actually call node.done().
// Otherwise, we will call node.done() after the function returns regardless.
if (/node\.done\s*\(\s*\)/.test(node.func)) {
handleNodeDoneCall = false;
}
var functionText = "var results = null;"+
"results = (async function(msg,__send__,__done__){ "+
@ -130,6 +125,26 @@ module.exports = function(RED) {
"};\n"+
node.func+"\n"+
"})(msg,__send__,__done__);";
var handleNodeDoneCall = true;
// Check to see if the Function appears to call `node.done()`. If so,
// we will assume it is well written and does actually call node.done().
// Otherwise, we will call node.done() after the function returns regardless.
if (/node\.done\s*\(\s*\)/.test(functionText)) {
// We have spotted the code contains `node.done`. It could be in a comment
// so need to do the extra work to parse the AST and examine it properly.
acornWalk.simple(acorn.parse(functionText,{ecmaVersion: "latest"} ), {
CallExpression(astNode) {
if (astNode.callee && astNode.callee.object) {
if (astNode.callee.object.name === "node" && astNode.callee.property.name === "done") {
handleNodeDoneCall = false;
}
}
}
})
}
var finScript = null;
var finOpt = null;
node.topic = n.topic;

View File

@ -15,6 +15,8 @@
}
],
"dependencies": {
"acorn": "8.3.0",
"acorn-walk": "8.1.0",
"ajv": "6.12.6",
"body-parser": "1.19.0",
"cheerio": "0.22.0",