@@ -752,12 +752,12 @@ gethandle(PyObject* obj, const char* name)
752752 return ret ;
753753}
754754
755- static PyObject *
755+ static wchar_t *
756756getenvironment (PyObject * environment )
757757{
758758 Py_ssize_t i , envsize , totalsize ;
759- Py_UCS4 * buffer = NULL , * p , * end ;
760- PyObject * keys , * values , * res ;
759+ wchar_t * buffer = NULL , * p , * end ;
760+ PyObject * keys , * values ;
761761
762762 /* convert environment dictionary to windows environment string */
763763 if (! PyMapping_Check (environment )) {
@@ -775,17 +775,18 @@ getenvironment(PyObject* environment)
775775 goto error ;
776776 }
777777
778- envsize = PySequence_Fast_GET_SIZE (keys );
779- if (PySequence_Fast_GET_SIZE (values ) != envsize ) {
778+ envsize = PyList_GET_SIZE (keys );
779+ if (PyList_GET_SIZE (values ) != envsize ) {
780780 PyErr_SetString (PyExc_RuntimeError ,
781781 "environment changed size during iteration" );
782782 goto error ;
783783 }
784784
785785 totalsize = 1 ; /* trailing null character */
786786 for (i = 0 ; i < envsize ; i ++ ) {
787- PyObject * key = PySequence_Fast_GET_ITEM (keys , i );
788- PyObject * value = PySequence_Fast_GET_ITEM (values , i );
787+ PyObject * key = PyList_GET_ITEM (keys , i );
788+ PyObject * value = PyList_GET_ITEM (values , i );
789+ Py_ssize_t size ;
789790
790791 if (! PyUnicode_Check (key ) || ! PyUnicode_Check (value )) {
791792 PyErr_SetString (PyExc_TypeError ,
@@ -806,19 +807,25 @@ getenvironment(PyObject* environment)
806807 PyErr_SetString (PyExc_ValueError , "illegal environment variable name" );
807808 goto error ;
808809 }
809- if (totalsize > PY_SSIZE_T_MAX - PyUnicode_GET_LENGTH (key ) - 1 ) {
810+
811+ size = PyUnicode_AsWideChar (key , NULL , 0 );
812+ assert (size > 1 );
813+ if (totalsize > PY_SSIZE_T_MAX - size ) {
810814 PyErr_SetString (PyExc_OverflowError , "environment too long" );
811815 goto error ;
812816 }
813- totalsize += PyUnicode_GET_LENGTH (key ) + 1 ; /* +1 for '=' */
814- if (totalsize > PY_SSIZE_T_MAX - PyUnicode_GET_LENGTH (value ) - 1 ) {
817+ totalsize += size ; /* including '=' */
818+
819+ size = PyUnicode_AsWideChar (value , NULL , 0 );
820+ assert (size > 0 );
821+ if (totalsize > PY_SSIZE_T_MAX - size ) {
815822 PyErr_SetString (PyExc_OverflowError , "environment too long" );
816823 goto error ;
817824 }
818- totalsize += PyUnicode_GET_LENGTH ( value ) + 1 ; /* +1 for '\0' */
825+ totalsize += size ; /* including trailing '\0' */
819826 }
820827
821- buffer = PyMem_NEW (Py_UCS4 , totalsize );
828+ buffer = PyMem_NEW (wchar_t , totalsize );
822829 if (! buffer ) {
823830 PyErr_NoMemory ();
824831 goto error ;
@@ -827,34 +834,25 @@ getenvironment(PyObject* environment)
827834 end = buffer + totalsize ;
828835
829836 for (i = 0 ; i < envsize ; i ++ ) {
830- PyObject * key = PySequence_Fast_GET_ITEM (keys , i );
831- PyObject * value = PySequence_Fast_GET_ITEM (values , i );
832- if (!PyUnicode_AsUCS4 (key , p , end - p , 0 ))
833- goto error ;
834- p += PyUnicode_GET_LENGTH (key );
835- * p ++ = '=' ;
836- if (!PyUnicode_AsUCS4 (value , p , end - p , 0 ))
837- goto error ;
838- p += PyUnicode_GET_LENGTH (value );
839- * p ++ = '\0' ;
837+ PyObject * key = PyList_GET_ITEM (keys , i );
838+ PyObject * value = PyList_GET_ITEM (values , i );
839+ Py_ssize_t size = PyUnicode_AsWideChar (key , p , end - p );
840+ assert (1 <= size && size < end - p );
841+ p += size ;
842+ * p ++ = L'=' ;
843+ size = PyUnicode_AsWideChar (value , p , end - p );
844+ assert (0 <= size && size < end - p );
845+ p += size + 1 ;
840846 }
841847
842- /* add trailing null byte */
843- * p ++ = '\0' ;
848+ /* add trailing null character */
849+ * p ++ = L '\0' ;
844850 assert (p == end );
845851
846- Py_XDECREF (keys );
847- Py_XDECREF (values );
848-
849- res = PyUnicode_FromKindAndData (PyUnicode_4BYTE_KIND , buffer , p - buffer );
850- PyMem_Free (buffer );
851- return res ;
852-
853852 error :
854- PyMem_Free (buffer );
855853 Py_XDECREF (keys );
856854 Py_XDECREF (values );
857- return NULL ;
855+ return buffer ;
858856}
859857
860858static LPHANDLE
@@ -1053,8 +1051,7 @@ _winapi_CreateProcess_impl(PyObject *module,
10531051 BOOL result ;
10541052 PROCESS_INFORMATION pi ;
10551053 STARTUPINFOEXW si ;
1056- PyObject * environment = NULL ;
1057- wchar_t * wenvironment ;
1054+ wchar_t * wenvironment = NULL ;
10581055 wchar_t * command_line_copy = NULL ;
10591056 AttributeList attribute_list = {0 };
10601057
@@ -1071,20 +1068,11 @@ _winapi_CreateProcess_impl(PyObject *module,
10711068 goto cleanup ;
10721069
10731070 if (env_mapping != Py_None ) {
1074- environment = getenvironment (env_mapping );
1075- if (environment == NULL ) {
1076- goto cleanup ;
1077- }
1078- /* contains embedded null characters */
1079- wenvironment = PyUnicode_AsUnicode (environment );
1071+ wenvironment = getenvironment (env_mapping );
10801072 if (wenvironment == NULL ) {
10811073 goto cleanup ;
10821074 }
10831075 }
1084- else {
1085- environment = NULL ;
1086- wenvironment = NULL ;
1087- }
10881076
10891077 if (getattributelist (startup_info , "lpAttributeList" , & attribute_list ) < 0 )
10901078 goto cleanup ;
@@ -1131,7 +1119,7 @@ _winapi_CreateProcess_impl(PyObject *module,
11311119
11321120cleanup :
11331121 PyMem_Free (command_line_copy );
1134- Py_XDECREF ( environment );
1122+ PyMem_Free ( wenvironment );
11351123 freeattributelist (& attribute_list );
11361124
11371125 return ret ;
0 commit comments