fix(protocols): guard against zero/malformed length fields in binary protocol parsers

MongoDB had the same infinite-loop bug as MSSQL (msg_len=0 → buffer never
shrinks in while loop). Postgres, MySQL, and MQTT had related length-field
issues (stuck state, resource exhaustion, overlong remaining-length).

Also fixes an existing MongoDB _op_reply struct.pack format bug (extra 'q'
specifier caused struct.error on any OP_QUERY response).

Adds 53 regression + protocol boundary tests across MSSQL, MongoDB,
Postgres, MySQL, and MQTT, including a _run_with_timeout threading harness
to catch infinite loops and @pytest.mark.fuzz hypothesis tests for each.
This commit is contained in:
2026-04-12 01:01:13 -04:00
parent 65d585569b
commit d63e396410
10 changed files with 894 additions and 2 deletions

View File

@@ -49,6 +49,10 @@ class PostgresProtocol(asyncio.Protocol):
if len(self._buf) < 4:
return
msg_len = struct.unpack(">I", self._buf[:4])[0]
if msg_len < 8 or msg_len > 10_000:
self._transport.close()
self._buf = b""
return
if len(self._buf) < msg_len:
return
msg = self._buf[:msg_len]
@@ -59,6 +63,10 @@ class PostgresProtocol(asyncio.Protocol):
return
msg_type = chr(self._buf[0])
msg_len = struct.unpack(">I", self._buf[1:5])[0]
if msg_len < 4 or msg_len > 10_000:
self._transport.close()
self._buf = b""
return
if len(self._buf) < msg_len + 1:
return
payload = self._buf[5:msg_len + 1]