changeset: 105197:af78b33704af branch: 3.6 parent: 105194:1a9e4b465497 parent: 105196:e076ace7b0ff user: Steve Dower date: Sat Nov 19 19:17:26 2016 -0800 files: Lib/test/test_os.py Modules/posixmodule.c description: Issue #28732: Raise ValueError when argv[0] is empty diff -r 1a9e4b465497 -r af78b33704af Lib/test/test_os.py --- a/Lib/test/test_os.py Sat Nov 19 18:53:19 2016 -0800 +++ b/Lib/test/test_os.py Sat Nov 19 19:17:26 2016 -0800 @@ -1481,8 +1481,16 @@ self.assertRaises(OSError, os.execvpe, 'no such app-', ['no such app-'], None) + def test_execv_with_bad_arglist(self): + self.assertRaises(ValueError, os.execv, 'notepad', ()) + self.assertRaises(ValueError, os.execv, 'notepad', []) + self.assertRaises(ValueError, os.execv, 'notepad', ('',)) + self.assertRaises(ValueError, os.execv, 'notepad', ['']) + def test_execvpe_with_bad_arglist(self): self.assertRaises(ValueError, os.execvpe, 'notepad', [], None) + self.assertRaises(ValueError, os.execvpe, 'notepad', [], {}) + self.assertRaises(ValueError, os.execvpe, 'notepad', [''], {}) @unittest.skipUnless(hasattr(os, '_execvpe'), "No internal os._execvpe function to test.") @@ -2325,23 +2333,29 @@ def test_spawnl_noargs(self): args = self.create_args() self.assertRaises(ValueError, os.spawnl, os.P_NOWAIT, args[0]) + self.assertRaises(ValueError, os.spawnl, os.P_NOWAIT, args[0], '') @requires_os_func('spawnle') - def test_spawnl_noargs(self): + def test_spawnle_noargs(self): args = self.create_args() self.assertRaises(ValueError, os.spawnle, os.P_NOWAIT, args[0], {}) + self.assertRaises(ValueError, os.spawnle, os.P_NOWAIT, args[0], '', {}) @requires_os_func('spawnv') def test_spawnv_noargs(self): args = self.create_args() self.assertRaises(ValueError, os.spawnv, os.P_NOWAIT, args[0], ()) self.assertRaises(ValueError, os.spawnv, os.P_NOWAIT, args[0], []) + self.assertRaises(ValueError, os.spawnv, os.P_NOWAIT, args[0], ('',)) + self.assertRaises(ValueError, os.spawnv, os.P_NOWAIT, args[0], ['']) @requires_os_func('spawnve') - def test_spawnv_noargs(self): + def test_spawnve_noargs(self): args = self.create_args() self.assertRaises(ValueError, os.spawnve, os.P_NOWAIT, args[0], (), {}) self.assertRaises(ValueError, os.spawnve, os.P_NOWAIT, args[0], [], {}) + self.assertRaises(ValueError, os.spawnve, os.P_NOWAIT, args[0], ('',), {}) + self.assertRaises(ValueError, os.spawnve, os.P_NOWAIT, args[0], [''], {}) # The introduction of this TestCase caused at least two different errors on # *nix buildbots. Temporarily skip this to let the buildbots move along. diff -r 1a9e4b465497 -r af78b33704af Modules/posixmodule.c --- a/Modules/posixmodule.c Sat Nov 19 18:53:19 2016 -0800 +++ b/Modules/posixmodule.c Sat Nov 19 19:17:26 2016 -0800 @@ -4916,12 +4916,20 @@ if (argvlist == NULL) { return NULL; } - + if (!argvlist[0][0]) { + PyErr_SetString(PyExc_ValueError, + "execv() arg 2 first element cannot be empty"); + free_string_array(argvlist, argc); + return NULL; + } + + _Py_BEGIN_SUPPRESS_IPH #ifdef HAVE_WEXECV _wexecv(path->wide, argvlist); #else execv(path->narrow, argvlist); #endif + _Py_END_SUPPRESS_IPH /* If we get here it's definitely an error */ @@ -4961,6 +4969,11 @@ goto fail; } argc = PySequence_Size(argv); + if (argc < 1) { + PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty"); + return NULL; + } + if (!PyMapping_Check(env)) { PyErr_SetString(PyExc_TypeError, "execve: environment must be a mapping object"); @@ -4971,11 +4984,17 @@ if (argvlist == NULL) { goto fail; } + if (!argvlist[0][0]) { + PyErr_SetString(PyExc_ValueError, + "execve: argv first element cannot be empty"); + goto fail; + } envlist = parse_envlist(env, &envc); if (envlist == NULL) goto fail; + _Py_BEGIN_SUPPRESS_IPH #ifdef HAVE_FEXECVE if (path->fd > -1) fexecve(path->fd, argvlist, envlist); @@ -4986,6 +5005,7 @@ #else execve(path->narrow, argvlist, envlist); #endif + _Py_END_SUPPRESS_IPH /* If we get here it's definitely an error */ @@ -5061,6 +5081,13 @@ "spawnv() arg 2 must contain only strings"); return NULL; } + if (i == 0 && !argvlist[0][0]) { + free_string_array(argvlist, i); + PyErr_SetString( + PyExc_ValueError, + "spawnv() arg 2 first element cannot be empty"); + return NULL; + } } argvlist[argc] = NULL; @@ -5155,6 +5182,13 @@ lastarg = i; goto fail_1; } + if (i == 0 && !argvlist[0][0]) { + lastarg = i; + PyErr_SetString( + PyExc_ValueError, + "spawnv() arg 2 first element cannot be empty"); + goto fail_1; + } } lastarg = argc; argvlist[argc] = NULL;