Skip to content

Commit 30ac37c

Browse files
fix: validate version parameter in MessageDecoder constructor
MessageDecoder now rejects unsupported protocol versions at construction time for response decoders, matching the validation already present in MessageEncoder. Request decoders ignore the version parameter since it comes from the handshake. Closes #122 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 3eb5523 commit 30ac37c

2 files changed

Lines changed: 20 additions & 0 deletions

File tree

src/dqlitewire/codec.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,11 @@ def __init__(self, is_request: bool = False, version: int = PROTOCOL_VERSION) ->
175175
for pre-1.0 dqlite servers (affects LeaderResponse format).
176176
Ignored for request decoders (version comes from handshake).
177177
"""
178+
if not is_request and version not in _SUPPORTED_VERSIONS:
179+
raise ProtocolError(
180+
f"Unsupported protocol version: {version:#x}. "
181+
f"Supported: {', '.join(f'{v:#x}' for v in sorted(_SUPPORTED_VERSIONS))}"
182+
)
178183
self._buffer = ReadBuffer()
179184
self._is_request = is_request
180185
self._type_map = REQUEST_TYPES if is_request else RESPONSE_TYPES

tests/test_codec.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,21 @@ def test_encode_message(self) -> None:
8080

8181

8282
class TestMessageDecoder:
83+
def test_decoder_rejects_invalid_version(self) -> None:
84+
"""122: response decoder must reject invalid version at construction."""
85+
with pytest.raises(ProtocolError, match="Unsupported protocol version"):
86+
MessageDecoder(version=0xDEADBEEF)
87+
88+
def test_decoder_accepts_legacy_version(self) -> None:
89+
"""122: PROTOCOL_VERSION_LEGACY must be accepted."""
90+
decoder = MessageDecoder(version=PROTOCOL_VERSION_LEGACY)
91+
assert decoder.version == PROTOCOL_VERSION_LEGACY
92+
93+
def test_decoder_request_ignores_version(self) -> None:
94+
"""122: request decoders ignore version param (comes from handshake)."""
95+
decoder = MessageDecoder(is_request=True, version=0xDEADBEEF)
96+
assert decoder.version is None # not set until handshake
97+
8398
def test_decode_handshake(self) -> None:
8499
decoder = MessageDecoder(is_request=True)
85100
decoder.feed(PROTOCOL_VERSION.to_bytes(8, "little"))

0 commit comments

Comments
 (0)