diff --git a/can/interfaces/gs_usb.py b/can/interfaces/gs_usb.py index fcf21d3f4..60debe1cb 100644 --- a/can/interfaces/gs_usb.py +++ b/can/interfaces/gs_usb.py @@ -142,14 +142,14 @@ def send(self, msg: can.Message, timeout: float | None = None) -> None: if msg.is_error_frame: can_id = can_id | CAN_ERR_FLAG - # Pad message data - msg.data.extend([0x00] * (CAN_MAX_DLC - len(msg.data))) + # Copy and pad message data without mutating msg.data + msg_data = msg.data + bytearray([0x00] * (CAN_MAX_DLC - len(msg.data))) frame = GsUsbFrame() frame.can_id = can_id frame.can_dlc = msg.dlc frame.timestamp_us = 0 # timestamp frame field is only useful on receive - frame.data = list(msg.data) + frame.data = list(msg_data) try: self.gs_usb.send(frame) diff --git a/doc/changelog.d/2085.fixed.rst b/doc/changelog.d/2085.fixed.rst new file mode 100644 index 000000000..a7f0b5319 --- /dev/null +++ b/doc/changelog.d/2085.fixed.rst @@ -0,0 +1 @@ +Fixed gs_usb.py modyfying the data member of the can.Message msg passed to GsUsbBus send method. diff --git a/test/test_interface_gs_usb.py b/test/test_interface_gs_usb.py index 9f0e35534..8a7c898b2 100644 --- a/test/test_interface_gs_usb.py +++ b/test/test_interface_gs_usb.py @@ -2,6 +2,7 @@ from unittest.mock import MagicMock, patch +import can import pytest from can.interfaces.gs_usb import ( @@ -65,3 +66,22 @@ def test_find_devices_returns_empty_list_when_no_devices(mock_find): devices = _find_gs_usb_devices() assert devices == [] + + +@patch("can.interfaces.gs_usb.GsUsb") +@patch("can.interfaces.gs_usb._find_gs_usb_devices") +def test_send_dlc_zero_does_not_modify_message_data(mock_find_devices, mock_gs_usb_cls): + """Verify that send() does not mutate msg.data when DLC < CAN_MAX_DLC.""" + mock_find_devices.return_value = [MagicMock()] + mock_gs_usb = MagicMock() + mock_gs_usb_cls.return_value = mock_gs_usb + mock_gs_usb.device_capability.fclk_can = 48_000_000 + + bus = GsUsbBus(channel=0, bitrate=500_000) + msg = can.Message(arbitration_id=0x123, data=bytearray(), dlc=0) + msg_data_copy = msg.data.copy() + + bus.send(msg) + + assert msg.data == msg_data_copy + mock_gs_usb.send.assert_called_once()