Skip to content

Commit cce9da4

Browse files
fix: reject ClusterRequest format=0 to prevent ServersResponse V0 corruption
ServersResponse.decode_body unconditionally reads a uint64 role field after each node's address. If a V0-format response (no role field) were received, the decoder would silently misinterpret subsequent node IDs as role values, cascading data corruption. ClusterRequest now rejects format=0 at construction time since ServersResponse only supports V1. Closes #120 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent be96234 commit cce9da4

2 files changed

Lines changed: 13 additions & 0 deletions

File tree

src/dqlitewire/messages/requests.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,12 @@ class ClusterRequest(Message):
507507

508508
def __post_init__(self) -> None:
509509
_check_uint64("format", self.format)
510+
if self.format == 0:
511+
raise ValueError(
512+
"ClusterRequest format=0 (V0) is not supported. "
513+
"ServersResponse only decodes V1 format (with node role fields). "
514+
"Use format=1."
515+
)
510516

511517
def encode_body(self) -> bytes:
512518
return encode_uint64(self.format)

tests/test_messages_requests.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
"""Tests for request message encoding/decoding."""
22

3+
import pytest
4+
35
from dqlitewire.constants import HEADER_SIZE, RequestType
46
from dqlitewire.messages.base import Header
57
from dqlitewire.messages.requests import (
@@ -402,6 +404,11 @@ def test_default_format_is_v1(self) -> None:
402404
msg = ClusterRequest()
403405
assert msg.format == 1
404406

407+
def test_format_v0_rejected(self) -> None:
408+
"""120: V0 cluster format not supported by ServersResponse decoder."""
409+
with pytest.raises(ValueError, match="format=0.*not supported"):
410+
ClusterRequest(format=0)
411+
405412

406413
class TestTransferRequest:
407414
def test_roundtrip(self) -> None:

0 commit comments

Comments
 (0)