summaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/src/Modules/_winapi.c
diff options
context:
space:
mode:
authorshadchin <[email protected]>2024-02-07 09:25:06 +0300
committerAlexander Smirnov <[email protected]>2024-02-09 19:18:32 +0300
commitf0785dc88eee3da0f1514f5b4cafa931571e669d (patch)
tree44165310ad6023cd29776f9b1b4477364cd2b5bb /contrib/tools/python3/src/Modules/_winapi.c
parent2c0985fb513cb5b352324abf223bf749c6c2bd24 (diff)
Update Python 3 to 3.11.8
Diffstat (limited to 'contrib/tools/python3/src/Modules/_winapi.c')
-rw-r--r--contrib/tools/python3/src/Modules/_winapi.c218
1 files changed, 196 insertions, 22 deletions
diff --git a/contrib/tools/python3/src/Modules/_winapi.c b/contrib/tools/python3/src/Modules/_winapi.c
index dcfe3e18730..19cfa75bbe5 100644
--- a/contrib/tools/python3/src/Modules/_winapi.c
+++ b/contrib/tools/python3/src/Modules/_winapi.c
@@ -39,12 +39,13 @@
#include "structmember.h" // PyMemberDef
-#define WINDOWS_LEAN_AND_MEAN
#include "windows.h"
#include <winioctl.h>
#include <crtdbg.h>
#include "winreparse.h"
+#include "pycore_runtime.h" // _Py_ID
+
#if defined(MS_WIN32) && !defined(MS_WIN64)
#define HANDLE_TO_PYNUM(handle) \
PyLong_FromUnsignedLong((unsigned long) handle)
@@ -451,7 +452,7 @@ _winapi_ConnectNamedPipe_impl(PyObject *module, HANDLE handle,
/*[clinic input]
_winapi.CreateFile -> HANDLE
- file_name: LPCTSTR
+ file_name: LPCWSTR
desired_access: DWORD
share_mode: DWORD
security_attributes: LPSECURITY_ATTRIBUTES
@@ -462,12 +463,12 @@ _winapi.CreateFile -> HANDLE
[clinic start generated code]*/
static HANDLE
-_winapi_CreateFile_impl(PyObject *module, LPCTSTR file_name,
+_winapi_CreateFile_impl(PyObject *module, LPCWSTR file_name,
DWORD desired_access, DWORD share_mode,
LPSECURITY_ATTRIBUTES security_attributes,
DWORD creation_disposition,
DWORD flags_and_attributes, HANDLE template_file)
-/*[clinic end generated code: output=417ddcebfc5a3d53 input=6423c3e40372dbd5]*/
+/*[clinic end generated code: output=818c811e5e04d550 input=1fa870ed1c2e3d69]*/
{
HANDLE handle;
@@ -478,14 +479,15 @@ _winapi_CreateFile_impl(PyObject *module, LPCTSTR file_name,
}
Py_BEGIN_ALLOW_THREADS
- handle = CreateFile(file_name, desired_access,
- share_mode, security_attributes,
- creation_disposition,
- flags_and_attributes, template_file);
+ handle = CreateFileW(file_name, desired_access,
+ share_mode, security_attributes,
+ creation_disposition,
+ flags_and_attributes, template_file);
Py_END_ALLOW_THREADS
- if (handle == INVALID_HANDLE_VALUE)
+ if (handle == INVALID_HANDLE_VALUE) {
PyErr_SetFromWindowsErr(0);
+ }
return handle;
}
@@ -542,7 +544,12 @@ _winapi_CreateJunction_impl(PyObject *module, LPCWSTR src_path,
{
/* Privilege adjustment */
HANDLE token = NULL;
- TOKEN_PRIVILEGES tp;
+ struct {
+ TOKEN_PRIVILEGES base;
+ /* overallocate by a few array elements */
+ LUID_AND_ATTRIBUTES privs[4];
+ } tp, previousTp;
+ int previousTpSize = 0;
/* Reparse data buffer */
const USHORT prefix_len = 4;
@@ -566,17 +573,21 @@ _winapi_CreateJunction_impl(PyObject *module, LPCWSTR src_path,
/* Adjust privileges to allow rewriting directory entry as a
junction point. */
- if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token))
+ if (!OpenProcessToken(GetCurrentProcess(),
+ TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) {
goto cleanup;
+ }
- if (!LookupPrivilegeValue(NULL, SE_RESTORE_NAME, &tp.Privileges[0].Luid))
+ if (!LookupPrivilegeValue(NULL, SE_RESTORE_NAME, &tp.base.Privileges[0].Luid)) {
goto cleanup;
+ }
- tp.PrivilegeCount = 1;
- tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
- if (!AdjustTokenPrivileges(token, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),
- NULL, NULL))
+ tp.base.PrivilegeCount = 1;
+ tp.base.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+ if (!AdjustTokenPrivileges(token, FALSE, &tp.base, sizeof(previousTp),
+ &previousTp.base, &previousTpSize)) {
goto cleanup;
+ }
if (GetFileAttributesW(src_path) == INVALID_FILE_ATTRIBUTES)
goto cleanup;
@@ -657,8 +668,15 @@ _winapi_CreateJunction_impl(PyObject *module, LPCWSTR src_path,
cleanup:
ret = GetLastError();
- CloseHandle(token);
- CloseHandle(junction);
+ if (previousTpSize) {
+ AdjustTokenPrivileges(token, FALSE, &previousTp.base, previousTpSize,
+ NULL, NULL);
+ }
+
+ if (token != NULL)
+ CloseHandle(token);
+ if (junction != NULL)
+ CloseHandle(junction);
PyMem_RawFree(rdb);
if (ret != 0)
@@ -782,12 +800,162 @@ gethandle(PyObject* obj, const char* name)
return ret;
}
+static PyObject *
+sortenvironmentkey(PyObject *module, PyObject *item)
+{
+ PyObject *result = NULL;
+ PyObject *locale = PyUnicode_FromWideChar(LOCALE_NAME_INVARIANT, -1);
+ if (locale) {
+ result = _winapi_LCMapStringEx_impl(NULL, locale, LCMAP_UPPERCASE, item);
+ Py_DECREF(locale);
+ }
+ return result;
+}
+
+static PyMethodDef sortenvironmentkey_def = {
+ "sortenvironmentkey", _PyCFunction_CAST(sortenvironmentkey), METH_O, "",
+};
+
+static int
+sort_environment_keys(PyObject *keys)
+{
+ PyObject *keyfunc = PyCFunction_New(&sortenvironmentkey_def, NULL);
+ if (keyfunc == NULL) {
+ return -1;
+ }
+ PyObject *kwnames = Py_BuildValue("(s)", "key");
+ if (kwnames == NULL) {
+ Py_DECREF(keyfunc);
+ return -1;
+ }
+ PyObject *args[] = { keys, keyfunc };
+ PyObject *ret = PyObject_VectorcallMethod(&_Py_ID(sort), args, 1, kwnames);
+ Py_DECREF(keyfunc);
+ Py_DECREF(kwnames);
+ if (ret == NULL) {
+ return -1;
+ }
+ Py_DECREF(ret);
+
+ return 0;
+}
+
+static int
+compare_string_ordinal(PyObject *str1, PyObject *str2, int *result)
+{
+ wchar_t *s1 = PyUnicode_AsWideCharString(str1, NULL);
+ if (s1 == NULL) {
+ return -1;
+ }
+ wchar_t *s2 = PyUnicode_AsWideCharString(str2, NULL);
+ if (s2 == NULL) {
+ PyMem_Free(s1);
+ return -1;
+ }
+ *result = CompareStringOrdinal(s1, -1, s2, -1, TRUE);
+ PyMem_Free(s1);
+ PyMem_Free(s2);
+ return 0;
+}
+
+static PyObject *
+dedup_environment_keys(PyObject *keys)
+{
+ PyObject *result = PyList_New(0);
+ if (result == NULL) {
+ return NULL;
+ }
+
+ // Iterate over the pre-ordered keys, check whether the current key is equal
+ // to the next key (ignoring case), if different, insert the current value
+ // into the result list. If they are equal, do nothing because we always
+ // want to keep the last inserted one.
+ for (Py_ssize_t i = 0; i < PyList_GET_SIZE(keys); i++) {
+ PyObject *key = PyList_GET_ITEM(keys, i);
+
+ // The last key will always be kept.
+ if (i + 1 == PyList_GET_SIZE(keys)) {
+ if (PyList_Append(result, key) < 0) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ continue;
+ }
+
+ PyObject *next_key = PyList_GET_ITEM(keys, i + 1);
+ int compare_result;
+ if (compare_string_ordinal(key, next_key, &compare_result) < 0) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ if (compare_result == CSTR_EQUAL) {
+ continue;
+ }
+ if (PyList_Append(result, key) < 0) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ }
+
+ return result;
+}
+
+static PyObject *
+normalize_environment(PyObject *environment)
+{
+ PyObject *keys = PyMapping_Keys(environment);
+ if (keys == NULL) {
+ return NULL;
+ }
+
+ if (sort_environment_keys(keys) < 0) {
+ Py_DECREF(keys);
+ return NULL;
+ }
+
+ PyObject *normalized_keys = dedup_environment_keys(keys);
+ Py_DECREF(keys);
+ if (normalized_keys == NULL) {
+ return NULL;
+ }
+
+ PyObject *result = PyDict_New();
+ if (result == NULL) {
+ Py_DECREF(normalized_keys);
+ return NULL;
+ }
+
+ for (int i = 0; i < PyList_GET_SIZE(normalized_keys); i++) {
+ PyObject *key = PyList_GET_ITEM(normalized_keys, i);
+ PyObject *value = PyObject_GetItem(environment, key);
+ if (value == NULL) {
+ Py_DECREF(normalized_keys);
+ Py_DECREF(result);
+ return NULL;
+ }
+
+ int ret = PyObject_SetItem(result, key, value);
+ Py_DECREF(value);
+ if (ret < 0) {
+ Py_DECREF(normalized_keys);
+ Py_DECREF(result);
+ return NULL;
+ }
+ }
+
+ Py_DECREF(normalized_keys);
+
+ return result;
+}
+
static wchar_t *
getenvironment(PyObject* environment)
{
Py_ssize_t i, envsize, totalsize;
wchar_t *buffer = NULL, *p, *end;
- PyObject *keys, *values;
+ PyObject *normalized_environment = NULL;
+ PyObject *keys = NULL;
+ PyObject *values = NULL;
/* convert environment dictionary to windows environment string */
if (! PyMapping_Check(environment)) {
@@ -796,11 +964,16 @@ getenvironment(PyObject* environment)
return NULL;
}
- keys = PyMapping_Keys(environment);
- if (!keys) {
+ normalized_environment = normalize_environment(environment);
+ if (normalize_environment == NULL) {
return NULL;
}
- values = PyMapping_Values(environment);
+
+ keys = PyMapping_Keys(normalized_environment);
+ if (!keys) {
+ goto error;
+ }
+ values = PyMapping_Values(normalized_environment);
if (!values) {
goto error;
}
@@ -892,6 +1065,7 @@ getenvironment(PyObject* environment)
cleanup:
error:
+ Py_XDECREF(normalized_environment);
Py_XDECREF(keys);
Py_XDECREF(values);
return buffer;