sdk/python/forkd/sandbox.py:207-220:
def _send(self, msg: dict) -> dict:
host, _, port_s = self.target.rpartition(":")
port = int(port_s)
with socket.create_connection((host, port), timeout=5) as s:
s.settimeout(self.timeout + 5)
s.sendall((json.dumps(msg) + "\n").encode())
s.shutdown(socket.SHUT_WR)
buf = bytearray()
while True:
chunk = s.recv(65536)
if not chunk:
break
buf.extend(chunk)
return json.loads(buf.decode())
Two issues:
-
rpartition(":") mishandles IPv6 targets. If FORKD_TARGET=[::1]:8888, rpartition(":") splits at the last colon, giving host="[::1]" and port_s="8888". The [ and ] are then passed to create_connection, which (depending on Python version) either dies or silently fails. Not common today since the default is 10.42.0.2:8888, but the target argument is user-configurable and this'll bite someone.
-
json.loads(buf.decode()) on an empty buf raises JSONDecodeError. If the guest agent dies mid-response or the timeout fires before any data is received, the user sees a baffling parse error instead of "connection closed" / "timeout". The TS SDK handles the empty-body case (if (!text) return null as T; at controller.ts:251); the Python sandbox doesn't.
For #1: use urllib.parse.urlsplit("//" + target).hostname and .port. Handles IPv6 brackets correctly.
For #2: if not buf: raise RuntimeError(f"forkd: empty response from {self.target}") before json.loads.
Both small, both worth a regression test in sdk/python/tests/ (which doesn't currently exist for sandbox — only example.py shows usage).
sdk/python/forkd/sandbox.py:207-220:Two issues:
rpartition(":")mishandles IPv6 targets. IfFORKD_TARGET=[::1]:8888,rpartition(":")splits at the last colon, givinghost="[::1]"andport_s="8888". The[and]are then passed tocreate_connection, which (depending on Python version) either dies or silently fails. Not common today since the default is10.42.0.2:8888, but thetargetargument is user-configurable and this'll bite someone.json.loads(buf.decode())on an emptybufraisesJSONDecodeError. If the guest agent dies mid-response or the timeout fires before any data is received, the user sees a baffling parse error instead of "connection closed" / "timeout". The TS SDK handles the empty-body case (if (!text) return null as T;at controller.ts:251); the Python sandbox doesn't.For #1: use
urllib.parse.urlsplit("//" + target).hostnameand.port. Handles IPv6 brackets correctly.For #2:
if not buf: raise RuntimeError(f"forkd: empty response from {self.target}")beforejson.loads.Both small, both worth a regression test in
sdk/python/tests/(which doesn't currently exist for sandbox — only example.py shows usage).