bpo-31446: Copy command line that should be passed to CreateProcessW(). (GH-11141)

This commit is contained in:
Vladimir Matveev 2018-12-14 00:30:51 -08:00 committed by Serhiy Storchaka
parent 08c2ba0717
commit 7b36016a15
3 changed files with 28 additions and 8 deletions

View File

@ -0,0 +1,2 @@
Copy command line that was passed to CreateProcessW since this function can
change the content of the input buffer.

View File

@ -975,7 +975,8 @@ cleanup:
_winapi.CreateProcess _winapi.CreateProcess
application_name: Py_UNICODE(accept={str, NoneType}) 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 proc_attrs: object
Ignored internally, can be None. Ignored internally, can be None.
thread_attrs: object thread_attrs: object
@ -995,12 +996,12 @@ process ID, and thread ID.
static PyObject * static PyObject *
_winapi_CreateProcess_impl(PyObject *module, Py_UNICODE *application_name, _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, PyObject *thread_attrs, BOOL inherit_handles,
DWORD creation_flags, PyObject *env_mapping, DWORD creation_flags, PyObject *env_mapping,
Py_UNICODE *current_directory, Py_UNICODE *current_directory,
PyObject *startup_info) PyObject *startup_info)
/*[clinic end generated code: output=4652a33aff4b0ae1 input=4a43b05038d639bb]*/ /*[clinic end generated code: output=2ecaab46a05e3123 input=42ac293eaea03fc4]*/
{ {
PyObject *ret = NULL; PyObject *ret = NULL;
BOOL result; BOOL result;
@ -1008,6 +1009,7 @@ _winapi_CreateProcess_impl(PyObject *module, Py_UNICODE *application_name,
STARTUPINFOEXW si; STARTUPINFOEXW si;
PyObject *environment = NULL; PyObject *environment = NULL;
wchar_t *wenvironment; wchar_t *wenvironment;
wchar_t *command_line_copy = NULL;
AttributeList attribute_list = {0}; AttributeList attribute_list = {0};
ZeroMemory(&si, sizeof(si)); ZeroMemory(&si, sizeof(si));
@ -1042,10 +1044,23 @@ _winapi_CreateProcess_impl(PyObject *module, Py_UNICODE *application_name,
goto cleanup; goto cleanup;
si.lpAttributeList = attribute_list.attribute_list; 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 Py_BEGIN_ALLOW_THREADS
result = CreateProcessW(application_name, result = CreateProcessW(application_name,
command_line, command_line_copy,
NULL, NULL,
NULL, NULL,
inherit_handles, inherit_handles,
@ -1069,6 +1084,7 @@ _winapi_CreateProcess_impl(PyObject *module, Py_UNICODE *application_name,
pi.dwThreadId); pi.dwThreadId);
cleanup: cleanup:
PyMem_Free(command_line_copy);
Py_XDECREF(environment); Py_XDECREF(environment);
freeattributelist(&attribute_list); freeattributelist(&attribute_list);

View File

@ -286,6 +286,8 @@ PyDoc_STRVAR(_winapi_CreateProcess__doc__,
"\n" "\n"
"Create a new process and its primary thread.\n" "Create a new process and its primary thread.\n"
"\n" "\n"
" command_line\n"
" Can be str or None\n"
" proc_attrs\n" " proc_attrs\n"
" Ignored internally, can be None.\n" " Ignored internally, can be None.\n"
" thread_attrs\n" " thread_attrs\n"
@ -299,7 +301,7 @@ PyDoc_STRVAR(_winapi_CreateProcess__doc__,
static PyObject * static PyObject *
_winapi_CreateProcess_impl(PyObject *module, Py_UNICODE *application_name, _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, PyObject *thread_attrs, BOOL inherit_handles,
DWORD creation_flags, PyObject *env_mapping, DWORD creation_flags, PyObject *env_mapping,
Py_UNICODE *current_directory, Py_UNICODE *current_directory,
@ -310,7 +312,7 @@ _winapi_CreateProcess(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
{ {
PyObject *return_value = NULL; PyObject *return_value = NULL;
Py_UNICODE *application_name; Py_UNICODE *application_name;
Py_UNICODE *command_line; PyObject *command_line;
PyObject *proc_attrs; PyObject *proc_attrs;
PyObject *thread_attrs; PyObject *thread_attrs;
BOOL inherit_handles; BOOL inherit_handles;
@ -319,7 +321,7 @@ _winapi_CreateProcess(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
Py_UNICODE *current_directory; Py_UNICODE *current_directory;
PyObject *startup_info; 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, &current_directory, &startup_info)) { &application_name, &command_line, &proc_attrs, &thread_attrs, &inherit_handles, &creation_flags, &env_mapping, &current_directory, &startup_info)) {
goto exit; goto exit;
} }
@ -941,4 +943,4 @@ _winapi_GetFileType(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P
exit: exit:
return return_value; return return_value;
} }
/*[clinic end generated code: output=915dd640329de0c0 input=a9049054013a1b77]*/ /*[clinic end generated code: output=1568ad4bd625f2af input=a9049054013a1b77]*/