From 1c7315857742520ace3af221d9bc65655031b6f5 Mon Sep 17 00:00:00 2001 From: liyi Date: Mon, 20 Jan 2025 16:21:41 +0800 Subject: [PATCH] =?UTF-8?q?fix:=E4=BC=98=E5=8C=96=E5=BA=8F=E5=88=97?= =?UTF-8?q?=E5=8C=96=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/talk/startChart/entity/scp_message.dart | 256 +++++++++++++------- 1 file changed, 167 insertions(+), 89 deletions(-) diff --git a/lib/talk/startChart/entity/scp_message.dart b/lib/talk/startChart/entity/scp_message.dart index 411d9452..48a97f3b 100644 --- a/lib/talk/startChart/entity/scp_message.dart +++ b/lib/talk/startChart/entity/scp_message.dart @@ -149,122 +149,200 @@ class ScpMessage { static ScpMessage deserialize(Uint8List bytes) { final message = ScpMessage(); + final length = bytes.length; int offset = 0; - // String hexString = - // bytes.map((b) => b.toRadixString(16).padLeft(2, '0')).join(); - // // _log(text: 'result bytes hex: ${hexString}'); - // _log( - // text: - // '\n result bytes hex: ${hexString} \n payload hex: ${hexString.substring(210)}'); + // 提前检查字节数组长度是否足够 + if (length < 4 + 1 + 2 + 1 + 1 + 44 + 44 + 2 + 2 + 4) { + throw FormatException("Invalid message length"); + } + + // 使用 ByteData 读取多字节数据 + final byteData = ByteData.sublistView(bytes); // ProtocolFlag (4 bytes) - if (bytes.length - offset >= 4) { - message.ProtocolFlag = utf8.decode(bytes.sublist(offset, offset + 4)); - offset += 4; - } else { - throw FormatException("Invalid ProtocolFlag length"); - } + message.ProtocolFlag = utf8.decode(bytes.sublist(offset, offset + 4)); + offset += 4; // MessageType (1 byte) - if (bytes.length - offset >= 1) { - message.MessageType = bytes[offset]; - offset += 1; - } else { - throw FormatException("Invalid MessageType length"); - } + message.MessageType = bytes[offset]; + offset += 1; // MessageId (2 bytes, little-endian) - if (bytes.length - offset >= 2) { - message.MessageId = (bytes[offset + 1] << 8) | bytes[offset]; - offset += 2; - } else { - throw FormatException("Invalid MessageId length"); - } + message.MessageId = byteData.getUint16(offset, Endian.little); + offset += 2; // SpTotal (1 byte) - if (bytes.length - offset >= 1) { - message.SpTotal = bytes[offset]; - offset += 1; - } else { - throw FormatException("Invalid SpTotal length"); - } + message.SpTotal = bytes[offset]; + offset += 1; // SpIndex (1 byte) - if (bytes.length - offset >= 1) { - message.SpIndex = bytes[offset]; - offset += 1; - } else { - throw FormatException("Invalid SpIndex length"); - } + message.SpIndex = bytes[offset]; + offset += 1; - // FromPeerId (字符串,长度固定为44字节) - if (bytes.length - offset >= 44) { - message.FromPeerId = - utf8.decode(bytes.sublist(offset, offset + 44)).trimRight(); - offset += 44; - } else { - throw FormatException("Invalid FromPeerId length"); - } + // FromPeerId (44 bytes) + message.FromPeerId = + utf8.decode(bytes.sublist(offset, offset + 44)).trimRight(); + offset += 44; - // ToPeerId (字符串,长度固定为44字节) - if (bytes.length - offset >= 44) { - message.ToPeerId = - utf8.decode(bytes.sublist(offset, offset + 44)).trimRight(); - offset += 44; - } else { - throw FormatException("Invalid ToPeerId length"); - } + // ToPeerId (44 bytes) + message.ToPeerId = + utf8.decode(bytes.sublist(offset, offset + 44)).trimRight(); + offset += 44; // PayloadType (2 bytes, little-endian) - if (bytes.length - offset >= 2) { - message.PayloadType = (bytes[offset + 1] << 8) | bytes[offset]; - offset += 2; - } else { - throw FormatException("Invalid PayloadType length"); - } + message.PayloadType = byteData.getUint16(offset, Endian.little); + offset += 2; // PayloadCRC (2 bytes, little-endian) - if (bytes.length - offset >= 2) { - message.PayloadCRC = (bytes[offset + 1] << 8) | bytes[offset]; - offset += 2; - } else { - throw FormatException("Invalid PayloadCRC length"); - } + message.PayloadCRC = byteData.getUint16(offset, Endian.little); + offset += 2; // PayloadLength (4 bytes, little-endian) - if (bytes.length - offset >= 4) { - message.PayloadLength = (bytes[offset] | - (bytes[offset + 1] << 8) | - (bytes[offset + 2] << 16) | - (bytes[offset + 3] << 24)); // 修正为 little-endian - offset += 4; - } else { - throw FormatException("Invalid PayloadLength length"); - } + message.PayloadLength = byteData.getUint32(offset, Endian.little); + offset += 4; - // 处理其他类型的Payload - if (message.PayloadLength != null && - bytes.length - offset >= message.PayloadLength!) { - final sublist = bytes.sublist(offset, offset + message.PayloadLength!); - offset += message.PayloadLength!; - message.Payload = _handlePayLoad( - payloadType: message.PayloadType ?? 0, - messageType: message.MessageType ?? 0, - byte: sublist, - offset: offset, - PayloadLength: message.PayloadLength, - spIndex: message.SpIndex, - spTotal: message.SpTotal, - messageId: message.MessageId, - ); - } else { + // 检查 Payload 长度是否有效 + if (message.PayloadLength == null || + length - offset < message.PayloadLength!) { throw FormatException("Invalid Payload or PayloadLength"); } + // 处理 Payload + final payloadBytes = bytes.sublist(offset, offset + message.PayloadLength!); + offset += message.PayloadLength!; + message.Payload = _handlePayLoad( + payloadType: message.PayloadType ?? 0, + messageType: message.MessageType ?? 0, + byte: payloadBytes, + offset: offset, + PayloadLength: message.PayloadLength, + spIndex: message.SpIndex, + spTotal: message.SpTotal, + messageId: message.MessageId, + ); + return message; } + // static ScpMessage deserialize(Uint8List bytes) { + // final message = ScpMessage(); + // int offset = 0; + // + // // String hexString = + // // bytes.map((b) => b.toRadixString(16).padLeft(2, '0')).join(); + // // // _log(text: 'result bytes hex: ${hexString}'); + // // _log( + // // text: + // // '\n result bytes hex: ${hexString} \n payload hex: ${hexString.substring(210)}'); + // + // // ProtocolFlag (4 bytes) + // if (bytes.length - offset >= 4) { + // message.ProtocolFlag = utf8.decode(bytes.sublist(offset, offset + 4)); + // offset += 4; + // } else { + // throw FormatException("Invalid ProtocolFlag length"); + // } + // + // // MessageType (1 byte) + // if (bytes.length - offset >= 1) { + // message.MessageType = bytes[offset]; + // offset += 1; + // } else { + // throw FormatException("Invalid MessageType length"); + // } + // + // // MessageId (2 bytes, little-endian) + // if (bytes.length - offset >= 2) { + // message.MessageId = (bytes[offset + 1] << 8) | bytes[offset]; + // offset += 2; + // } else { + // throw FormatException("Invalid MessageId length"); + // } + // + // // SpTotal (1 byte) + // if (bytes.length - offset >= 1) { + // message.SpTotal = bytes[offset]; + // offset += 1; + // } else { + // throw FormatException("Invalid SpTotal length"); + // } + // + // // SpIndex (1 byte) + // if (bytes.length - offset >= 1) { + // message.SpIndex = bytes[offset]; + // offset += 1; + // } else { + // throw FormatException("Invalid SpIndex length"); + // } + // + // // FromPeerId (字符串,长度固定为44字节) + // if (bytes.length - offset >= 44) { + // message.FromPeerId = + // utf8.decode(bytes.sublist(offset, offset + 44)).trimRight(); + // offset += 44; + // } else { + // throw FormatException("Invalid FromPeerId length"); + // } + // + // // ToPeerId (字符串,长度固定为44字节) + // if (bytes.length - offset >= 44) { + // message.ToPeerId = + // utf8.decode(bytes.sublist(offset, offset + 44)).trimRight(); + // offset += 44; + // } else { + // throw FormatException("Invalid ToPeerId length"); + // } + // + // // PayloadType (2 bytes, little-endian) + // if (bytes.length - offset >= 2) { + // message.PayloadType = (bytes[offset + 1] << 8) | bytes[offset]; + // offset += 2; + // } else { + // throw FormatException("Invalid PayloadType length"); + // } + // + // // PayloadCRC (2 bytes, little-endian) + // if (bytes.length - offset >= 2) { + // message.PayloadCRC = (bytes[offset + 1] << 8) | bytes[offset]; + // offset += 2; + // } else { + // throw FormatException("Invalid PayloadCRC length"); + // } + // + // // PayloadLength (4 bytes, little-endian) + // if (bytes.length - offset >= 4) { + // message.PayloadLength = (bytes[offset] | + // (bytes[offset + 1] << 8) | + // (bytes[offset + 2] << 16) | + // (bytes[offset + 3] << 24)); // 修正为 little-endian + // offset += 4; + // } else { + // throw FormatException("Invalid PayloadLength length"); + // } + // + // // 处理其他类型的Payload + // if (message.PayloadLength != null && + // bytes.length - offset >= message.PayloadLength!) { + // final sublist = bytes.sublist(offset, offset + message.PayloadLength!); + // offset += message.PayloadLength!; + // message.Payload = _handlePayLoad( + // payloadType: message.PayloadType ?? 0, + // messageType: message.MessageType ?? 0, + // byte: sublist, + // offset: offset, + // PayloadLength: message.PayloadLength, + // spIndex: message.SpIndex, + // spTotal: message.SpTotal, + // messageId: message.MessageId, + // ); + // } else { + // throw FormatException("Invalid Payload or PayloadLength"); + // } + // + // return message; + // } + // 根据不同payloadType序列化对应的payload结构体 static dynamic _handlePayLoad({ required int payloadType,