zcbot/tests/test_shell_security.py

46 lines
1.6 KiB
Python

from __future__ import annotations
import os
import tempfile
import unittest
from pathlib import Path
from unittest.mock import patch
from core import procs
from core.proc_wrapper import _shell_argv as wrapper_shell_argv
from tools.shell import ShellTool
class ShellSecurityTests(unittest.TestCase):
def test_shell_argv_uses_explicit_interpreter(self) -> None:
argv = procs.shell_argv("echo ok")
wrapper_argv = wrapper_shell_argv("echo ok")
self.assertEqual(argv, wrapper_argv)
self.assertEqual(argv[-1], "echo ok")
if os.name == "nt":
self.assertEqual(argv[1:4], ["/d", "/s", "/c"])
else:
self.assertEqual(argv[:2], ["/bin/sh", "-c"])
def test_foreground_shell_still_executes_command(self) -> None:
with tempfile.TemporaryDirectory() as tmp:
result = ShellTool(base_dir=Path(tmp)).execute("echo shell-ok")
self.assertIn("shell-ok", result)
self.assertIn("[exit 0]", result)
def test_background_shell_persists_explicit_argv(self) -> None:
with tempfile.TemporaryDirectory() as tmp, patch(
"tools.shell.procs.count_running", return_value=0
), patch("tools.shell.procs.launch_host", return_value=("proc-1", Path(tmp))) as launch:
result = ShellTool(base_dir=Path(tmp)).execute(
"echo background-ok", background=True
)
self.assertIn("proc_id=proc-1", result)
kwargs = launch.call_args.kwargs
self.assertEqual(kwargs["argv"], procs.shell_argv("echo background-ok"))
self.assertNotIn("shell_cmd", kwargs)
if __name__ == "__main__":
unittest.main()