Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion cron/lifecycle_guard.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,10 @@ def _read_referenced_script(path: Path) -> tuple[Optional[str], bool]:
flags = os.O_RDONLY | getattr(os, "O_NONBLOCK", 0)
try:
descriptor = os.open(path, flags)
except OSError:
except (OSError, ValueError):
# Path-like input can contain an embedded NUL after shell tokenization.
# Treat malformed references like unreadable paths instead of crashing
# the terminal tool before the requested command can run.
return None, False
try:
metadata = os.fstat(descriptor)
Expand Down
7 changes: 7 additions & 0 deletions tests/hermes_cli/test_gateway_restart_loop.py
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,13 @@ def test_clean_prompt_does_not_raise(self):
check_gateway_lifecycle("research the gateway architecture", None)
check_gateway_lifecycle("check server health and restart watchers", None)

def test_embedded_nul_in_referenced_path_does_not_crash(self):
"""Malformed shell input must not crash the terminal guard in os.open."""
from cron.lifecycle_guard import contains_gateway_lifecycle_command_or_referenced_script

command = "/bin/bash /tmp/safe\x00broken.sh"
assert not contains_gateway_lifecycle_command_or_referenced_script(command)

def test_script_with_command_raises(self, tmp_path, monkeypatch):
from cron.lifecycle_guard import GatewayLifecycleBlocked, check_gateway_lifecycle
script = tmp_path / "restart.sh"
Expand Down