From 8ab808683e5dfba2c6440bd492441329bd616159 Mon Sep 17 00:00:00 2001 From: Bluetooth Devices Bot Date: Fri, 15 May 2026 06:57:55 +0000 Subject: [PATCH] fix: render gap.py invalid-AD debug log without raising TypeError The malformed-AD debug log used three %s placeholders but only passed two arguments, so any DEBUG-level handler raised "TypeError: not enough arguments for format string" while formatting the record. Add the missing AD `length` argument so the message renders cleanly and includes useful diagnostic context. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/bluetooth_data_tools/gap.py | 3 ++- tests/test_gap.py | 13 +++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/bluetooth_data_tools/gap.py b/src/bluetooth_data_tools/gap.py index a37c6d7..608aead 100644 --- a/src/bluetooth_data_tools/gap.py +++ b/src/bluetooth_data_tools/gap.py @@ -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: diff --git a/tests/test_gap.py b/tests/test_gap.py index 6b923bb..364dc24 100644 --- a/tests/test_gap.py +++ b/tests/test_gap.py @@ -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."""