@@ -599,11 +599,32 @@ def test_urandom_failure(self):
599599 assert_python_ok ('-c' , code )
600600
601601
602- class ExecvpeTests (unittest .TestCase ):
602+ class ExecTests (unittest .TestCase ):
603603
604604 def test_execvpe_with_bad_arglist (self ):
605605 self .assertRaises (ValueError , os .execvpe , 'notepad' , [], None )
606606
607+ def test_execve_invalid_env (self ):
608+ args = [sys .executable , '-c' , 'pass' ]
609+
610+ # null character in the enviroment variable name
611+ newenv = os .environ .copy ()
612+ newenv ["FRUIT\0 VEGETABLE" ] = "cabbage"
613+ with self .assertRaises (TypeError ):
614+ os .execve (args [0 ], args , newenv )
615+
616+ # null character in the enviroment variable value
617+ newenv = os .environ .copy ()
618+ newenv ["FRUIT" ] = "orange\0 VEGETABLE=cabbage"
619+ with self .assertRaises (TypeError ):
620+ os .execve (args [0 ], args , newenv )
621+
622+ # equal character in the enviroment variable name
623+ newenv = os .environ .copy ()
624+ newenv ["FRUIT=ORANGE" ] = "lemon"
625+ with self .assertRaises (ValueError ):
626+ os .execve (args [0 ], args , newenv )
627+
607628
608629@unittest .skipUnless (sys .platform == "win32" , "Win32 specific tests" )
609630class Win32ErrorTests (unittest .TestCase ):
@@ -879,6 +900,62 @@ def test_CTRL_BREAK_EVENT(self):
879900 self ._kill_with_event (signal .CTRL_BREAK_EVENT , "CTRL_BREAK_EVENT" )
880901
881902
903+ class SpawnTests (unittest .TestCase ):
904+ def _test_invalid_env (self , spawn ):
905+ args = [sys .executable , '-c' , 'pass' ]
906+
907+ # null character in the enviroment variable name
908+ newenv = os .environ .copy ()
909+ newenv ["FRUIT\0 VEGETABLE" ] = "cabbage"
910+ try :
911+ exitcode = spawn (os .P_WAIT , args [0 ], args , newenv )
912+ except TypeError :
913+ pass
914+ else :
915+ self .assertEqual (exitcode , 127 )
916+
917+ # null character in the enviroment variable value
918+ newenv = os .environ .copy ()
919+ newenv ["FRUIT" ] = "orange\0 VEGETABLE=cabbage"
920+ try :
921+ exitcode = spawn (os .P_WAIT , args [0 ], args , newenv )
922+ except TypeError :
923+ pass
924+ else :
925+ self .assertEqual (exitcode , 127 )
926+
927+ # equal character in the enviroment variable name
928+ newenv = os .environ .copy ()
929+ newenv ["FRUIT=ORANGE" ] = "lemon"
930+ try :
931+ exitcode = spawn (os .P_WAIT , args [0 ], args , newenv )
932+ except ValueError :
933+ pass
934+ else :
935+ self .assertEqual (exitcode , 127 )
936+
937+ # equal character in the enviroment variable value
938+ filename = test_support .TESTFN
939+ self .addCleanup (test_support .unlink , filename )
940+ with open (filename , "w" ) as fp :
941+ fp .write ('import sys, os\n '
942+ 'if os.getenv("FRUIT") != "orange=lemon":\n '
943+ ' raise AssertionError' )
944+ args = [sys .executable , filename ]
945+ newenv = os .environ .copy ()
946+ newenv ["FRUIT" ] = "orange=lemon"
947+ exitcode = spawn (os .P_WAIT , args [0 ], args , newenv )
948+ self .assertEqual (exitcode , 0 )
949+
950+ @unittest .skipUnless (hasattr (os , 'spawnve' ), 'test needs os.spawnve()' )
951+ def test_spawnve_invalid_env (self ):
952+ self ._test_invalid_env (os .spawnve )
953+
954+ @unittest .skipUnless (hasattr (os , 'spawnvpe' ), 'test needs os.spawnvpe()' )
955+ def test_spawnvpe_invalid_env (self ):
956+ self ._test_invalid_env (os .spawnvpe )
957+
958+
882959def test_main ():
883960 test_support .run_unittest (
884961 FileTests ,
@@ -890,11 +967,12 @@ def test_main():
890967 DevNullTests ,
891968 URandomTests ,
892969 URandomFDTests ,
893- ExecvpeTests ,
970+ ExecTests ,
894971 Win32ErrorTests ,
895972 TestInvalidFD ,
896973 PosixUidGidTests ,
897- Win32KillTests
974+ Win32KillTests ,
975+ SpawnTests ,
898976 )
899977
900978if __name__ == "__main__" :
0 commit comments