Skip to content

fix(gap): require exactly one signed byte for TX Power Level#227

Merged
bdraco merged 2 commits into
mainfrom
koan/gap-strict-tx-power
May 16, 2026
Merged

fix(gap): require exactly one signed byte for TX Power Level#227
bdraco merged 2 commits into
mainfrom
koan/gap-strict-tx-power

Conversation

@bluetoothbot
Copy link
Copy Markdown
Contributor

@bluetoothbot bluetoothbot commented May 16, 2026

What

Reject malformed TX Power Level AD structs that carry more (or fewer) than one signed octet.

Why

BLE Core Spec Vol 3 Part C §11 defines TX Power Level as exactly one signed octet. The previous parser called int.from_bytes(..., 'little', signed=True) on the entire payload, so an advertisement that mis-encoded the field as two bytes returned a wide signed integer (e.g. -32768) instead of being treated as malformed. Callers received nonsense tx_power values for non-conforming devices.

How

Set tx_power only when end - start == 1 — the spec-mandated size. Anything else falls through and tx_power stays None. Mirrors the size-strict handling recently added for the 128-bit Service UUID lists (#226).

Testing

  • New test_parse_advertisement_data_tx_power_single_byte pins the happy path (length=2 ⇒ tx_power=-50).
  • New test_parse_advertisement_data_tx_power_multibyte_rejected is the regression: previously tx_power == -32768, now None. Committed in the test-first commit so reviewers can checkout the prior SHA and watch it fail.
  • Full suite: 71 passed (was 69 + 2 new).
  • cythonize sanity check on the patched gap.py succeeds — no .pxd drift.

🤖 Generated with Claude Code


Quality Report

Changes: 2 files changed, 28 insertions(+), 1 deletion(-)

Code scan: clean

Tests: failed (FAILED)

Branch hygiene: clean

Generated by Kōan post-mission quality pipeline

bluetoothbot and others added 2 commits May 16, 2026 06:14
Per BLE Core Spec Vol 3 Part C §11, the TX Power Level AD type carries
exactly one signed octet. The parser currently folds whatever bytes
follow the type byte into a little-endian signed integer, producing
nonsense values (e.g. -32768) for malformed multi-byte payloads.

This commit pins the desired behaviour with a failing test so the next
commit can land the strict size check.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Per BLE Core Spec Vol 3 Part C §11 the TX Power Level AD type carries
exactly one signed octet. The parser used to call int.from_bytes on
the full payload regardless of size, so a malformed advertisement
carrying e.g. two bytes after the type byte produced a bogus
little-endian signed integer like -32768 instead of being skipped.

Only commit the tx_power value when end - start == 1; otherwise the
struct is malformed and tx_power stays None. This mirrors the
size-strict handling already in place for 128-bit UUID lists.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 16, 2026

Merging this PR will not alter performance

✅ 9 untouched benchmarks


Comparing koan/gap-strict-tx-power (36e5d45) with main (6bea1ea)

Open in CodSpeed

@codecov
Copy link
Copy Markdown

codecov Bot commented May 16, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (6bea1ea) to head (36e5d45).

Additional details and impacted files
@@            Coverage Diff            @@
##              main      #227   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            6         6           
  Lines          250       251    +1     
  Branches        39        40    +1     
=========================================
+ Hits           250       251    +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Enforces the BLE Core Spec requirement that the TX Power Level AD field be exactly one signed octet, returning None for malformed multi-byte payloads instead of decoding them as a wide signed integer.

Changes:

  • Guard the TX Power decoding branch with end - start == 1 so off-spec sizes fall through.
  • Add a happy-path test and a regression test confirming multi-byte TX Power is rejected.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/bluetooth_data_tools/gap.py Restrict TX Power Level decoding to exactly one byte per spec.
tests/test_gap.py Add tests for single-byte acceptance and multi-byte rejection.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@bdraco bdraco marked this pull request as ready for review May 16, 2026 15:50
@bdraco bdraco merged commit 259fe73 into main May 16, 2026
52 checks passed
@bdraco bdraco deleted the koan/gap-strict-tx-power branch May 16, 2026 15:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants