diff --git a/Include/cpython/unicodeobject.h b/Include/cpython/unicodeobject.h index c1a8564349b995..4cab116e8f805c 100644 --- a/Include/cpython/unicodeobject.h +++ b/Include/cpython/unicodeobject.h @@ -11,6 +11,8 @@ /* --- Internal Unicode Operations ---------------------------------------- */ +#define USE_UNICODE_WCHAR_CACHE 1 + /* Since splitting on whitespace is an important use case, and whitespace in most situations is solely ASCII whitespace, we optimize for the common case by using a quick look-up table @@ -1177,4 +1179,7 @@ PyAPI_FUNC(PyObject*) _PyUnicode_FromId(_Py_Identifier*); and where the hash values are equal (i.e. a very probable match) */ PyAPI_FUNC(int) _PyUnicode_EQ(PyObject *, PyObject *); +PyAPI_FUNC(int) _PyUnicode_WideCharString_Converter(PyObject *, void *); +PyAPI_FUNC(int) _PyUnicode_WideCharString_Opt_Converter(PyObject *, void *); + PyAPI_FUNC(Py_ssize_t) _PyUnicode_ScanIdentifier(PyObject *); diff --git a/Lib/test/clinic.test b/Lib/test/clinic.test index f2be61355cc978..07e13829d5db97 100644 --- a/Lib/test/clinic.test +++ b/Lib/test/clinic.test @@ -1813,13 +1813,26 @@ test_Py_UNICODE_converter(PyObject *module, PyObject *const *args, Py_ssize_t na const Py_UNICODE *e; Py_ssize_clean_t e_length; - if (!_PyArg_ParseStack(args, nargs, "uuZu#Z#:test_Py_UNICODE_converter", - &a, &b, &c, &d, &d_length, &e, &e_length)) { + if (!_PyArg_ParseStack(args, nargs, "O&O&O&u#Z#:test_Py_UNICODE_converter", + _PyUnicode_WideCharString_Converter, &a, _PyUnicode_WideCharString_Converter, &b, _PyUnicode_WideCharString_Opt_Converter, &c, &d, &d_length, &e, &e_length)) { goto exit; } return_value = test_Py_UNICODE_converter_impl(module, a, b, c, d, d_length, e, e_length); exit: + /* Cleanup for a */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)a); + #endif /* USE_UNICODE_WCHAR_CACHE */ + /* Cleanup for b */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)b); + #endif /* USE_UNICODE_WCHAR_CACHE */ + /* Cleanup for c */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)c); + #endif /* USE_UNICODE_WCHAR_CACHE */ + return return_value; } @@ -1830,7 +1843,7 @@ test_Py_UNICODE_converter_impl(PyObject *module, const Py_UNICODE *a, Py_ssize_clean_t d_length, const Py_UNICODE *e, Py_ssize_clean_t e_length) -/*[clinic end generated code: output=dd0a09a1b772e57b input=064a3b68ad7f04b0]*/ +/*[clinic end generated code: output=ef45e982fedf0b3d input=064a3b68ad7f04b0]*/ /*[clinic input] diff --git a/Modules/clinic/_winapi.c.h b/Modules/clinic/_winapi.c.h index e21f2bc2b6fd6f..6022dfe0db4b28 100644 --- a/Modules/clinic/_winapi.c.h +++ b/Modules/clinic/_winapi.c.h @@ -367,13 +367,22 @@ _winapi_CreateProcess(PyObject *module, PyObject *const *args, Py_ssize_t nargs) const Py_UNICODE *current_directory; PyObject *startup_info; - if (!_PyArg_ParseStack(args, nargs, "ZOOOikOZO:CreateProcess", - &application_name, &command_line, &proc_attrs, &thread_attrs, &inherit_handles, &creation_flags, &env_mapping, ¤t_directory, &startup_info)) { + if (!_PyArg_ParseStack(args, nargs, "O&OOOikOO&O:CreateProcess", + _PyUnicode_WideCharString_Opt_Converter, &application_name, &command_line, &proc_attrs, &thread_attrs, &inherit_handles, &creation_flags, &env_mapping, _PyUnicode_WideCharString_Opt_Converter, ¤t_directory, &startup_info)) { goto exit; } return_value = _winapi_CreateProcess_impl(module, application_name, command_line, proc_attrs, thread_attrs, inherit_handles, creation_flags, env_mapping, current_directory, startup_info); exit: + /* Cleanup for application_name */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)application_name); + #endif /* USE_UNICODE_WCHAR_CACHE */ + /* Cleanup for current_directory */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)current_directory); + #endif /* USE_UNICODE_WCHAR_CACHE */ + return return_value; } @@ -1097,4 +1106,4 @@ _winapi_GetFileType(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P exit: return return_value; } -/*[clinic end generated code: output=f3897898ea1da99d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=db87076a32fa7abe input=a9049054013a1b77]*/ diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index b691cfbc6edef3..6533edfdb47d23 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -1674,12 +1674,28 @@ os_system(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k { PyObject *return_value = NULL; static const char * const _keywords[] = {"command", NULL}; - static _PyArg_Parser _parser = {"u:system", _keywords, 0}; + static _PyArg_Parser _parser = {NULL, _keywords, "system", 0}; + PyObject *argsbuf[1]; const Py_UNICODE *command; long _return_value; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &command)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("system", "argument 'command'", "str", args[0]); + goto exit; + } + #if USE_UNICODE_WCHAR_CACHE + _Py_COMP_DIAG_PUSH + _Py_COMP_DIAG_IGNORE_DEPR_DECLS + command = _PyUnicode_AsUnicode(args[0]); + _Py_COMP_DIAG_POP + #else /* USE_UNICODE_WCHAR_CACHE */ + command = PyUnicode_AsWideCharString(args[0], NULL); + #endif /* USE_UNICODE_WCHAR_CACHE */ + if (command == NULL) { goto exit; } _return_value = os_system_impl(module, command); @@ -1689,6 +1705,11 @@ os_system(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k return_value = PyLong_FromLong(_return_value); exit: + /* Cleanup for command */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)command); + #endif /* USE_UNICODE_WCHAR_CACHE */ + return return_value; } @@ -6998,19 +7019,47 @@ os_startfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject { PyObject *return_value = NULL; static const char * const _keywords[] = {"filepath", "operation", NULL}; - static _PyArg_Parser _parser = {"O&|u:startfile", _keywords, 0}; + static _PyArg_Parser _parser = {NULL, _keywords, "startfile", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t filepath = PATH_T_INITIALIZE("startfile", "filepath", 0, 0); const Py_UNICODE *operation = NULL; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - path_converter, &filepath, &operation)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!path_converter(args[0], &filepath)) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("startfile", "argument 'operation'", "str", args[1]); goto exit; } + #if USE_UNICODE_WCHAR_CACHE + _Py_COMP_DIAG_PUSH + _Py_COMP_DIAG_IGNORE_DEPR_DECLS + operation = _PyUnicode_AsUnicode(args[1]); + _Py_COMP_DIAG_POP + #else /* USE_UNICODE_WCHAR_CACHE */ + operation = PyUnicode_AsWideCharString(args[1], NULL); + #endif /* USE_UNICODE_WCHAR_CACHE */ + if (operation == NULL) { + goto exit; + } +skip_optional_pos: return_value = os_startfile_impl(module, &filepath, operation); exit: /* Cleanup for filepath */ path_cleanup(&filepath); + /* Cleanup for operation */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)operation); + #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -8876,4 +8925,4 @@ os_waitstatus_to_exitcode(PyObject *module, PyObject *const *args, Py_ssize_t na #ifndef OS_WAITSTATUS_TO_EXITCODE_METHODDEF #define OS_WAITSTATUS_TO_EXITCODE_METHODDEF #endif /* !defined(OS_WAITSTATUS_TO_EXITCODE_METHODDEF) */ -/*[clinic end generated code: output=d7c1212a94613496 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ba3d4b35fda2c208 input=a9049054013a1b77]*/ diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index c46ba4ae57dc6b..1cf219e8875669 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -3273,6 +3273,80 @@ PyUnicode_AsWideCharString(PyObject *unicode, #endif /* HAVE_WCHAR_H */ +int +_PyUnicode_WideCharString_Converter(PyObject *obj, void *ptr) +{ + wchar_t **p = (wchar_t **)ptr; + if (obj == NULL) { +#if !USE_UNICODE_WCHAR_CACHE + PyMem_Free(*p); +#endif /* USE_UNICODE_WCHAR_CACHE */ + *p = NULL; + return 1; + } + if (PyUnicode_Check(obj)) { +#if USE_UNICODE_WCHAR_CACHE +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS + *p = (wchar_t *)_PyUnicode_AsUnicode(obj); + if (*p == NULL) { + return 0; + } + return 1; +_Py_COMP_DIAG_POP +#else /* USE_UNICODE_WCHAR_CACHE */ + *p = PyUnicode_AsWideCharString(obj, NULL); + if (*p == NULL) { + return 0; + } + return Py_CLEANUP_SUPPORTED; +#endif /* USE_UNICODE_WCHAR_CACHE */ + } + PyErr_Format(PyExc_TypeError, + "argument must be str, not %.50s", + obj->ob_type->tp_name); + return 0; +} + +int +_PyUnicode_WideCharString_Opt_Converter(PyObject *obj, void *ptr) +{ + wchar_t **p = (wchar_t **)ptr; + if (obj == NULL) { +#if !USE_UNICODE_WCHAR_CACHE + PyMem_Free(*p); +#endif /* USE_UNICODE_WCHAR_CACHE */ + *p = NULL; + return 1; + } + if (obj == Py_None) { + *p = NULL; + return 1; + } + if (PyUnicode_Check(obj)) { +#if USE_UNICODE_WCHAR_CACHE +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS + *p = (wchar_t *)_PyUnicode_AsUnicode(obj); + if (*p == NULL) { + return 0; + } + return 1; +_Py_COMP_DIAG_POP +#else /* USE_UNICODE_WCHAR_CACHE */ + *p = PyUnicode_AsWideCharString(obj, NULL); + if (*p == NULL) { + return 0; + } + return Py_CLEANUP_SUPPORTED; +#endif /* USE_UNICODE_WCHAR_CACHE */ + } + PyErr_Format(PyExc_TypeError, + "argument must be str or None, not %.50s", + obj->ob_type->tp_name); + return 0; +} + PyObject * PyUnicode_FromOrdinal(int ordinal) { diff --git a/PC/clinic/winreg.c.h b/PC/clinic/winreg.c.h index 5f37fcda0a9ab8..5c97eaeee9e273 100644 --- a/PC/clinic/winreg.c.h +++ b/PC/clinic/winreg.c.h @@ -152,8 +152,30 @@ winreg_ConnectRegistry(PyObject *module, PyObject *const *args, Py_ssize_t nargs HKEY key; HKEY _return_value; - if (!_PyArg_ParseStack(args, nargs, "ZO&:ConnectRegistry", - &computer_name, clinic_HKEY_converter, &key)) { + if (!_PyArg_CheckPositional("ConnectRegistry", nargs, 2, 2)) { + goto exit; + } + if (args[0] == Py_None) { + computer_name = NULL; + } + else if (PyUnicode_Check(args[0])) { + #if USE_UNICODE_WCHAR_CACHE + _Py_COMP_DIAG_PUSH + _Py_COMP_DIAG_IGNORE_DEPR_DECLS + computer_name = _PyUnicode_AsUnicode(args[0]); + _Py_COMP_DIAG_POP + #else /* USE_UNICODE_WCHAR_CACHE */ + computer_name = PyUnicode_AsWideCharString(args[0], NULL); + #endif /* USE_UNICODE_WCHAR_CACHE */ + if (computer_name == NULL) { + goto exit; + } + } + else { + _PyArg_BadArgument("ConnectRegistry", "argument 1", "str or None", args[0]); + goto exit; + } + if (!clinic_HKEY_converter(args[1], &key)) { goto exit; } _return_value = winreg_ConnectRegistry_impl(module, computer_name, key); @@ -163,6 +185,11 @@ winreg_ConnectRegistry(PyObject *module, PyObject *const *args, Py_ssize_t nargs return_value = PyHKEY_FromHKEY(_return_value); exit: + /* Cleanup for computer_name */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)computer_name); + #endif /* USE_UNICODE_WCHAR_CACHE */ + return return_value; } @@ -199,8 +226,30 @@ winreg_CreateKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) const Py_UNICODE *sub_key; HKEY _return_value; - if (!_PyArg_ParseStack(args, nargs, "O&Z:CreateKey", - clinic_HKEY_converter, &key, &sub_key)) { + if (!_PyArg_CheckPositional("CreateKey", nargs, 2, 2)) { + goto exit; + } + if (!clinic_HKEY_converter(args[0], &key)) { + goto exit; + } + if (args[1] == Py_None) { + sub_key = NULL; + } + else if (PyUnicode_Check(args[1])) { + #if USE_UNICODE_WCHAR_CACHE + _Py_COMP_DIAG_PUSH + _Py_COMP_DIAG_IGNORE_DEPR_DECLS + sub_key = _PyUnicode_AsUnicode(args[1]); + _Py_COMP_DIAG_POP + #else /* USE_UNICODE_WCHAR_CACHE */ + sub_key = PyUnicode_AsWideCharString(args[1], NULL); + #endif /* USE_UNICODE_WCHAR_CACHE */ + if (sub_key == NULL) { + goto exit; + } + } + else { + _PyArg_BadArgument("CreateKey", "argument 2", "str or None", args[1]); goto exit; } _return_value = winreg_CreateKey_impl(module, key, sub_key); @@ -210,6 +259,11 @@ winreg_CreateKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) return_value = PyHKEY_FromHKEY(_return_value); exit: + /* Cleanup for sub_key */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)sub_key); + #endif /* USE_UNICODE_WCHAR_CACHE */ + return return_value; } @@ -251,7 +305,7 @@ winreg_CreateKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py { PyObject *return_value = NULL; static const char * const _keywords[] = {"key", "sub_key", "reserved", "access", NULL}; - static _PyArg_Parser _parser = {"O&Z|ii:CreateKeyEx", _keywords, 0}; + static _PyArg_Parser _parser = {"O&O&|ii:CreateKeyEx", _keywords, 0}; HKEY key; const Py_UNICODE *sub_key; int reserved = 0; @@ -259,7 +313,7 @@ winreg_CreateKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py HKEY _return_value; if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - clinic_HKEY_converter, &key, &sub_key, &reserved, &access)) { + clinic_HKEY_converter, &key, _PyUnicode_WideCharString_Opt_Converter, &sub_key, &reserved, &access)) { goto exit; } _return_value = winreg_CreateKeyEx_impl(module, key, sub_key, reserved, access); @@ -269,6 +323,11 @@ winreg_CreateKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py return_value = PyHKEY_FromHKEY(_return_value); exit: + /* Cleanup for sub_key */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)sub_key); + #endif /* USE_UNICODE_WCHAR_CACHE */ + return return_value; } @@ -303,13 +362,35 @@ winreg_DeleteKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) HKEY key; const Py_UNICODE *sub_key; - if (!_PyArg_ParseStack(args, nargs, "O&u:DeleteKey", - clinic_HKEY_converter, &key, &sub_key)) { + if (!_PyArg_CheckPositional("DeleteKey", nargs, 2, 2)) { + goto exit; + } + if (!clinic_HKEY_converter(args[0], &key)) { + goto exit; + } + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("DeleteKey", "argument 2", "str", args[1]); + goto exit; + } + #if USE_UNICODE_WCHAR_CACHE + _Py_COMP_DIAG_PUSH + _Py_COMP_DIAG_IGNORE_DEPR_DECLS + sub_key = _PyUnicode_AsUnicode(args[1]); + _Py_COMP_DIAG_POP + #else /* USE_UNICODE_WCHAR_CACHE */ + sub_key = PyUnicode_AsWideCharString(args[1], NULL); + #endif /* USE_UNICODE_WCHAR_CACHE */ + if (sub_key == NULL) { goto exit; } return_value = winreg_DeleteKey_impl(module, key, sub_key); exit: + /* Cleanup for sub_key */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)sub_key); + #endif /* USE_UNICODE_WCHAR_CACHE */ + return return_value; } @@ -351,19 +432,24 @@ winreg_DeleteKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py { PyObject *return_value = NULL; static const char * const _keywords[] = {"key", "sub_key", "access", "reserved", NULL}; - static _PyArg_Parser _parser = {"O&u|ii:DeleteKeyEx", _keywords, 0}; + static _PyArg_Parser _parser = {"O&O&|ii:DeleteKeyEx", _keywords, 0}; HKEY key; const Py_UNICODE *sub_key; REGSAM access = KEY_WOW64_64KEY; int reserved = 0; if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - clinic_HKEY_converter, &key, &sub_key, &access, &reserved)) { + clinic_HKEY_converter, &key, _PyUnicode_WideCharString_Converter, &sub_key, &access, &reserved)) { goto exit; } return_value = winreg_DeleteKeyEx_impl(module, key, sub_key, access, reserved); exit: + /* Cleanup for sub_key */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)sub_key); + #endif /* USE_UNICODE_WCHAR_CACHE */ + return return_value; } @@ -391,13 +477,40 @@ winreg_DeleteValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) HKEY key; const Py_UNICODE *value; - if (!_PyArg_ParseStack(args, nargs, "O&Z:DeleteValue", - clinic_HKEY_converter, &key, &value)) { + if (!_PyArg_CheckPositional("DeleteValue", nargs, 2, 2)) { + goto exit; + } + if (!clinic_HKEY_converter(args[0], &key)) { + goto exit; + } + if (args[1] == Py_None) { + value = NULL; + } + else if (PyUnicode_Check(args[1])) { + #if USE_UNICODE_WCHAR_CACHE + _Py_COMP_DIAG_PUSH + _Py_COMP_DIAG_IGNORE_DEPR_DECLS + value = _PyUnicode_AsUnicode(args[1]); + _Py_COMP_DIAG_POP + #else /* USE_UNICODE_WCHAR_CACHE */ + value = PyUnicode_AsWideCharString(args[1], NULL); + #endif /* USE_UNICODE_WCHAR_CACHE */ + if (value == NULL) { + goto exit; + } + } + else { + _PyArg_BadArgument("DeleteValue", "argument 2", "str or None", args[1]); goto exit; } return_value = winreg_DeleteValue_impl(module, key, value); exit: + /* Cleanup for value */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)value); + #endif /* USE_UNICODE_WCHAR_CACHE */ + return return_value; } @@ -517,12 +630,29 @@ winreg_ExpandEnvironmentStrings(PyObject *module, PyObject *arg) PyObject *return_value = NULL; const Py_UNICODE *string; - if (!PyArg_Parse(arg, "u:ExpandEnvironmentStrings", &string)) { + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("ExpandEnvironmentStrings", "argument", "str", arg); + goto exit; + } + #if USE_UNICODE_WCHAR_CACHE + _Py_COMP_DIAG_PUSH + _Py_COMP_DIAG_IGNORE_DEPR_DECLS + string = _PyUnicode_AsUnicode(arg); + _Py_COMP_DIAG_POP + #else /* USE_UNICODE_WCHAR_CACHE */ + string = PyUnicode_AsWideCharString(arg, NULL); + #endif /* USE_UNICODE_WCHAR_CACHE */ + if (string == NULL) { goto exit; } return_value = winreg_ExpandEnvironmentStrings_impl(module, string); exit: + /* Cleanup for string */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)string); + #endif /* USE_UNICODE_WCHAR_CACHE */ + return return_value; } @@ -609,13 +739,54 @@ winreg_LoadKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) const Py_UNICODE *sub_key; const Py_UNICODE *file_name; - if (!_PyArg_ParseStack(args, nargs, "O&uu:LoadKey", - clinic_HKEY_converter, &key, &sub_key, &file_name)) { + if (!_PyArg_CheckPositional("LoadKey", nargs, 3, 3)) { + goto exit; + } + if (!clinic_HKEY_converter(args[0], &key)) { + goto exit; + } + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("LoadKey", "argument 2", "str", args[1]); + goto exit; + } + #if USE_UNICODE_WCHAR_CACHE + _Py_COMP_DIAG_PUSH + _Py_COMP_DIAG_IGNORE_DEPR_DECLS + sub_key = _PyUnicode_AsUnicode(args[1]); + _Py_COMP_DIAG_POP + #else /* USE_UNICODE_WCHAR_CACHE */ + sub_key = PyUnicode_AsWideCharString(args[1], NULL); + #endif /* USE_UNICODE_WCHAR_CACHE */ + if (sub_key == NULL) { + goto exit; + } + if (!PyUnicode_Check(args[2])) { + _PyArg_BadArgument("LoadKey", "argument 3", "str", args[2]); + goto exit; + } + #if USE_UNICODE_WCHAR_CACHE + _Py_COMP_DIAG_PUSH + _Py_COMP_DIAG_IGNORE_DEPR_DECLS + file_name = _PyUnicode_AsUnicode(args[2]); + _Py_COMP_DIAG_POP + #else /* USE_UNICODE_WCHAR_CACHE */ + file_name = PyUnicode_AsWideCharString(args[2], NULL); + #endif /* USE_UNICODE_WCHAR_CACHE */ + if (file_name == NULL) { goto exit; } return_value = winreg_LoadKey_impl(module, key, sub_key, file_name); exit: + /* Cleanup for sub_key */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)sub_key); + #endif /* USE_UNICODE_WCHAR_CACHE */ + /* Cleanup for file_name */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)file_name); + #endif /* USE_UNICODE_WCHAR_CACHE */ + return return_value; } @@ -650,7 +821,7 @@ winreg_OpenKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje { PyObject *return_value = NULL; static const char * const _keywords[] = {"key", "sub_key", "reserved", "access", NULL}; - static _PyArg_Parser _parser = {"O&Z|ii:OpenKey", _keywords, 0}; + static _PyArg_Parser _parser = {"O&O&|ii:OpenKey", _keywords, 0}; HKEY key; const Py_UNICODE *sub_key; int reserved = 0; @@ -658,7 +829,7 @@ winreg_OpenKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje HKEY _return_value; if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - clinic_HKEY_converter, &key, &sub_key, &reserved, &access)) { + clinic_HKEY_converter, &key, _PyUnicode_WideCharString_Opt_Converter, &sub_key, &reserved, &access)) { goto exit; } _return_value = winreg_OpenKey_impl(module, key, sub_key, reserved, access); @@ -668,6 +839,11 @@ winreg_OpenKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje return_value = PyHKEY_FromHKEY(_return_value); exit: + /* Cleanup for sub_key */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)sub_key); + #endif /* USE_UNICODE_WCHAR_CACHE */ + return return_value; } @@ -702,7 +878,7 @@ winreg_OpenKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb { PyObject *return_value = NULL; static const char * const _keywords[] = {"key", "sub_key", "reserved", "access", NULL}; - static _PyArg_Parser _parser = {"O&Z|ii:OpenKeyEx", _keywords, 0}; + static _PyArg_Parser _parser = {"O&O&|ii:OpenKeyEx", _keywords, 0}; HKEY key; const Py_UNICODE *sub_key; int reserved = 0; @@ -710,7 +886,7 @@ winreg_OpenKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb HKEY _return_value; if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - clinic_HKEY_converter, &key, &sub_key, &reserved, &access)) { + clinic_HKEY_converter, &key, _PyUnicode_WideCharString_Opt_Converter, &sub_key, &reserved, &access)) { goto exit; } _return_value = winreg_OpenKeyEx_impl(module, key, sub_key, reserved, access); @@ -720,6 +896,11 @@ winreg_OpenKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb return_value = PyHKEY_FromHKEY(_return_value); exit: + /* Cleanup for sub_key */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)sub_key); + #endif /* USE_UNICODE_WCHAR_CACHE */ + return return_value; } @@ -792,13 +973,40 @@ winreg_QueryValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) HKEY key; const Py_UNICODE *sub_key; - if (!_PyArg_ParseStack(args, nargs, "O&Z:QueryValue", - clinic_HKEY_converter, &key, &sub_key)) { + if (!_PyArg_CheckPositional("QueryValue", nargs, 2, 2)) { + goto exit; + } + if (!clinic_HKEY_converter(args[0], &key)) { + goto exit; + } + if (args[1] == Py_None) { + sub_key = NULL; + } + else if (PyUnicode_Check(args[1])) { + #if USE_UNICODE_WCHAR_CACHE + _Py_COMP_DIAG_PUSH + _Py_COMP_DIAG_IGNORE_DEPR_DECLS + sub_key = _PyUnicode_AsUnicode(args[1]); + _Py_COMP_DIAG_POP + #else /* USE_UNICODE_WCHAR_CACHE */ + sub_key = PyUnicode_AsWideCharString(args[1], NULL); + #endif /* USE_UNICODE_WCHAR_CACHE */ + if (sub_key == NULL) { + goto exit; + } + } + else { + _PyArg_BadArgument("QueryValue", "argument 2", "str or None", args[1]); goto exit; } return_value = winreg_QueryValue_impl(module, key, sub_key); exit: + /* Cleanup for sub_key */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)sub_key); + #endif /* USE_UNICODE_WCHAR_CACHE */ + return return_value; } @@ -831,13 +1039,40 @@ winreg_QueryValueEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs) HKEY key; const Py_UNICODE *name; - if (!_PyArg_ParseStack(args, nargs, "O&Z:QueryValueEx", - clinic_HKEY_converter, &key, &name)) { + if (!_PyArg_CheckPositional("QueryValueEx", nargs, 2, 2)) { + goto exit; + } + if (!clinic_HKEY_converter(args[0], &key)) { + goto exit; + } + if (args[1] == Py_None) { + name = NULL; + } + else if (PyUnicode_Check(args[1])) { + #if USE_UNICODE_WCHAR_CACHE + _Py_COMP_DIAG_PUSH + _Py_COMP_DIAG_IGNORE_DEPR_DECLS + name = _PyUnicode_AsUnicode(args[1]); + _Py_COMP_DIAG_POP + #else /* USE_UNICODE_WCHAR_CACHE */ + name = PyUnicode_AsWideCharString(args[1], NULL); + #endif /* USE_UNICODE_WCHAR_CACHE */ + if (name == NULL) { + goto exit; + } + } + else { + _PyArg_BadArgument("QueryValueEx", "argument 2", "str or None", args[1]); goto exit; } return_value = winreg_QueryValueEx_impl(module, key, name); exit: + /* Cleanup for name */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)name); + #endif /* USE_UNICODE_WCHAR_CACHE */ + return return_value; } @@ -875,13 +1110,35 @@ winreg_SaveKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) HKEY key; const Py_UNICODE *file_name; - if (!_PyArg_ParseStack(args, nargs, "O&u:SaveKey", - clinic_HKEY_converter, &key, &file_name)) { + if (!_PyArg_CheckPositional("SaveKey", nargs, 2, 2)) { + goto exit; + } + if (!clinic_HKEY_converter(args[0], &key)) { + goto exit; + } + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("SaveKey", "argument 2", "str", args[1]); + goto exit; + } + #if USE_UNICODE_WCHAR_CACHE + _Py_COMP_DIAG_PUSH + _Py_COMP_DIAG_IGNORE_DEPR_DECLS + file_name = _PyUnicode_AsUnicode(args[1]); + _Py_COMP_DIAG_POP + #else /* USE_UNICODE_WCHAR_CACHE */ + file_name = PyUnicode_AsWideCharString(args[1], NULL); + #endif /* USE_UNICODE_WCHAR_CACHE */ + if (file_name == NULL) { goto exit; } return_value = winreg_SaveKey_impl(module, key, file_name); exit: + /* Cleanup for file_name */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)file_name); + #endif /* USE_UNICODE_WCHAR_CACHE */ + return return_value; } @@ -929,13 +1186,18 @@ winreg_SetValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) const Py_UNICODE *value; Py_ssize_clean_t value_length; - if (!_PyArg_ParseStack(args, nargs, "O&Zku#:SetValue", - clinic_HKEY_converter, &key, &sub_key, &type, &value, &value_length)) { + if (!_PyArg_ParseStack(args, nargs, "O&O&ku#:SetValue", + clinic_HKEY_converter, &key, _PyUnicode_WideCharString_Opt_Converter, &sub_key, &type, &value, &value_length)) { goto exit; } return_value = winreg_SetValue_impl(module, key, sub_key, type, value, value_length); exit: + /* Cleanup for sub_key */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)sub_key); + #endif /* USE_UNICODE_WCHAR_CACHE */ + return return_value; } @@ -1000,13 +1262,18 @@ winreg_SetValueEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs) DWORD type; PyObject *value; - if (!_PyArg_ParseStack(args, nargs, "O&ZOkO:SetValueEx", - clinic_HKEY_converter, &key, &value_name, &reserved, &type, &value)) { + if (!_PyArg_ParseStack(args, nargs, "O&O&OkO:SetValueEx", + clinic_HKEY_converter, &key, _PyUnicode_WideCharString_Opt_Converter, &value_name, &reserved, &type, &value)) { goto exit; } return_value = winreg_SetValueEx_impl(module, key, value_name, reserved, type, value); exit: + /* Cleanup for value_name */ + #if !USE_UNICODE_WCHAR_CACHE + PyMem_Free((void *)value_name); + #endif /* USE_UNICODE_WCHAR_CACHE */ + return return_value; } @@ -1111,4 +1378,4 @@ winreg_QueryReflectionKey(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=f4f996d40d06f14c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=fa5f21ea6a75d0e9 input=a9049054013a1b77]*/ diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index b1bf7826ebf9fe..3a9f4c228c22b9 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -3374,20 +3374,81 @@ def parse_arg(self, argname, displayname): displayname=displayname) return super().parse_arg(argname, displayname) +@add_legacy_c_converter('u') @add_legacy_c_converter('u#', zeroes=True) @add_legacy_c_converter('Z', accept={str, NoneType}) @add_legacy_c_converter('Z#', accept={str, NoneType}, zeroes=True) class Py_UNICODE_converter(CConverter): type = 'const Py_UNICODE *' default_type = (str, Null, NoneType) - format_unit = 'u' def converter_init(self, *, accept={str}, zeroes=False): format_unit = 'Z' if accept=={str, NoneType} else 'u' if zeroes: format_unit += '#' self.length = True - self.format_unit = format_unit + self.format_unit = format_unit + else: + self.accept = accept + if accept == {str}: + self.converter = '_PyUnicode_WideCharString_Converter' + elif accept == {str, NoneType}: + self.converter = '_PyUnicode_WideCharString_Opt_Converter' + else: + fail("Py_UNICODE_converter: illegal 'accept' argument " + repr(accept)) + + def cleanup(self): + if not self.length: + return """\ +#if !USE_UNICODE_WCHAR_CACHE +PyMem_Free((void *){name}); +#endif /* USE_UNICODE_WCHAR_CACHE */ +""".format(name=self.name) + + def parse_arg(self, argname, argnum): + if not self.length: + if self.accept == {str}: + return """ + if (!PyUnicode_Check({argname})) {{{{ + _PyArg_BadArgument("{{name}}", {argnum}, "str", {argname}); + goto exit; + }}}} + #if USE_UNICODE_WCHAR_CACHE + _Py_COMP_DIAG_PUSH + _Py_COMP_DIAG_IGNORE_DEPR_DECLS + {paramname} = _PyUnicode_AsUnicode({argname}); + _Py_COMP_DIAG_POP + #else /* USE_UNICODE_WCHAR_CACHE */ + {paramname} = PyUnicode_AsWideCharString({argname}, NULL); + #endif /* USE_UNICODE_WCHAR_CACHE */ + if ({paramname} == NULL) {{{{ + goto exit; + }}}} + """.format(argname=argname, paramname=self.name, argnum=argnum) + elif self.accept == {str, NoneType}: + return """ + if ({argname} == Py_None) {{{{ + {paramname} = NULL; + }}}} + else if (PyUnicode_Check({argname})) {{{{ + #if USE_UNICODE_WCHAR_CACHE + _Py_COMP_DIAG_PUSH + _Py_COMP_DIAG_IGNORE_DEPR_DECLS + {paramname} = _PyUnicode_AsUnicode({argname}); + _Py_COMP_DIAG_POP + #else /* USE_UNICODE_WCHAR_CACHE */ + {paramname} = PyUnicode_AsWideCharString({argname}, NULL); + #endif /* USE_UNICODE_WCHAR_CACHE */ + if ({paramname} == NULL) {{{{ + goto exit; + }}}} + }}}} + else {{{{ + _PyArg_BadArgument("{{name}}", {argnum}, "str or None", {argname}); + goto exit; + }}}} + """.format(argname=argname, paramname=self.name, argnum=argnum) + return super().parse_arg(argname, argnum) @add_legacy_c_converter('s*', accept={str, buffer}) @add_legacy_c_converter('z*', accept={str, buffer, NoneType}) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy