diff --git a/Misc/NEWS.d/next/Library/2018-12-12-22-52-34.bpo-31446.l--Fjz.rst b/Misc/NEWS.d/next/Library/2018-12-12-22-52-34.bpo-31446.l--Fjz.rst new file mode 100644 index 00000000000..741263f16bb --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-12-12-22-52-34.bpo-31446.l--Fjz.rst @@ -0,0 +1,2 @@ +Copy command line that was passed to CreateProcessW since this function can +change the content of the input buffer. diff --git a/Modules/_winapi.c b/Modules/_winapi.c index 44788e5992a..852e0a7d7b4 100644 --- a/Modules/_winapi.c +++ b/Modules/_winapi.c @@ -975,7 +975,8 @@ getattributelist(PyObject *obj, const char *name, AttributeList *attribute_list) _winapi.CreateProcess application_name: Py_UNICODE(accept={str, NoneType}) - command_line: Py_UNICODE(accept={str, NoneType}) + command_line: object + Can be str or None proc_attrs: object Ignored internally, can be None. thread_attrs: object @@ -995,12 +996,12 @@ process ID, and thread ID. static PyObject * _winapi_CreateProcess_impl(PyObject *module, Py_UNICODE *application_name, - Py_UNICODE *command_line, PyObject *proc_attrs, + PyObject *command_line, PyObject *proc_attrs, PyObject *thread_attrs, BOOL inherit_handles, DWORD creation_flags, PyObject *env_mapping, Py_UNICODE *current_directory, PyObject *startup_info) -/*[clinic end generated code: output=4652a33aff4b0ae1 input=4a43b05038d639bb]*/ +/*[clinic end generated code: output=2ecaab46a05e3123 input=42ac293eaea03fc4]*/ { PyObject *ret = NULL; BOOL result; @@ -1008,6 +1009,7 @@ _winapi_CreateProcess_impl(PyObject *module, Py_UNICODE *application_name, STARTUPINFOEXW si; PyObject *environment = NULL; wchar_t *wenvironment; + wchar_t *command_line_copy = NULL; AttributeList attribute_list = {0}; ZeroMemory(&si, sizeof(si)); @@ -1042,10 +1044,23 @@ _winapi_CreateProcess_impl(PyObject *module, Py_UNICODE *application_name, goto cleanup; si.lpAttributeList = attribute_list.attribute_list; + if (PyUnicode_Check(command_line)) { + command_line_copy = PyUnicode_AsWideCharString(command_line, NULL); + if (command_line_copy == NULL) { + goto cleanup; + } + } + else if (command_line != Py_None) { + PyErr_Format(PyExc_TypeError, + "CreateProcess() argument 2 must be str or None, not %s", + Py_TYPE(command_line)->tp_name); + goto cleanup; + } + Py_BEGIN_ALLOW_THREADS result = CreateProcessW(application_name, - command_line, + command_line_copy, NULL, NULL, inherit_handles, @@ -1069,6 +1084,7 @@ _winapi_CreateProcess_impl(PyObject *module, Py_UNICODE *application_name, pi.dwThreadId); cleanup: + PyMem_Free(command_line_copy); Py_XDECREF(environment); freeattributelist(&attribute_list); diff --git a/Modules/clinic/_winapi.c.h b/Modules/clinic/_winapi.c.h index f82b46d7381..241c18e5a25 100644 --- a/Modules/clinic/_winapi.c.h +++ b/Modules/clinic/_winapi.c.h @@ -286,6 +286,8 @@ PyDoc_STRVAR(_winapi_CreateProcess__doc__, "\n" "Create a new process and its primary thread.\n" "\n" +" command_line\n" +" Can be str or None\n" " proc_attrs\n" " Ignored internally, can be None.\n" " thread_attrs\n" @@ -299,7 +301,7 @@ PyDoc_STRVAR(_winapi_CreateProcess__doc__, static PyObject * _winapi_CreateProcess_impl(PyObject *module, Py_UNICODE *application_name, - Py_UNICODE *command_line, PyObject *proc_attrs, + PyObject *command_line, PyObject *proc_attrs, PyObject *thread_attrs, BOOL inherit_handles, DWORD creation_flags, PyObject *env_mapping, Py_UNICODE *current_directory, @@ -310,7 +312,7 @@ _winapi_CreateProcess(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; Py_UNICODE *application_name; - Py_UNICODE *command_line; + PyObject *command_line; PyObject *proc_attrs; PyObject *thread_attrs; BOOL inherit_handles; @@ -319,7 +321,7 @@ _winapi_CreateProcess(PyObject *module, PyObject *const *args, Py_ssize_t nargs) Py_UNICODE *current_directory; PyObject *startup_info; - if (!_PyArg_ParseStack(args, nargs, "ZZOOikOZO:CreateProcess", + if (!_PyArg_ParseStack(args, nargs, "ZOOOikOZO:CreateProcess", &application_name, &command_line, &proc_attrs, &thread_attrs, &inherit_handles, &creation_flags, &env_mapping, ¤t_directory, &startup_info)) { goto exit; } @@ -941,4 +943,4 @@ _winapi_GetFileType(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P exit: return return_value; } -/*[clinic end generated code: output=915dd640329de0c0 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1568ad4bd625f2af input=a9049054013a1b77]*/