46 lines
1.6 KiB
Python
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()
|