From b5bdb8a32312072db13a2d0b21358118e4414060 Mon Sep 17 00:00:00 2001 From: everhardt Date: Sat, 8 Jun 2024 09:08:20 +0200 Subject: [PATCH] fix: uncaught error in read device identification (#557) * fix: uncaught exception * fix: two interpretations of numOfObjects --- index.js | 100 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 54 insertions(+), 46 deletions(-) diff --git a/index.js b/index.js index b88fa58..5225496 100644 --- a/index.js +++ b/index.js @@ -268,7 +268,10 @@ function _readFC43(data, modbus, next) { let startAt = 8; const result = {}; - for (let i = 0; i < numOfObjects; i++) { + // The modbus specification states that numOfObjects is the number of + // objects in the response, but the example on page 45 shows the total + // number over all responses. Therefore be careful about reading more data than available + for (let i = 0; i < numOfObjects && startAt < data.length; i++) { const objectId = parseInt(data.readUInt8(startAt)); const objectLength = parseInt(data.readUInt8(startAt + 1)); const startOfData = startAt + 2; @@ -496,51 +499,56 @@ function _onReceive(data) { /* parse incoming data */ - - switch (code) { - case 1: - case 2: - // Read Coil Status (FC=01) - // Read Input Status (FC=02) - _readFC2(data, next); - break; - case 3: - case 4: - // Read Input Registers (FC=04) - // Read Holding Registers (FC=03) - if (modbus._enron && !(transaction.nextDataAddress >= modbus._enronTables.shortRange[0] && transaction.nextDataAddress <= modbus._enronTables.shortRange[1])) { - _readFC3or4Enron(data, next); - } else { - _readFC3or4(data, next); - } - break; - case 5: - // Force Single Coil - _readFC5(data, next); - break; - case 6: - // Preset Single Register - if (modbus._enron && !(transaction.nextDataAddress >= modbus._enronTables.shortRange[0] && transaction.nextDataAddress <= modbus._enronTables.shortRange[1])) { - _readFC6Enron(data, next); - } else { - _readFC6(data, next); - } - break; - case 15: - case 16: - // Force Multiple Coils - // Preset Multiple Registers - _readFC16(data, next); - break; - case 17: - _readFC17(data, next); - break; - case 20: - _readFC20(data, transaction.next); - break; - case 43: - // read device identification - _readFC43(data, modbus, next); + try { + switch (code) { + case 1: + case 2: + // Read Coil Status (FC=01) + // Read Input Status (FC=02) + _readFC2(data, next); + break; + case 3: + case 4: + // Read Input Registers (FC=04) + // Read Holding Registers (FC=03) + if (modbus._enron && !(transaction.nextDataAddress >= modbus._enronTables.shortRange[0] && transaction.nextDataAddress <= modbus._enronTables.shortRange[1])) { + _readFC3or4Enron(data, next); + } else { + _readFC3or4(data, next); + } + break; + case 5: + // Force Single Coil + _readFC5(data, next); + break; + case 6: + // Preset Single Register + if (modbus._enron && !(transaction.nextDataAddress >= modbus._enronTables.shortRange[0] && transaction.nextDataAddress <= modbus._enronTables.shortRange[1])) { + _readFC6Enron(data, next); + } else { + _readFC6(data, next); + } + break; + case 15: + case 16: + // Force Multiple Coils + // Preset Multiple Registers + _readFC16(data, next); + break; + case 17: + _readFC17(data, next); + break; + case 20: + _readFC20(data, transaction.next); + break; + case 43: + // read device identification + _readFC43(data, modbus, next); + } + } catch (e) { + if (transaction.next) { + next(e); + } } }