From f35c6e737e0085eb66ee140c1ef777ababb4357c Mon Sep 17 00:00:00 2001 From: Daniel Lando Date: Fri, 16 Apr 2021 12:44:03 +0200 Subject: [PATCH] fix(security): prevent `_parseByte` to throw (#107) * fix(security): prevent _parseByte to throw Ref: https://github.com/moscajs/aedes/issues/612 * fix: emit error when type parse fails * fix: add test --- parser.js | 11 +++++++++-- test.js | 27 ++++++++++++++++++++++++--- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/parser.js b/parser.js index a1e2667..da599eb 100644 --- a/parser.js +++ b/parser.js @@ -602,8 +602,11 @@ class Parser extends EventEmitter { } _parseByte () { - const result = this._list.readUInt8(this._pos) - this._pos++ + let result + if (this._pos < this._list.length) { + result = this._list.readUInt8(this._pos) + this._pos++ + } debug('_parseByte: result: %o', result) return result } @@ -646,6 +649,10 @@ class Parser extends EventEmitter { const result = {} while (this._pos < end) { const type = this._parseByte() + if (!type) { + this._emitError(new Error('Cannot parse property code type')) + return false + } const name = constants.propertiesCodes[type] if (!name) { this._emitError(new Error('Unknown property')) diff --git a/test.js b/test.js index 77ff4df..f12de52 100644 --- a/test.js +++ b/test.js @@ -572,9 +572,9 @@ testParseGenerateDefaults('no clientId with 5.0', { clean: true, keepalive: 60, properties: - { - receiveMaximum: 20 - }, + { + receiveMaximum: 20 + }, clientId: '' }, Buffer.from( [16, 16, 0, 4, 77, 81, 84, 84, 5, 2, 0, 60, 3, 33, 0, 20, 0, 0] @@ -2690,6 +2690,27 @@ testParseError('Malformed Subscribe Payload', Buffer.from([ 0 // requested QoS ])) +test('Cannot parse property code type', t => { + const packets = Buffer.from([ + 16, 16, 0, 4, 77, 81, 84, 84, 5, 2, 0, 60, 3, 33, 0, 20, 0, 0, 98, 2, 211, 1, 224, 2, 0, 32 + ]) + + t.plan(3) + + const parser = mqtt.parser() + + parser.on('error', err => { + t.equal(err.message, 'Cannot parse property code type', 'expected error message') + t.end() + }) + + parser.on('packet', (packet) => { + t.pass('Packet parsed') + }) + + parser.parse(packets) +}) + testWriteToStreamError('Invalid command', { cmd: 'invalid' })