dart_mavlink icon indicating copy to clipboard operation
dart_mavlink copied to clipboard

Corrupted FTP message following a non-ftp frame

Open sagimann opened this issue 7 months ago • 0 comments

Hi, I have found the following issue: A FTP message gets injected with the previous message's excess data:

        test('parse_secondMessage', () async {
            MavlinkParser parser = MavlinkParser(MavlinkDialectCommon());
            final completer = Completer<MavlinkMessage>();
            parser.stream.listen((MavlinkFrame frm) {
                if (frm.message is FileTransferProtocol) {
                  completer.complete(frm.message);
                }
            });
            // a heartbeat followed by a FTP ACK in the same frame:
            List<int> bytes = [253, 28, 0, 0, 149, 1, 1, 30, 0, 0, 43, 196, 233, 0, 159, 76, 89, 189, 119, 113, 38, 61, 42, 28, 211, 63, 128, 224, 101, 56, 160, 47, 44, 187, 80, 14, 229, 184, 100, 205, 253, 19, 0, 0, 150, 1, 1, 110, 0, 0, 0, 1, 1, 4, 0, 0, 128, 6, 3, 0, 0, 0, 0, 0, 0, 68, 65, 80, 77, 171, 119];
            Uint8List rawData = Uint8List.fromList(bytes);
            parser.parse(rawData);
            MavlinkMessage message = await completer.future;
            expect(message, isA<FileTransferProtocol>());
            FileTransferProtocol ftp = message as FileTransferProtocol;
            Uint8List sub = ftp.payload.sublist(0,18)
            expect(sub , equals(Uint8List.fromList([4, 0, 0, 128, 6, 3, 0, 0, 0, 0, 0, 0, 68, 65, 80, 77, 0, 0])));
        });

fails:

Expected: [4, 0, 0, 128, 6, 3, 0, 0, 0, 0, 0, 0, 68, 65, 80, 77, 0, 0]
  Actual: [4, 0, 0, 128, 6, 3, 0, 0, 0, 0, 0, 0, 68, 65, 80, 77, 56, 160]
   Which: at location [16] is <56> instead of <0>

suggestion to fix:

common.dart (commit 4c93f21):

  factory FileTransferProtocol.parse(ByteData data_) {
      ...
      var d = data_.buffer.asUint8List() + List<int>.filled(len, 0);

change to:

  factory FileTransferProtocol.parse(ByteData data_) {
      ...
      var d = data_.buffer.asUint8List(data_.offsetInBytes, data_.lengthInBytes) + List<int>.filled(len, 0);

sagimann avatar Jun 25 '24 10:06 sagimann