diff --git a/node_modules/node-zklib/zklibtcp.js b/node_modules/node-zklib/zklibtcp.js index 194a9d8..f7c83e3 100644 --- a/node_modules/node-zklib/zklibtcp.js +++ b/node_modules/node-zklib/zklibtcp.js @@ -120,6 +120,17 @@ class ZKLibTCP { replyBuffer = Buffer.concat([replyBuffer, data]) if (checkNotEventTCP(data)) return; clearTimeout(timer) + + // Guard: a header decoded from a buffer shorter than 16 bytes (partial + // packet, or the socket handed us a zero-length chunk) must not reach + // decodeTCPHeader — reject instead of throwing synchronously inside + // this listener, where nothing downstream can catch it. + if (!replyBuffer || replyBuffer.length < 16) { + this.socket.removeListener('data', handleOnData) + reject(new Error('INVALID_REPLY_HEADER: reply too short to decode')) + return + } + const header = decodeTCPHeader(replyBuffer.subarray(0,16)); if(header.commandId === COMMANDS.CMD_DATA){ @@ -228,7 +239,19 @@ class ZKLibTCP { reply = await this.requestData(buf) } catch (err) { + // FIX: this used to fall through to decodeTCPHeader(reply.subarray(...)) + // below with reply still null, throwing synchronously *after* the + // promise had already been rejected — an unhandled exception that + // crashed the whole process instead of just failing this call. reject(err) + return + } + + // FIX: defensive guard in case something upstream ever resolves with a + // falsy/undersized reply without going through the catch above. + if (!reply || reply.length < 16) { + reject(new Error('INVALID_REPLY: no usable reply from device')) + return } const header = decodeTCPHeader(reply.subarray(0, 16))