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

Serhiy Storchaka webhook-mailer at python.org
Fri Dec 14 03:30:58 EST 2018


https://github.com/python/cpython/commit/7b36016a15aeed0d76a4c05a66203e6d7723aace
commit: 7b36016a15aeed0d76a4c05a66203e6d7723aace
branch: master
author: Vladimir Matveev <v2matveev at outlook.com>
committer: Serhiy Storchaka <storchaka at gmail.com>
date: 2018-12-14T10:30:51+02:00
summary:

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

files:
A Misc/NEWS.d/next/Library/2018-12-12-22-52-34.bpo-31446.l--Fjz.rst
M Modules/_winapi.c
M Modules/clinic/_winapi.c.h

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 000000000000..741263f16bb4
--- /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 44788e5992a0..852e0a7d7b48 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 f82b46d7381c..241c18e5a252 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, &current_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]*/



More information about the Python-checkins mailing list