]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-85283: Build md5 extension with limited C API (#110967)
authorVictor Stinner <vstinner@python.org>
Tue, 17 Oct 2023 10:57:41 +0000 (12:57 +0200)
committerGitHub <noreply@github.com>
Tue, 17 Oct 2023 10:57:41 +0000 (10:57 +0000)
* Replace _Py_strhex() with few lines of code.
* Replace _PyType_GetModuleState() with PyType_GetModuleState().
* Fix make check-c-globals.

Doc/whatsnew/3.13.rst
Misc/NEWS.d/next/Build/2023-10-17-01-56-11.gh-issue-85283.V156T2.rst
Modules/clinic/md5module.c.h
Modules/md5module.c
Tools/c-analyzer/cpython/ignored.tsv

index a932be43413b1e1c4be0560b6f5032f2be2120de..8ce41e130864903964c8ffe5cec75d1695db9bd1 100644 (file)
@@ -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 <limited-c-api>`.
+* The ``errno``, ``md5``, ``_ctypes_test``, ``_stat`` and
+  ``_testimportmultiple`` C extensions are now built with the :ref:`limited C
+  API <limited-c-api>`.
   (Contributed by Victor Stinner in :gh:`85283`.)
 
 
index db4849650fd8499d28e421ae22a1a87c6bca9ec4..4240db7c3b9f6c347e7735eeb12d5c6aa6469156 100644 (file)
@@ -1,3 +1,3 @@
-The ``errno``, ``_ctypes_test`` and ``_testimportmultiple`` C extensions are
-now built with the :ref:`limited C API <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 <limited-c-api>`. Patch
+by Victor Stinner.
index 6087a0f9c25c1a57807547cfba6c74cd5c15530a..11db7952c5ce6abbe9e89bee706e8476faa6f9da 100644 (file)
@@ -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]*/
index 5463effb507de655cfea9ec0a859f08829cfaeba..9d412ba580c336d5dfb21352bbba4249caa25153 100644 (file)
 */
 
 /* 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) {
index 0ba7ab15ce89b8d8cdf57be968a038e991183bdb..66c77cdaf17ddf89d08341df5d87d898e117f78a 100644 (file)
@@ -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       -