@@ -772,23 +772,88 @@ gethandle(PyObject* obj, const char* name)
772
772
return ret ;
773
773
}
774
774
775
+ static PyObject * sortenvironmentkey (PyObject * module , PyObject * item ) {
776
+ Py_ssize_t n ;
777
+ wchar_t * s = PyUnicode_AsWideCharString (item , & n );
778
+ if (s == NULL ) {
779
+ return NULL ;
780
+ }
781
+ return _winapi_LCMapStringEx_impl (NULL , LOCALE_NAME_INVARIANT , LCMAP_UPPERCASE , s );
782
+ }
783
+
784
+ static PyMethodDef sortenvironmentkey_def = {
785
+ "sortenvironmentkey" ,
786
+ _PyCFunction_CAST (sortenvironmentkey ),
787
+ METH_O ,
788
+ ""
789
+ };
790
+
791
+ static PyObject *
792
+ normalize_environment (PyObject * environment ) {
793
+ PyObject * result , * keys , * keyfunc , * sort , * args , * kwargs ;
794
+
795
+ keys = PyMapping_Keys (environment );
796
+ if (keys == NULL ) {
797
+ return NULL ;
798
+ }
799
+
800
+ keyfunc = PyCFunction_New (& sortenvironmentkey_def , NULL );
801
+ sort = PyObject_GetAttrString (keys , "sort" );
802
+ args = PyTuple_New (0 );
803
+ kwargs = PyDict_New ();
804
+ PyDict_SetItemString (kwargs , "key" , keyfunc );
805
+ if (PyObject_Call (sort , args , kwargs ) == NULL ) {
806
+ goto error ;
807
+ }
808
+
809
+ result = PyDict_New ();
810
+
811
+ for (int i = 0 ; i < PyList_GET_SIZE (keys ); i ++ ) {
812
+ if (i < 1 ) {
813
+ continue ;
814
+ }
815
+ PyObject * key = PyList_GET_ITEM (keys , i );
816
+ wchar_t * key_string = PyUnicode_AsWideCharString (key , NULL );
817
+ wchar_t * prev_key_string = PyUnicode_AsWideCharString (PyList_GET_ITEM (keys , i - 1 ), NULL );
818
+ if (CompareStringOrdinal (prev_key_string , -1 , key_string , -1 , TRUE) == CSTR_EQUAL ) {
819
+ continue ;
820
+ }
821
+ PyObject * value = PyDict_GetItem (environment , key );
822
+ PyDict_SetItem (result , key , value );
823
+ }
824
+
825
+ error :
826
+ Py_DECREF (keys );
827
+ Py_DECREF (keyfunc );
828
+ Py_DECREF (sort );
829
+ Py_DECREF (args );
830
+ Py_DECREF (kwargs );
831
+
832
+ return result ;
833
+ }
834
+
775
835
static wchar_t *
776
- getenvironment (PyObject * environment )
836
+ getenvironment (PyObject * env )
777
837
{
778
838
Py_ssize_t i , envsize , totalsize ;
779
839
wchar_t * buffer = NULL , * p , * end ;
780
- PyObject * keys , * values ;
840
+ PyObject * environment = NULL , * keys = NULL , * values = NULL ;
781
841
782
842
/* convert environment dictionary to windows environment string */
783
- if (! PyMapping_Check (environment )) {
843
+ if (! PyMapping_Check (env )) {
784
844
PyErr_SetString (
785
845
PyExc_TypeError , "environment must be dictionary or None" );
786
846
return NULL ;
787
847
}
788
848
849
+ environment = normalize_environment (env );
850
+ if (environment == NULL ) {
851
+ goto error ;
852
+ }
853
+
789
854
keys = PyMapping_Keys (environment );
790
855
if (!keys ) {
791
- return NULL ;
856
+ goto error ;
792
857
}
793
858
values = PyMapping_Values (environment );
794
859
if (!values ) {
@@ -869,7 +934,8 @@ getenvironment(PyObject* environment)
869
934
* p ++ = L'\0' ;
870
935
assert (p == end );
871
936
872
- error :
937
+ error :
938
+ Py_XDECREF (environment );
873
939
Py_XDECREF (keys );
874
940
Py_XDECREF (values );
875
941
return buffer ;
0 commit comments