diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index a932be43413b1e1..8ce41e130864903 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -932,8 +932,9 @@ Build Changes * Building CPython now requires a compiler with support for the C11 atomic library, GCC built-in atomic functions, or MSVC interlocked intrinsics. -* The ``errno``, ``_ctypes_test``, ``_stat`` and ``_testimportmultiple`` C - extensions are now built with the :ref:`limited C API `. +* The ``errno``, ``md5``, ``_ctypes_test``, ``_stat`` and + ``_testimportmultiple`` C extensions are now built with the :ref:`limited C + API `. (Contributed by Victor Stinner in :gh:`85283`.) diff --git a/Misc/NEWS.d/next/Build/2023-10-17-01-56-11.gh-issue-85283.V156T2.rst b/Misc/NEWS.d/next/Build/2023-10-17-01-56-11.gh-issue-85283.V156T2.rst index db4849650fd8499..4240db7c3b9f6c3 100644 --- a/Misc/NEWS.d/next/Build/2023-10-17-01-56-11.gh-issue-85283.V156T2.rst +++ b/Misc/NEWS.d/next/Build/2023-10-17-01-56-11.gh-issue-85283.V156T2.rst @@ -1,3 +1,3 @@ -The ``errno``, ``_ctypes_test`` and ``_testimportmultiple`` C extensions are -now built with the :ref:`limited C API `. Patch by Victor -Stinner. +The ``errno``, ``md5``, ``_ctypes_test`` and ``_testimportmultiple`` C +extensions are now built with the :ref:`limited C API `. Patch +by Victor Stinner. diff --git a/Modules/clinic/md5module.c.h b/Modules/clinic/md5module.c.h index 6087a0f9c25c1a5..11db7952c5ce6ab 100644 --- a/Modules/clinic/md5module.c.h +++ b/Modules/clinic/md5module.c.h @@ -2,11 +2,6 @@ preserve [clinic start generated code]*/ -#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) -# include "pycore_gc.h" // PyGC_Head -# include "pycore_runtime.h" // _Py_ID() -#endif - PyDoc_STRVAR(MD5Type_copy__doc__, "copy($self, /)\n" "--\n" @@ -81,70 +76,25 @@ PyDoc_STRVAR(_md5_md5__doc__, "Return a new MD5 hash object; optionally initialized with a string."); #define _MD5_MD5_METHODDEF \ - {"md5", _PyCFunction_CAST(_md5_md5), METH_FASTCALL|METH_KEYWORDS, _md5_md5__doc__}, + {"md5", (PyCFunction)(void(*)(void))_md5_md5, METH_VARARGS|METH_KEYWORDS, _md5_md5__doc__}, static PyObject * _md5_md5_impl(PyObject *module, PyObject *string, int usedforsecurity); static PyObject * -_md5_md5(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_md5_md5(PyObject *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - - #define NUM_KEYWORDS 2 - static struct { - PyGC_Head _this_is_not_used; - PyObject_VAR_HEAD - PyObject *ob_item[NUM_KEYWORDS]; - } _kwtuple = { - .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) - .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, - }; - #undef NUM_KEYWORDS - #define KWTUPLE (&_kwtuple.ob_base.ob_base) - - #else // !Py_BUILD_CORE - # define KWTUPLE NULL - #endif // !Py_BUILD_CORE - - static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = { - .keywords = _keywords, - .fname = "md5", - .kwtuple = KWTUPLE, - }; - #undef KWTUPLE - PyObject *argsbuf[2]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + static char *_keywords[] = {"string", "usedforsecurity", NULL}; PyObject *string = NULL; int usedforsecurity = 1; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); - if (!args) { + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O$p:md5", _keywords, + &string, &usedforsecurity)) goto exit; - } - if (!noptargs) { - goto skip_optional_pos; - } - if (args[0]) { - string = args[0]; - if (!--noptargs) { - goto skip_optional_pos; - } - } -skip_optional_pos: - if (!noptargs) { - goto skip_optional_kwonly; - } - usedforsecurity = PyObject_IsTrue(args[1]); - if (usedforsecurity < 0) { - goto exit; - } -skip_optional_kwonly: return_value = _md5_md5_impl(module, string, usedforsecurity); exit: return return_value; } -/*[clinic end generated code: output=943d42b9d17d9a5b input=a9049054013a1b77]*/ +/*[clinic end generated code: output=015f7613e3a9bb93 input=a9049054013a1b77]*/ diff --git a/Modules/md5module.c b/Modules/md5module.c index 5463effb507de65..9d412ba580c336d 100644 --- a/Modules/md5module.c +++ b/Modules/md5module.c @@ -15,14 +15,12 @@ */ /* MD5 objects */ -#ifndef Py_BUILD_CORE_BUILTIN -# define Py_BUILD_CORE_MODULE 1 -#endif + +// Need limited C API version 3.13 for Py_MOD_PER_INTERPRETER_GIL_SUPPORTED +#define Py_LIMITED_API 0x030d0000 #include "Python.h" #include "hashlib.h" -#include "pycore_strhex.h" // _Py_strhex() -#include "pycore_typeobject.h" // _PyType_GetModuleState() /*[clinic input] module _md5 @@ -94,7 +92,7 @@ MD5_dealloc(MD5object *ptr) if (ptr->lock != NULL) { PyThread_free_lock(ptr->lock); } - PyTypeObject *tp = Py_TYPE(ptr); + PyTypeObject *tp = Py_TYPE((PyObject*)ptr); PyObject_GC_UnTrack(ptr); PyObject_GC_Del(ptr); Py_DECREF(tp); @@ -115,7 +113,7 @@ static PyObject * MD5Type_copy_impl(MD5object *self, PyTypeObject *cls) /*[clinic end generated code: output=bf055e08244bf5ee input=d89087dcfb2a8620]*/ { - MD5State *st = _PyType_GetModuleState(cls); + MD5State *st = PyType_GetModuleState(cls); MD5object *newobj; if ((newobj = newMD5object(st))==NULL) @@ -158,7 +156,16 @@ MD5Type_hexdigest_impl(MD5object *self) ENTER_HASHLIB(self); Hacl_Streaming_MD5_legacy_finish(self->hash_state, digest); LEAVE_HASHLIB(self); - return _Py_strhex((const char*)digest, MD5_DIGESTSIZE); + + const char *hexdigits = "0123456789abcdef"; + char digest_hex[MD5_DIGESTSIZE * 2]; + char *str = digest_hex; + for (size_t i=0; i < MD5_DIGESTSIZE; i++) { + unsigned char byte = digest[i]; + *str++ = hexdigits[byte >> 4]; + *str++ = hexdigits[byte & 0x0f]; + } + return PyUnicode_FromStringAndSize(digest_hex, sizeof(digest_hex)); } static void update(Hacl_Streaming_MD5_state *state, uint8_t *buf, Py_ssize_t len) { diff --git a/Tools/c-analyzer/cpython/ignored.tsv b/Tools/c-analyzer/cpython/ignored.tsv index 0ba7ab15ce89b8d..66c77cdaf17ddf8 100644 --- a/Tools/c-analyzer/cpython/ignored.tsv +++ b/Tools/c-analyzer/cpython/ignored.tsv @@ -729,3 +729,4 @@ Modules/_io/_iomodule.c - _PyIO_Module - Modules/_sqlite/module.c - _sqlite3module - Python/optimizer_analysis.c - _Py_PartitionRootNode_Type - Python/optimizer_analysis.c - _Py_UOpsAbstractInterpContext_Type - +Modules/clinic/md5module.c.h _md5_md5 _keywords -