HCI_IsoDataPacket.from_bytes() raises struct.error on a short ISO packet instead of InvalidPacketError.
Reproduction
Deterministic, no hardware:
from bumble import hci
# type=0x05 (ISO), pdu_info=0x0001 (handle=1, pb_flag=0b00), data_total_length=0
hci.HCI_IsoDataPacket.from_bytes(bytes([0x05, 0x01, 0x00, 0x00, 0x00]))
struct.error: unpack_from requires a buffer of at least 9 bytes for unpacking
4 bytes at offset 5 (actual buffer size is 5)
Why
from_bytes() (hci.py, around lines 8189 and 8193) derives pb_flag from the header and then unpacks the timestamp / SDU-info fields without checking that the buffer actually contains them:
if ts_flag:
time_stamp, *_ = struct.unpack_from('<I', packet, pos) # hci.py:8189
if should_include_sdu_info:
packet_sequence_number, sdu_info = struct.unpack_from('<HH', packet, pos) # hci.py:8193
With pb_flag == 0b00 the SDU info is mandatory per the spec, so data_total_length == 0 is malformed — but a malformed packet should not produce a struct.error.
How it is reachable
PacketParser frames the packet purely from data_total_length (HCI_PACKET_INFO[HCI_ISO_DATA_PACKET] = (2, 2, 'H')), so a length of 0 yields a 5-byte packet that is happily emitted to the sink, which then calls from_bytes():
from bumble.transport import common
p = common.PacketParser()
p.set_packet_sink(sink)
p.feed_data(bytes([0x05, 0x01, 0x00, 0x00, 0x00])) # sink.on_packet() called with 5 bytes
We hit this in the field on a serial (H:4) LE Audio controller. It is currently non-fatal only because feed_data() wraps sink.on_packet() in a bare except Exception and logs — so the real symptom is a logged traceback rather than a clean InvalidPacketError.
Suggested fix
Validate the buffer length before unpacking and raise core.InvalidPacketError, consistent with PacketReader (transport/common.py:195, 201, which already raises InvalidPacketError('packet too short')).
Happy to send a PR.
HCI_IsoDataPacket.from_bytes()raisesstruct.erroron a short ISO packet instead ofInvalidPacketError.Reproduction
Deterministic, no hardware:
Why
from_bytes()(hci.py, around lines 8189 and 8193) derivespb_flagfrom the header and then unpacks the timestamp / SDU-info fields without checking that the buffer actually contains them:With
pb_flag == 0b00the SDU info is mandatory per the spec, sodata_total_length == 0is malformed — but a malformed packet should not produce astruct.error.How it is reachable
PacketParserframes the packet purely fromdata_total_length(HCI_PACKET_INFO[HCI_ISO_DATA_PACKET] = (2, 2, 'H')), so a length of0yields a 5-byte packet that is happily emitted to the sink, which then callsfrom_bytes():We hit this in the field on a serial (H:4) LE Audio controller. It is currently non-fatal only because
feed_data()wrapssink.on_packet()in a bareexcept Exceptionand logs — so the real symptom is a logged traceback rather than a cleanInvalidPacketError.Suggested fix
Validate the buffer length before unpacking and raise
core.InvalidPacketError, consistent withPacketReader(transport/common.py:195, 201, which already raisesInvalidPacketError('packet too short')).Happy to send a PR.