@@ -2624,6 +2624,40 @@ def test_execve_invalid_env(self):
26242624 with self .assertRaises (ValueError ):
26252625 os .execve (args [0 ], args , newenv )
26262626
2627+ # See https://github.com/python/cpython/issues/137934 and the other
2628+ # related issues for the reason why we cannot test this on Windows.
2629+ @unittest .skipIf (os .name == "nt" , "POSIX-specific test" )
2630+ def test_execve_env_concurrent_mutation_with_fspath_posix (self ):
2631+ # Prevent crash when mutating environment during parsing.
2632+ # Regression test for https://github.com/python/cpython/issues/143309.
2633+
2634+ message = "hello from execve"
2635+ code = """
2636+ import os, sys
2637+
2638+ class MyPath:
2639+ def __fspath__(self):
2640+ mutated.clear()
2641+ return b"pwn"
2642+
2643+ mutated = KEYS = VALUES = [MyPath()]
2644+
2645+ class MyEnv:
2646+ def __getitem__(self): raise RuntimeError("must not be called")
2647+ def __len__(self): return 1
2648+ def keys(self): return KEYS
2649+ def values(self): return VALUES
2650+
2651+ args = [sys.executable, '-c', "print({message!r})"]
2652+ os.execve(args[0], args, MyEnv())
2653+ """ .format (message = message )
2654+
2655+ # Use '__cleanenv' to signal to assert_python_ok() not
2656+ # to do a copy of os.environ on its own.
2657+ rc , out , _ = assert_python_ok ('-c' , code , __cleanenv = True )
2658+ self .assertEqual (rc , 0 )
2659+ self .assertIn (bytes (message , "ascii" ), out )
2660+
26272661 @unittest .skipUnless (sys .platform == "win32" , "Win32-specific test" )
26282662 def test_execve_with_empty_path (self ):
26292663 # bpo-32890: Check GetLastError() misuse
0 commit comments