Skip to content

Fix parse_response crash on empty response#151

Open
gruijter wants to merge 1 commit into
alistair23:mainfrom
gruijter:fix-parse-response-empty
Open

Fix parse_response crash on empty response#151
gruijter wants to merge 1 commit into
alistair23:mainfrom
gruijter:fix-parse-response-empty

Conversation

@gruijter

@gruijter gruijter commented Jul 7, 2026

Copy link
Copy Markdown

Problem

When the mower returns a response with response_length == 0 (for example, calling GetMessage when there are no logged errors), the library still attempts to parse fields according to the schema.

For commands whose schemas contain uint8 or bool fields, the parsing logic accesses the data array using direct indexing (data[dpos]). On an empty bytearray, this immediately raises an IndexError: bytearray index out of range, causing the library to crash.

Solution

Directly after slicing data from the response packet, check if response_length == 0. If so, return None immediately, representing a valid "no data available" response.

Verification

A unit test test_decode_empty_response was added to tests/test_response.py to verify that parsing a response packet with a data length of 0 returns None instead of raising an IndexError.

@gruijter

gruijter commented Jul 7, 2026

Copy link
Copy Markdown
Author

Note: this may overlap with #148 — happy to close/rebase once that lands, whichever the maintainer prefers.

Comment thread tests/__init__.py Outdated
Comment on lines +1 to +11
import sys
from unittest.mock import MagicMock

class MockBleakGATTCharacteristic:
pass

class MockBleakClient:
pass

class MockBleakClientWithServiceCache:
pass

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Maybe from a different commit?

When the mower returns an empty response (response_length == 0),
parse_response() attempts to parse fields according to the schema.
For schema definitions containing uint8 or bool fields, this leads to direct
index access data[dpos] on the empty bytearray, raising an IndexError.

This fix checks if response_length is 0 right after assigning `data` and
returns None immediately, representing a valid "no data available" response.
@gruijter
gruijter force-pushed the fix-parse-response-empty branch from 35ed26d to edd5903 Compare July 8, 2026 09:07
@gruijter

gruijter commented Jul 8, 2026

Copy link
Copy Markdown
Author

Good catch — you're right, this wasn't needed here.

I removed the tests/init.py mock scaffolding and verified the test suite (including test_decode_empty_response) still passes cleanly without it, since bleak is already a real dependency of the package. The scaffolding must have been added defensively without checking whether it was actually required.

Force-pushed a clean commit (edd5903) that now only touches:

  • The null-check in protocol.py's parse_response()
  • The one new unit test for the empty-response case

Nothing else in the diff. Let me know if anything else needs adjusting.

@AlirezaT

AlirezaT commented Jul 8, 2026

Copy link
Copy Markdown

I checked this against #148. I do not think #148 currently covers this exact empty-response case.

#148 adds response-result helpers, serialized command flow, and variable trailing-field parsing via remaining_uint, but Command.parse_response() on that branch still slices data and then enters schema parsing even when response_length == 0. So a zero-length OK response can still fail or validate incorrectly depending on the response schema.

So this PR looks orthogonal and useful unless the same guard/test is folded into #148.

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