Skip to content

fix: guard relay_switch get_basic_info against short responses#509

Draft
bluetoothbot wants to merge 2 commits into
sblibs:masterfrom
bluetoothbot:koan/guard-relay-switch-parsers
Draft

fix: guard relay_switch get_basic_info against short responses#509
bluetoothbot wants to merge 2 commits into
sblibs:masterfrom
bluetoothbot:koan/guard-relay-switch-parsers

Conversation

@bluetoothbot

@bluetoothbot bluetoothbot commented Jun 2, 2026

Copy link
Copy Markdown
Collaborator

What

Guard relay_switch.get_basic_info (RELAY_SWITCH_1, RELAY_SWITCH_1PM, RELAY_SWITCH_2PM, PLUG_MINI_EU, GARAGE_DOOR_OPENER) against truncated BLE responses.

Why

Closes #369. The reporter saw IndexError: bytearray index out of range from _parse_common_data and ValueError: Insufficient data: need at least 4 bytes, got 1 from _parse_user_data (via parse_uint24_be) when a single-byte payload — b"\x02" — reached the parser. The base _get_basic_info only filters the exact bytes b"\x07" and b"\x00", so anything else slips through and crashes inside the parser. Same class of bug as #491/#495/#496/#499/#500 — this branch is the relay-switch arm of that sweep, which was skipped at the time.

How

  • SwitchbotRelaySwitch.get_basic_info: bail with a warning if _data < 17 (last index touched is [16]) or _channel1_data < 15 (last 2-byte power slot is at offset 13).
  • SwitchbotRelaySwitch2PM.get_basic_info: same guard for _channel2_data.
  • Warnings log the hex payload so the next short response is easy to identify in the wild.

Testing

  • tests/test_relay_switch.py — added test_get_basic_info_2PM_short_response (5 truncation scenarios) and test_get_basic_info_short_response parametrised across all four single-channel models × 2 truncation scenarios. Each case asserts get_basic_info() returns None instead of raising.
  • Full suite: 1226 passed.

Quality Report

Changes: 2 files changed, 124 insertions(+)

Code scan: clean

Tests: passed (1226 passed)

Branch hygiene: clean

Generated by Kōan post-mission quality pipeline

bluetoothbot and others added 2 commits June 2, 2026 15:35
Closes sblibs#369. `_parse_common_data` reads `raw_data[1]`, `[2]`, `[16]` and
`_parse_user_data` calls `parse_uint24_be(raw_data, 1)` plus
`parse_power_data(raw_data, 13, ...)`. The base `_get_basic_info` only
filters single-byte payloads matching `b"\\x07"` or `b"\\x00"`, so any
other truncated response (e.g. the reporter's `b"\\x02"`) bubbles up and
raises IndexError/ValueError inside the parsers.

Gate `get_basic_info` (1PM/garage door/plug mini EU) on `_data` ≥ 17
bytes and `_channel1_data` ≥ 15 bytes, and the 2PM override on
`_channel2_data` ≥ 15 bytes. Log a warning with the hex payload to aid
diagnosis. Add regression coverage for each of the three truncation
paths across all four single-channel models and the 2PM variant.
@codecov

codecov Bot commented Jun 2, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

Files with missing lines Coverage Δ
switchbot/devices/relay_switch.py 100.00% <100.00%> (ø)

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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.

Single data byte causing index out of range

1 participant