Commit 5ab602a8 authored by Steve Dower's avatar Steve Dower

Issue #28732: Raise ValueError when argv[0] is empty

parents 474d01a0 37cd2d2a
...@@ -1481,8 +1481,16 @@ class ExecTests(unittest.TestCase): ...@@ -1481,8 +1481,16 @@ class ExecTests(unittest.TestCase):
self.assertRaises(OSError, os.execvpe, 'no such app-', self.assertRaises(OSError, os.execvpe, 'no such app-',
['no such app-'], None) ['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): def test_execvpe_with_bad_arglist(self):
self.assertRaises(ValueError, os.execvpe, 'notepad', [], None) self.assertRaises(ValueError, os.execvpe, 'notepad', [], None)
self.assertRaises(ValueError, os.execvpe, 'notepad', [], {})
self.assertRaises(ValueError, os.execvpe, 'notepad', [''], {})
@unittest.skipUnless(hasattr(os, '_execvpe'), @unittest.skipUnless(hasattr(os, '_execvpe'),
"No internal os._execvpe function to test.") "No internal os._execvpe function to test.")
...@@ -2325,23 +2333,29 @@ class SpawnTests(unittest.TestCase): ...@@ -2325,23 +2333,29 @@ class SpawnTests(unittest.TestCase):
def test_spawnl_noargs(self): def test_spawnl_noargs(self):
args = self.create_args() args = self.create_args()
self.assertRaises(ValueError, os.spawnl, os.P_NOWAIT, args[0]) self.assertRaises(ValueError, os.spawnl, os.P_NOWAIT, args[0])
self.assertRaises(ValueError, os.spawnl, os.P_NOWAIT, args[0], '')
@requires_os_func('spawnle') @requires_os_func('spawnle')
def test_spawnl_noargs(self): def test_spawnle_noargs(self):
args = self.create_args() args = self.create_args()
self.assertRaises(ValueError, os.spawnle, os.P_NOWAIT, args[0], {}) self.assertRaises(ValueError, os.spawnle, os.P_NOWAIT, args[0], {})
self.assertRaises(ValueError, os.spawnle, os.P_NOWAIT, args[0], '', {})
@requires_os_func('spawnv') @requires_os_func('spawnv')
def test_spawnv_noargs(self): def test_spawnv_noargs(self):
args = self.create_args() 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], [])
self.assertRaises(ValueError, os.spawnv, os.P_NOWAIT, args[0], ('',))
self.assertRaises(ValueError, os.spawnv, os.P_NOWAIT, args[0], [''])
@requires_os_func('spawnve') @requires_os_func('spawnve')
def test_spawnv_noargs(self): def test_spawnve_noargs(self):
args = self.create_args() 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], [], {})
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 # The introduction of this TestCase caused at least two different errors on
# *nix buildbots. Temporarily skip this to let the buildbots move along. # *nix buildbots. Temporarily skip this to let the buildbots move along.
......
...@@ -4916,12 +4916,20 @@ os_execv_impl(PyObject *module, path_t *path, PyObject *argv) ...@@ -4916,12 +4916,20 @@ os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
if (argvlist == NULL) { if (argvlist == NULL) {
return 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 #ifdef HAVE_WEXECV
_wexecv(path->wide, argvlist); _wexecv(path->wide, argvlist);
#else #else
execv(path->narrow, argvlist); execv(path->narrow, argvlist);
#endif #endif
_Py_END_SUPPRESS_IPH
/* If we get here it's definitely an error */ /* If we get here it's definitely an error */
...@@ -4961,6 +4969,11 @@ os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env) ...@@ -4961,6 +4969,11 @@ os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
goto fail; goto fail;
} }
argc = PySequence_Size(argv); argc = PySequence_Size(argv);
if (argc < 1) {
PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty");
return NULL;
}
if (!PyMapping_Check(env)) { if (!PyMapping_Check(env)) {
PyErr_SetString(PyExc_TypeError, PyErr_SetString(PyExc_TypeError,
"execve: environment must be a mapping object"); "execve: environment must be a mapping object");
...@@ -4971,11 +4984,17 @@ os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env) ...@@ -4971,11 +4984,17 @@ os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
if (argvlist == NULL) { if (argvlist == NULL) {
goto fail; goto fail;
} }
if (!argvlist[0][0]) {
PyErr_SetString(PyExc_ValueError,
"execve: argv first element cannot be empty");
goto fail;
}
envlist = parse_envlist(env, &envc); envlist = parse_envlist(env, &envc);
if (envlist == NULL) if (envlist == NULL)
goto fail; goto fail;
_Py_BEGIN_SUPPRESS_IPH
#ifdef HAVE_FEXECVE #ifdef HAVE_FEXECVE
if (path->fd > -1) if (path->fd > -1)
fexecve(path->fd, argvlist, envlist); fexecve(path->fd, argvlist, envlist);
...@@ -4986,6 +5005,7 @@ os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env) ...@@ -4986,6 +5005,7 @@ os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
#else #else
execve(path->narrow, argvlist, envlist); execve(path->narrow, argvlist, envlist);
#endif #endif
_Py_END_SUPPRESS_IPH
/* If we get here it's definitely an error */ /* If we get here it's definitely an error */
...@@ -5061,6 +5081,13 @@ os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv) ...@@ -5061,6 +5081,13 @@ os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
"spawnv() arg 2 must contain only strings"); "spawnv() arg 2 must contain only strings");
return NULL; 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; argvlist[argc] = NULL;
...@@ -5155,6 +5182,13 @@ os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv, ...@@ -5155,6 +5182,13 @@ os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
lastarg = i; lastarg = i;
goto fail_1; 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; lastarg = argc;
argvlist[argc] = NULL; argvlist[argc] = NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment