diff --git a/can/io/blf.py b/can/io/blf.py index 81146233d..7d944a846 100644 --- a/can/io/blf.py +++ b/can/io/blf.py @@ -103,7 +103,7 @@ def timestamp_to_systemtime(timestamp: float) -> TSystemTime: if timestamp is None or timestamp < 631152000: # Probably not a Unix timestamp return 0, 0, 0, 0, 0, 0, 0, 0 - t = datetime.datetime.fromtimestamp(round(timestamp, 3)) + t = datetime.datetime.fromtimestamp(round(timestamp, 3), tz=datetime.timezone.utc) return ( t.year, t.month, @@ -126,6 +126,7 @@ def systemtime_to_timestamp(systemtime: TSystemTime) -> float: systemtime[5], systemtime[6], systemtime[7] * 1000, + tzinfo=datetime.timezone.utc, ) return t.timestamp() except ValueError: @@ -239,7 +240,7 @@ def _parse_data(self, data): raise BLFParseError("Could not find next object") from None header = unpack_obj_header_base(data, pos) # print(header) - signature, _, header_version, obj_size, obj_type = header + signature, header_size, header_version, obj_size, obj_type = header if signature != b"LOBJ": raise BLFParseError() @@ -334,10 +335,20 @@ def _parse_data(self, data): _, _, direction, - _, + ext_data_offset, _, ) = unpack_can_fd_64_msg(data, pos) - pos += can_fd_64_msg_size + + # :issue:`1905`: `valid_bytes` can be higher than the actually available data. + # Add zero-byte padding to mimic behavior of CANoe and binlog.dll. + data_field_length = min( + valid_bytes, + (ext_data_offset or obj_size) - header_size - can_fd_64_msg_size, + ) + msg_data_offset = pos + can_fd_64_msg_size + msg_data = data[msg_data_offset : msg_data_offset + data_field_length] + msg_data = msg_data.ljust(valid_bytes, b"\x00") + yield Message( timestamp=timestamp, arbitration_id=can_id & 0x1FFFFFFF, @@ -348,7 +359,7 @@ def _parse_data(self, data): bitrate_switch=bool(fd_flags & 0x2000), error_state_indicator=bool(fd_flags & 0x4000), dlc=dlc2len(dlc), - data=data[pos : pos + valid_bytes], + data=msg_data, channel=channel - 1, ) diff --git a/test/data/issue_1905.blf b/test/data/issue_1905.blf new file mode 100644 index 000000000..a896a6d7c Binary files /dev/null and b/test/data/issue_1905.blf differ diff --git a/test/logformats_test.py b/test/logformats_test.py index 0fbe065d2..a2fd0fe09 100644 --- a/test/logformats_test.py +++ b/test/logformats_test.py @@ -789,6 +789,30 @@ def test_timestamp_to_systemtime(self): places=3, ) + def test_issue_1905(self): + expected = can.Message( + timestamp=1735654183.491113, + channel=6, + arbitration_id=0x6A9, + is_extended_id=False, + is_fd=True, + bitrate_switch=True, + error_state_indicator=False, + dlc=64, + data=bytearray( + b"\xff\xff\xff\xff\xff\xff\xff\xff" + b"\xff\xff\xff\xff\xff\xff\xff\xff" + b"\xff\xff\xff\xff\xff\xff\xff\xff" + b"\xff\xff\xff\xff\xff\xff\xff\xff" + b"\xff\xff\xff\xff\xff\xff\xff\xff" + b"\xff\xff\xff\xff\xff\xff\xff\xff" + b"\x00\x00\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\x00\x00\x00\x00" + ), + ) + msgs = self._read_log_file("issue_1905.blf") + self.assertMessageEqual(expected, msgs[0]) + class TestCanutilsFileFormat(ReaderWriterTest): """Tests can.CanutilsLogWriter and can.CanutilsLogReader"""