Merge pull request #4416 from node-red/mqtt-check-topic-length

check topic length > 0 before publish
pull/4417/head^2
Nick O'Leary 2023-11-07 17:46:33 +00:00 committed by GitHub
commit c6a8eee73d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 16 additions and 15 deletions

View File

@ -104,6 +104,7 @@ module.exports = function(RED) {
* @returns `true` if it is a valid topic * @returns `true` if it is a valid topic
*/ */
function isValidPublishTopic(topic) { function isValidPublishTopic(topic) {
if (topic.length === 0) return false;
return !/[\+#\b\f\n\r\t\v\0]/.test(topic); return !/[\+#\b\f\n\r\t\v\0]/.test(topic);
} }
@ -219,8 +220,8 @@ module.exports = function(RED) {
*/ */
function subscriptionHandler(node, datatype ,topic, payload, packet) { function subscriptionHandler(node, datatype ,topic, payload, packet) {
const msg = {topic:topic, payload:null, qos:packet.qos, retain:packet.retain}; const msg = {topic:topic, payload:null, qos:packet.qos, retain:packet.retain};
const v5 = (node && node.brokerConn) const v5 = (node && node.brokerConn)
? node.brokerConn.v5() ? node.brokerConn.v5()
: Object.prototype.hasOwnProperty.call(packet, "properties"); : Object.prototype.hasOwnProperty.call(packet, "properties");
if(v5 && packet.properties) { if(v5 && packet.properties) {
setStrProp(packet.properties, msg, "responseTopic"); setStrProp(packet.properties, msg, "responseTopic");
@ -451,7 +452,7 @@ module.exports = function(RED) {
/** /**
* Perform the disconnect action * Perform the disconnect action
* @param {MQTTInNode|MQTTOutNode} node * @param {MQTTInNode|MQTTOutNode} node
* @param {Function} done * @param {Function} done
*/ */
function handleDisconnectAction(node, done) { function handleDisconnectAction(node, done) {
@ -865,7 +866,7 @@ module.exports = function(RED) {
* Call end and wait for the client to end (or timeout) * Call end and wait for the client to end (or timeout)
* @param {mqtt.MqttClient} client The broker client * @param {mqtt.MqttClient} client The broker client
* @param {number} ms The time to wait for the client to end * @param {number} ms The time to wait for the client to end
* @returns * @returns
*/ */
let waitEnd = (client, ms) => { let waitEnd = (client, ms) => {
return new Promise( (resolve, reject) => { return new Promise( (resolve, reject) => {
@ -905,7 +906,7 @@ module.exports = function(RED) {
node.subid = 1; node.subid = 1;
//typedef for subscription object: //typedef for subscription object:
/** /**
* @typedef {Object} Subscription * @typedef {Object} Subscription
* @property {String} topic - topic to subscribe to * @property {String} topic - topic to subscribe to
* @property {Object} [options] - options object * @property {Object} [options] - options object
@ -933,7 +934,7 @@ module.exports = function(RED) {
const ref = _ref || 0; const ref = _ref || 0;
let options let options
let qos = 1 // default to QoS 1 (AWS and several other brokers don't support QoS 2) let qos = 1 // default to QoS 1 (AWS and several other brokers don't support QoS 2)
// if options is an object, then clone it // if options is an object, then clone it
if (typeof _options == "object") { if (typeof _options == "object") {
options = RED.util.cloneMessage(_options || {}) options = RED.util.cloneMessage(_options || {})
@ -947,7 +948,7 @@ module.exports = function(RED) {
if (typeof qos === "number" && qos >= 0 && qos <= 2) { if (typeof qos === "number" && qos >= 0 && qos <= 2) {
options.qos = qos; options.qos = qos;
} }
subscription.topic = _topic; subscription.topic = _topic;
subscription.qos = qos; subscription.qos = qos;
subscription.options = RED.util.cloneMessage(options); subscription.options = RED.util.cloneMessage(options);
@ -957,16 +958,16 @@ module.exports = function(RED) {
} }
/** /**
* If topic is a subscription object, then use that, otherwise look up the topic in * If topic is a subscription object, then use that, otherwise look up the topic in
* the subscriptions object. If the topic is not found, then create a new subscription * the subscriptions object. If the topic is not found, then create a new subscription
* object and add it to the subscriptions object. * object and add it to the subscriptions object.
* @param {Subscription|String} topic * @param {Subscription|String} topic
* @param {*} options * @param {*} options
* @param {*} callback * @param {*} callback
* @param {*} ref * @param {*} ref
*/ */
node.subscribe = function (topic, options, callback, ref) { node.subscribe = function (topic, options, callback, ref) {
/** @type {Subscription} */ /** @type {Subscription} */
let subscription let subscription
let doCompare = false let doCompare = false
let changesFound = false let changesFound = false
@ -1004,7 +1005,7 @@ module.exports = function(RED) {
_brokerConn.unsubscribe(sub.topic, sub.ref, true) _brokerConn.unsubscribe(sub.topic, sub.ref, true)
} }
}) })
// if subscription is found (or sent in as a parameter), then check for changes. // if subscription is found (or sent in as a parameter), then check for changes.
// if there are any changes requested, tidy up the old subscription // if there are any changes requested, tidy up the old subscription
if (subscription) { if (subscription) {
@ -1091,7 +1092,7 @@ module.exports = function(RED) {
delete sub[ref] delete sub[ref]
} }
} }
// if instructed to remove the actual MQTT client subscription // if instructed to remove the actual MQTT client subscription
if (unsub) { if (unsub) {
// if there are no more subscriptions for the topic, then remove the topic // if there are no more subscriptions for the topic, then remove the topic
if (Object.keys(sub).length === 0) { if (Object.keys(sub).length === 0) {