fix(gateway): tolerate non-UTF-8 status/pid files in gateway status reads

`_read_json_file` caught OSError but not UnicodeDecodeError, so a status
file holding binary/non-UTF-8 bytes (truncated or clobbered write) would
crash the gateway status path instead of being treated as unreadable.
UnicodeDecodeError is a ValueError subclass, not an OSError, so it
escaped the existing guard.

Widen the catch to (OSError, UnicodeDecodeError) at both read sites in
gateway/status.py — `_read_json_file` and the sibling `_read_pid_record`,
which had the identical gap. Adds tests covering binary input (returns
None) and valid input (still parses) for both.

Co-authored-by: Teknium <127238744+teknium1@users.noreply.github.com>
This commit is contained in:
Brian Doherty 2026-06-04 19:08:54 -07:00 committed by Teknium
parent 7309f3bef7
commit 899ee8c23d
2 changed files with 32 additions and 3 deletions

View file

@ -1036,3 +1036,28 @@ class TestReadProcessCmdlinePsFallback:
)
result = status._read_process_cmdline(12345)
assert "hermes_cli/main.py" in result
class TestCorruptStatusFiles:
"""A status / pid file holding non-UTF-8 (binary) bytes must read as
None, not crash the gateway status path with UnicodeDecodeError."""
def test_read_json_file_returns_none_on_binary_garbage(self, tmp_path):
p = tmp_path / "runtime.json"
p.write_bytes(b"\xff\xfe\x00\x80not utf-8\x81")
assert status._read_json_file(p) is None
def test_read_json_file_still_parses_valid_json(self, tmp_path):
p = tmp_path / "runtime.json"
p.write_text(json.dumps({"pid": 7}), encoding="utf-8")
assert status._read_json_file(p) == {"pid": 7}
def test_read_pid_record_returns_none_on_binary_garbage(self, tmp_path):
p = tmp_path / "gateway.pid"
p.write_bytes(b"\xff\xfe\x00\x80\x81")
assert status._read_pid_record(p) is None
def test_read_pid_record_still_parses_bare_pid(self, tmp_path):
p = tmp_path / "gateway.pid"
p.write_text("4242", encoding="utf-8")
assert status._read_pid_record(p) == {"pid": 4242}