Skip to content

Commit 9cfb939

Browse files
fix: verify response type in finalize() for protocol consistency
Every other protocol method checked its expected response type, but finalize() silently accepted any non-failure response. Now raises ProtocolError if the response is not EmptyResponse. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent edd4daf commit 9cfb939

2 files changed

Lines changed: 18 additions & 0 deletions

File tree

src/dqliteclient/protocol.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from dqlitewire.messages import (
1010
ClientRequest,
1111
DbResponse,
12+
EmptyResponse,
1213
ExecSqlRequest,
1314
FailureResponse,
1415
FinalizeRequest,
@@ -138,6 +139,9 @@ async def finalize(self, db_id: int, stmt_id: int) -> None:
138139
if isinstance(response, FailureResponse):
139140
raise OperationalError(response.code, response.message)
140141

142+
if not isinstance(response, EmptyResponse):
143+
raise ProtocolError(f"Expected EmptyResponse, got {type(response).__name__}")
144+
141145
async def exec_sql(
142146
self, db_id: int, sql: str, params: Sequence[Any] | None = None
143147
) -> tuple[int, int]:

tests/test_protocol.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,20 @@ async def test_open_database_failure(
8585
assert exc_info.value.code == 1
8686
assert "cannot open" in exc_info.value.message
8787

88+
async def test_finalize_wrong_response_type(
89+
self,
90+
protocol: DqliteProtocol,
91+
mock_reader: AsyncMock,
92+
) -> None:
93+
"""finalize() should reject non-EmptyResponse (catches protocol desync)."""
94+
from dqlitewire.messages import DbResponse
95+
96+
# Server sends wrong response type
97+
mock_reader.read.return_value = DbResponse(db_id=99).encode()
98+
99+
with pytest.raises(ProtocolError, match="Expected EmptyResponse"):
100+
await protocol.finalize(1, 1)
101+
88102
async def test_exec_sql(
89103
self,
90104
protocol: DqliteProtocol,

0 commit comments

Comments
 (0)