fix(gap): require exactly one signed byte for TX Power Level#227
Merged
Conversation
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>
Codecov Report✅ All modified and coverable lines are covered by tests. 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. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
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 == 1so 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
approved these changes
May 16, 2026
This was referenced May 17, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 nonsensetx_powervalues for non-conforming devices.How
Set
tx_poweronly whenend - start == 1— the spec-mandated size. Anything else falls through andtx_powerstaysNone. Mirrors the size-strict handling recently added for the 128-bit Service UUID lists (#226).Testing
test_parse_advertisement_data_tx_power_single_bytepins the happy path (length=2 ⇒tx_power=-50).test_parse_advertisement_data_tx_power_multibyte_rejectedis the regression: previouslytx_power == -32768, nowNone. Committed in the test-first commit so reviewers can checkout the prior SHA and watch it fail.cythonizesanity check on the patchedgap.pysucceeds — no.pxddrift.🤖 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