Skip to content

Commit de2493e

Browse files
authored
fix(gap): include trailing 2-byte AD struct in parse bounds (#221)
1 parent fc2abe3 commit de2493e

2 files changed

Lines changed: 16 additions & 1 deletion

File tree

src/bluetooth_data_tools/gap.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ def _uncached_parse_advertisement_bytes(
191191
gap_data = gap_bytes
192192
# IMPORTANT: All data must be manually bounds checked
193193
# because the data is untrusted and can be malformed.
194-
while offset + 2 < total_length:
194+
while offset + 2 <= total_length:
195195
if not (length := gap_data[offset]):
196196
offset += 1 # Handle zero padding
197197
continue

tests/test_gap.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,21 @@ def test_parse_advertisement_data_ignores_invalid():
9999
assert adv.tx_power == 5
100100

101101

102+
def test_parse_advertisement_data_trailing_minimum_ad_struct(caplog):
103+
# Manufacturer-data struct (5 bytes) followed by a trailing minimum-AD
104+
# struct [length=1][type=0x09] (2 bytes). The loop must enter the trailing
105+
# struct rather than silently skip it; preceding data must still parse.
106+
import logging
107+
108+
data = [b"\x04\xff\x4c\x00\x10\x01\x09"]
109+
110+
with caplog.at_level(logging.DEBUG, logger="bluetooth_data_tools.gap"):
111+
adv = parse_advertisement_data(data)
112+
113+
assert adv.manufacturer_data == {76: b"\x10"}
114+
assert any("Invalid BLE GAP AD structure" in r.message for r in caplog.records)
115+
116+
102117
def test_parse_advertisement_data_ignores_zero_type():
103118
data = [
104119
b"\x02\x01\x1a\x02\n\x05\n\xffL\x00\x10\x05\n\x1cw\xf9[\x02\x00",

0 commit comments

Comments
 (0)