fix: guard relay_switch get_basic_info against short responses#509
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests.
... and 1 file with indirect coverage changes 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR hardens relay-switch get_basic_info() parsing against truncated BLE command responses so callers receive None (with a warning log) instead of raising IndexError/ValueError, addressing issue #369 for relay/plug/garage and 2PM variants.
Changes:
- Add minimum-length guards in
SwitchbotRelaySwitch.get_basic_info()forbasic_info(≥17) andchannel1_info(≥15), logging truncated payloads. - Add the same minimum-length guard for
channel2_infoinSwitchbotRelaySwitch2PM.get_basic_info()(≥15). - Add regression tests covering multiple truncation scenarios across single-channel models and the 2PM model.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
switchbot/devices/relay_switch.py |
Adds length checks + warning logs to prevent parsing truncated command responses. |
tests/test_relay_switch.py |
Adds parametrized async tests asserting short responses return None instead of raising. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
PR Review — fix: guard relay_switch get_basic_info against short responsesCorrect, well-scoped fix for issue #369 — merge-ready. Verified against the parsers:
🟢 Suggestions
1. Warnings omit device identity — harder to trace in the field
|
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.
Rebase with requested adjustmentsBranch Changes applied
StatsActions performed
CI statusCI will be checked asynchronously. Automated by Kōan |
f62aa33 to
de7e562
Compare
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 rangefrom_parse_common_dataandValueError: Insufficient data: need at least 4 bytes, got 1from_parse_user_data(viaparse_uint24_be) when a single-byte payload —b"\x02"— reached the parser. The base_get_basic_infoonly filters the exact bytesb"\x07"andb"\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.Testing
tests/test_relay_switch.py— addedtest_get_basic_info_2PM_short_response(5 truncation scenarios) andtest_get_basic_info_short_responseparametrised across all four single-channel models × 2 truncation scenarios. Each case assertsget_basic_info()returnsNoneinstead of raising.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