1212import time
1313import unittest
1414import zipfile
15+ from unittest import mock
1516from pathlib import Path
1617
1718
@@ -27,13 +28,22 @@ def load_json(path: Path) -> dict:
2728 return json .loads (path .read_text (encoding = "utf-8" ))
2829
2930
31+ def runtime_test_env () -> dict [str , str ]:
32+ # 安全回归必须使用原生引擎和默认 graded 策略,不能继承 runner 的演示/降级开关。
33+ env = {key : value for key , value in os .environ .items ()
34+ if not key .startswith ("MIMOSA_" ) and key not in {"NODE_OPTIONS" , "NODE_PATH" }}
35+ env ["MIMOSA_ENGINE" ] = "native"
36+ return env
37+
38+
3039def run_node (* args : str , cwd : Path | None = None , input_text : str | None = None ) -> subprocess .CompletedProcess [str ]:
3140 node = shutil .which ("node" )
3241 if node is None :
3342 raise AssertionError ("node must be available in PATH to validate Mimosa" )
3443 return subprocess .run (
3544 [node , * args ],
3645 cwd = cwd ,
46+ env = runtime_test_env (),
3747 input = input_text ,
3848 capture_output = True ,
3949 text = True ,
@@ -59,8 +69,7 @@ def __init__(self, server: Path, cwd: Path) -> None:
5969 node = shutil .which ("node" )
6070 if node is None :
6171 raise AssertionError ("node must be available in PATH to validate Mimosa" )
62- env = os .environ .copy ()
63- env ["MIMOSA_ENGINE" ] = "native"
72+ env = runtime_test_env ()
6473 self .process = subprocess .Popen (
6574 [node , str (server )],
6675 cwd = cwd ,
@@ -166,6 +175,14 @@ def assert_signed_inventory(test: unittest.TestCase, root: Path) -> None:
166175
167176
168177class MimosaPluginTest (unittest .TestCase ):
178+ def test_runtime_env_does_not_inherit_hook_overrides (self ) -> None :
179+ with mock .patch .dict (os .environ , {"MIMOSA_HOOK_BLOCK" : "warn" , "MIMOSA_NO_GIT_GATE" : "1" , "NODE_OPTIONS" : "--invalid" }):
180+ env = runtime_test_env ()
181+ self .assertNotIn ("MIMOSA_HOOK_BLOCK" , env )
182+ self .assertNotIn ("MIMOSA_NO_GIT_GATE" , env )
183+ self .assertNotIn ("NODE_OPTIONS" , env )
184+ self .assertEqual (env ["MIMOSA_ENGINE" ], "native" )
185+
169186 def test_marketplace_listing_uses_localized_product_name_and_published_icon (self ) -> None :
170187 marketplace = load_json (ROOT / "marketplace.json" )
171188 entry = next (item for item in marketplace ["plugins" ] if item ["name" ] == "mimosa" )
@@ -417,7 +434,12 @@ def test_pre_write_hook_blocks_command_injection(self) -> None:
417434 input_text = json .dumps (request ),
418435 )
419436 self .assertEqual (result .returncode , 0 , result .stderr )
420- response = json .loads (result .stdout )
437+ self .assertTrue (result .stdout .strip (),
438+ f"PreToolUse returned no decision JSON; stderr={ result .stderr [- 2000 :]!r} " )
439+ try :
440+ response = json .loads (result .stdout )
441+ except json .JSONDecodeError as error :
442+ self .fail (f"PreToolUse returned invalid JSON: { error } ; stderr={ result .stderr [- 2000 :]!r} " )
421443 decision = response ["hookSpecificOutput" ]
422444 self .assertEqual (decision ["hookEventName" ], "PreToolUse" )
423445 self .assertEqual (decision ["permissionDecision" ], "deny" )
0 commit comments