From 922b2a0d0d9928af420ea4d5c104f8be72517aa2 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 14 Dec 2018 11:18:13 +0200 Subject: [PATCH] [3.7] bpo-31446: Copy command line that should be passed to CreateProcessW(). (GH-11141). (GH-11149) (cherry picked from commit 7b36016a15aeed0d76a4c05a66203e6d7723aace) Co-authored-by: Vladimir Matveev --- .../2018-12-12-22-52-34.bpo-31446.l--Fjz.rst | 2 ++ Modules/_winapi.c | 24 +++++++++++++++---- Modules/clinic/_winapi.c.h | 10 ++++---- 3 files changed, 28 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2018-12-12-22-52-34.bpo-31446.l--Fjz.rst 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 9ea5a926629..127f8886e21 100644 --- a/Modules/_winapi.c +++ b/Modules/_winapi.c @@ -974,7 +974,8 @@ cleanup: _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 @@ -994,12 +995,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; @@ -1007,6 +1008,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)); @@ -1041,10 +1043,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, @@ -1068,6 +1083,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 c66522ebab6..436fbe54947 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=baaf3d379b91be0a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=3a6492395b11b5a5 input=a9049054013a1b77]*/