diff options
author | Gregory P. Smith <greg@mad-scientist.com> | 2010-03-15 06:07:42 (GMT) |
---|---|---|
committer | Gregory P. Smith <greg@mad-scientist.com> | 2010-03-15 06:07:42 (GMT) |
commit | 68f52178d9a77bb598664a090019f8f971d3de7d (patch) | |
tree | bbca03fa51b719d6b9841d0e1b6d4825cd993874 | |
parent | 845085703cacab33293898cb183f618d9f580d92 (diff) | |
download | cpython-68f52178d9a77bb598664a090019f8f971d3de7d.zip cpython-68f52178d9a77bb598664a090019f8f971d3de7d.tar.gz cpython-68f52178d9a77bb598664a090019f8f971d3de7d.tar.bz2 |
* Fix the refcount leak in _PySequence_BytesToCharpArray from r78946.
* Also fixes a potential extra DECREF of an arg in the error case within
_posixsubprocess.fork_exec() by not reusing the process_args variable.
-rw-r--r-- | Modules/_posixsubprocess.c | 16 | ||||
-rw-r--r-- | Objects/abstract.c | 5 |
2 files changed, 13 insertions, 8 deletions
diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c index d388d89..f9b38b6 100644 --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@ -172,7 +172,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args) PyObject *gc_module = NULL; PyObject *executable_list, *py_close_fds; PyObject *env_list, *preexec_fn; - PyObject *process_args = NULL, *converted_args = NULL; + PyObject *process_args, *converted_args = NULL, *fast_args = NULL; PyObject *preexec_fn_args_tuple = NULL; int p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite; int errpipe_read, errpipe_write, close_fds, restore_signals; @@ -224,15 +224,17 @@ subprocess_fork_exec(PyObject* self, PyObject *args) /* These conversions are done in the parent process to avoid allocating or freeing memory in the child process. */ if (process_args != Py_None) { + Py_ssize_t num_args; /* Equivalent to: */ /* tuple(PyUnicode_FSConverter(arg) for arg in process_args) */ - process_args = PySequence_Fast(process_args, "argv must be a tuple"); - converted_args = PyTuple_New(PySequence_Size(process_args)); + fast_args = PySequence_Fast(process_args, "argv must be a tuple"); + num_args = PySequence_Fast_GET_SIZE(fast_args); + converted_args = PyTuple_New(num_args); if (converted_args == NULL) goto cleanup; - for (arg_num = 0; arg_num < PySequence_Size(process_args); ++arg_num) { + for (arg_num = 0; arg_num < num_args; ++arg_num) { PyObject *borrowed_arg, *converted_arg; - borrowed_arg = PySequence_Fast_GET_ITEM(process_args, arg_num); + borrowed_arg = PySequence_Fast_GET_ITEM(fast_args, arg_num); if (PyUnicode_FSConverter(borrowed_arg, &converted_arg) == 0) goto cleanup; PyTuple_SET_ITEM(converted_args, arg_num, converted_arg); @@ -240,7 +242,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args) argv = _PySequence_BytesToCharpArray(converted_args); Py_CLEAR(converted_args); - Py_CLEAR(process_args); + Py_CLEAR(fast_args); if (!argv) goto cleanup; } @@ -319,7 +321,7 @@ cleanup: _Py_FreeCharPArray(argv); _Py_FreeCharPArray(exec_array); Py_XDECREF(converted_args); - Py_XDECREF(process_args); + Py_XDECREF(fast_args); /* Reenable gc if it was disabled. */ if (need_to_reenable_gc) diff --git a/Objects/abstract.c b/Objects/abstract.c index 952ad40..cd5a9fd 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2737,6 +2737,7 @@ _PySequence_BytesToCharpArray(PyObject* self) { char **array; Py_ssize_t i, argc; + PyObject *item = NULL; argc = PySequence_Size(self); if (argc == -1) @@ -2749,7 +2750,7 @@ _PySequence_BytesToCharpArray(PyObject* self) } for (i = 0; i < argc; ++i) { char *data; - PyObject *item = PySequence_GetItem(self, i); + item = PySequence_GetItem(self, i); data = PyBytes_AsString(item); if (data == NULL) { /* NULL terminate before freeing. */ @@ -2761,12 +2762,14 @@ _PySequence_BytesToCharpArray(PyObject* self) PyErr_NoMemory(); goto fail; } + Py_DECREF(item); } array[argc] = NULL; return array; fail: + Py_XDECREF(item); _Py_FreeCharPArray(array); return NULL; } |