Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/bluetooth_data_tools/gap.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,10 @@ def _uncached_parse_advertisement_bytes(
offset += 1 + length
if end > total_length or end - start <= 0:
_LOGGER.debug(
"Invalid BLE GAP AD structure at offset %s: %s (%s)",
"Invalid BLE GAP AD structure at offset %s: %s (length=%s)",
offset,
gap_bytes,
length,
)
continue
if gap_type_num == TYPE_SHORT_LOCAL_NAME and local_name is None:
Expand Down
13 changes: 13 additions & 0 deletions tests/test_gap.py
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,19 @@ def test_out_of_bounds_length():
)


def test_invalid_ad_debug_log_renders_without_error(caplog):
"""Malformed AD must produce a renderable debug log (regression: format-string mismatch)."""
# length=5 (claims 4 payload bytes after the type byte) but only 2 follow.
# Unique payload so the lru_cache doesn't return a previous result.
data = b"\x05\x09\xab\xcd"
with caplog.at_level("DEBUG", logger="bluetooth_data_tools.gap"):
adv = parse_advertisement_data((data,))
assert adv.local_name is None
# Render every captured record — a format-string mismatch raises here.
messages = [r.getMessage() for r in caplog.records]
assert any("Invalid BLE GAP AD structure" in m for m in messages)


def test_out_of_bounds_length_by_one():
"""Test out of bound length by one."""

Expand Down
Loading