From eb5e3f2c6a47eb50470cdecc1c7319c25331fad2 Mon Sep 17 00:00:00 2001 From: AN Long Date: Tue, 14 Mar 2023 21:13:37 +0800 Subject: [PATCH] gh-87868: correctly sort and remove duplicates in getenvironment() --- Modules/_winapi.c | 76 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 71 insertions(+), 5 deletions(-) diff --git a/Modules/_winapi.c b/Modules/_winapi.c index 83cde7501176b64..bcc1d40b4d1e2d8 100644 --- a/Modules/_winapi.c +++ b/Modules/_winapi.c @@ -772,23 +772,88 @@ gethandle(PyObject* obj, const char* name) return ret; } +static PyObject* sortenvironmentkey(PyObject *module, PyObject *item) { + Py_ssize_t n; + wchar_t* s = PyUnicode_AsWideCharString(item, &n); + if (s == NULL) { + return NULL; + } + return _winapi_LCMapStringEx_impl(NULL, LOCALE_NAME_INVARIANT, LCMAP_UPPERCASE, s); +} + +static PyMethodDef sortenvironmentkey_def = { + "sortenvironmentkey", + _PyCFunction_CAST(sortenvironmentkey), + METH_O, + "" +}; + +static PyObject * +normalize_environment(PyObject* environment) { + PyObject *result, *keys, *keyfunc, *sort, *args, *kwargs; + + keys = PyMapping_Keys(environment); + if (keys == NULL) { + return NULL; + } + + keyfunc = PyCFunction_New(&sortenvironmentkey_def, NULL); + sort = PyObject_GetAttrString(keys, "sort"); + args = PyTuple_New(0); + kwargs = PyDict_New(); + PyDict_SetItemString(kwargs, "key", keyfunc); + if (PyObject_Call(sort, args, kwargs) == NULL) { + goto error; + } + + result = PyDict_New(); + + for (int i = 0; i