Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions packages/node_modules/@node-red/nodes/core/network/31-tcpin.js
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,15 @@ module.exports = function(RED) {
let event;
while (event = dequeue(clients[connection_id].msgQueue)) {
if (event.msg.payload !== undefined) {
clients[connection_id].client.write(event.msg.payload);
if (typeof event.msg.payload !== 'string' && !Buffer.isBuffer(event.msg.payload) && !(event.msg.payload instanceof Uint8Array)) {
node.error(`TCP Out Invalid payload type: ${typeof event.msg.payload}. Expected Buffer, Uint8Array, or string.`, event.msg);
} else {
try {
clients[connection_id].client.write(event.msg.payload);
} catch (err) {
node.error(err, event.msg);
}
}
}
event.nodeDone();
}
Expand Down Expand Up @@ -870,7 +878,15 @@ module.exports = function(RED) {
if (clients[connection_id] && clients[connection_id].client) {
let event = dequeue(clients[connection_id].msgQueue)
if (event.msg.payload !== undefined ) {
clients[connection_id].client.write(event.msg.payload);
if (typeof event.msg.payload !== 'string' && !Buffer.isBuffer(event.msg.payload) && !(event.msg.payload instanceof Uint8Array)) {
node.error(`TCP Out Invalid payload type: ${typeof event.msg.payload}. Expected Buffer, Uint8Array, or string.`, event.msg);
} else {
try {
clients[connection_id].client.write(event.msg.payload);
} catch (err) {
node.error(err, event.msg);
}
}
}
event.nodeDone();
}
Expand Down
29 changes: 29 additions & 0 deletions test/nodes/core/network/31-tcprequest_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -351,5 +351,34 @@ describe('TCP Request Node', function() {
topic: 'quux'
}, done);
});

it('should handle payload mutation to number during connection without crashing and log an error', function(done) {
var flow = [{id:"n1", type:"tcp request", server:"localhost", port:port, out:"time", splitc: "0", wires:[["n2"]] },
{id:"n2", type:"helper"}];
helper.load(tcpinNode, flow, function() {
var n1 = helper.getNode("n1");
var msg = { payload: Buffer.from("foo") };
n1.receive(msg);
// Mutate the payload to a number synchronously after enqueue but before connection callback runs
msg.payload = 2;

setTimeout(function() {
try {
helper.log().called.should.be.true();
var logEvents = helper.log().args.filter(function (evt) {
return evt[0].type == "tcp request";
});
logEvents.should.have.length(1);
var logMsg = logEvents[0][0];
logMsg.should.have.property('level', helper.log().ERROR);
logMsg.should.have.property('id', 'n1');
logMsg.msg.should.containEql('Invalid payload type: number');
done();
} catch (err) {
done(err);
}
}, 100);
});
});
});
});
Loading