test(file-safety): add integration tests for safe-root denial messages

Exercises the actual ShellFileOperations.write_file and patch_replace
code paths (not just the helper in isolation) to verify that
safe-root denials surface 'outside HERMES_WRITE_SAFE_ROOT' and
credential-path denials surface 'protected system/credential file'.

Adapted from PR #55615 by @liuhao1024.
This commit is contained in:
kshitijk4poor 2026-07-14 16:26:24 +05:30 committed by kshitij
parent 55d826ccef
commit 320e886f3d

View file

@ -200,6 +200,75 @@ class TestGetWriteDeniedError:
assert get_write_denied_error(str(target)) is None
class TestSafeRootDenialMessageIntegration:
"""Regression tests verifying that file-tools surface the correct denial
message when HERMES_WRITE_SAFE_ROOT blocks a path.
Prior to this fix, ALL write denials returned the same "protected
system/credential file" message regardless of root cause. These tests
exercise the actual write_file / patch_replace code path, not just
the get_write_denied_error() helper in isolation.
"""
@pytest.fixture
def ops(self, tmp_path: Path):
from tools.environments.local import LocalEnvironment
from tools.file_operations import ShellFileOperations
env = LocalEnvironment(cwd=str(tmp_path))
return ShellFileOperations(env, cwd=str(tmp_path))
def test_write_file_safe_root_outside_shows_safe_root_message(
self, ops, tmp_path: Path, monkeypatch
):
safe_root = tmp_path / "workspace"
safe_root.mkdir()
outside = tmp_path / "other" / "file.txt"
outside.parent.mkdir()
monkeypatch.setenv("HERMES_WRITE_SAFE_ROOT", str(safe_root))
res = ops.write_file(str(outside), "content")
assert res.error is not None
assert "outside HERMES_WRITE_SAFE_ROOT" in res.error
assert str(safe_root) in res.error
assert "credential" not in res.error
assert not outside.exists()
def test_patch_replace_safe_root_outside_shows_safe_root_message(
self, ops, tmp_path: Path, monkeypatch
):
safe_root = tmp_path / "workspace"
safe_root.mkdir()
outside = tmp_path / "other" / "file.txt"
outside.parent.mkdir()
outside.write_text("old content")
monkeypatch.setenv("HERMES_WRITE_SAFE_ROOT", str(safe_root))
res = ops.patch_replace(str(outside), "old", "new")
assert res.error is not None
assert "outside HERMES_WRITE_SAFE_ROOT" in res.error
assert "credential" not in res.error
def test_write_file_credential_path_shows_credential_message(
self, ops, tmp_path: Path
):
res = ops.write_file("/etc/shadow", "content")
assert res.error is not None
assert "protected system/credential file" in res.error
assert "outside" not in res.error
def test_write_file_allowed_path_returns_no_error(
self, ops, tmp_path: Path, monkeypatch
):
safe_root = tmp_path / "workspace"
safe_root.mkdir()
inside = safe_root / "file.txt"
monkeypatch.setenv("HERMES_WRITE_SAFE_ROOT", str(safe_root))
res = ops.write_file(str(inside), "content")
assert res.error is None
assert inside.read_text() == "content"
class TestCheckSensitivePathMacOSBypass:
"""Verify _check_sensitive_path blocks /private/etc paths (issue #8734)."""