node-zserial 1.0.37 → 1.0.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/zserial.js +14 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-zserial",
3
- "version": "1.0.37",
3
+ "version": "1.0.38",
4
4
  "description": "Node-RED nodes to talk to serial ports",
5
5
  "dependencies": {
6
6
  "serialport": "^12.0.0"
package/zserial.js CHANGED
@@ -1101,6 +1101,16 @@ module.exports = function (RED) {
1101
1101
  // 绝大多数场景长度单位为“字节”;若遇到 KB 单位则折算
1102
1102
  const L = isKB ? (Lraw << 10) : Lraw; // KB -> *1024
1103
1103
 
1104
+ function isComplete645AtStart() {
1105
+ if (b.length < 12 || b[0] !== 0x68 || b[7] !== 0x68) return false;
1106
+ const len645 = b[9] >>> 0;
1107
+ const total645 = 12 + len645;
1108
+ if (total645 > b.length) return false;
1109
+ if (b[total645 - 1] !== 0x16) return false;
1110
+ const cs = b[total645 - 2] >>> 0;
1111
+ return cs === sum8(b, 0, total645 - 2) || cs === sum8(b, 8, total645 - 2);
1112
+ }
1113
+
1104
1114
  // ------------------------ 关键防误判(核心修复点) ------------------------
1105
1115
  // 误判根因:645 帧形态为 68 + 6字节地址 + 68 ...,地址字节中“偶然出现 0x16”
1106
1116
  // 例如:68 02 80 16 00 00 00 68 ...
@@ -1119,6 +1129,7 @@ module.exports = function (RED) {
1119
1129
  // 长度上限:防止错位/噪声把 L 解读成极大值导致 assembleBuf 长期等待。
1120
1130
  const MAX_698_LEN_L = 2048;
1121
1131
  if (L > MAX_698_LEN_L) {
1132
+ if (isComplete645AtStart()) return { ok: false };
1122
1133
  return { ok: false, used: 1, frame: input.slice(0, 1), err: "698_LEN_TOO_LARGE" };
1123
1134
  }
1124
1135
 
@@ -1143,6 +1154,9 @@ module.exports = function (RED) {
1143
1154
  // 半包:继续累积。这里必须显式告诉主循环“这是 698-LEN 半包”,
1144
1155
  // 否则后续 645 parser 会把第一个 0x68 当作错位字节丢掉。
1145
1156
  if (b.length < expectedEnd + 1) {
1157
+ // 若当前位置已经是完整且 CS 正确的 645 帧,让 645 parser 接管。
1158
+ // 不能仅凭 b[7] === 0x68 判断,否则会误伤 APDU 中第 8 字节刚好为 0x68 的正常 698 帧。
1159
+ if (isComplete645AtStart()) return { ok: false };
1146
1160
  return {
1147
1161
  ok: false,
1148
1162
  pending: true,