diff --git a/Doc/library/zlib.rst b/Doc/library/zlib.rst index 6a51320df70..e37be69d6a6 100644 --- a/Doc/library/zlib.rst +++ b/Doc/library/zlib.rst @@ -9,10 +9,8 @@ For applications that require data compression, the functions in this module allow compression and decompression, using the zlib library. The zlib library -has its own home page at https://www.zlib.net. There are known -incompatibilities between the Python module and versions of the zlib library -earlier than 1.1.3; 1.1.3 has a `security vulnerability `_, so we recommend using -1.1.4 or later. +has its own home page at https://www.zlib.net. zlib 1.2.2.1 is the minium +supported version. zlib's functions have many options and often need to be used in a particular order. This documentation doesn't attempt to cover all of the permutations; diff --git a/Doc/using/configure.rst b/Doc/using/configure.rst index 01537951aeb..1f773a3a547 100644 --- a/Doc/using/configure.rst +++ b/Doc/using/configure.rst @@ -26,28 +26,26 @@ To build optional modules: * `libbz2 `_ for the :mod:`bz2` module. -* `libb2 `_ (:ref:`BLAKE2 `), - used by :mod:`hashlib` module. +* `libb2 `_ (:ref:`BLAKE2 `) + for the :mod:`hashlib` module. * `libffi `_ 3.3.0 is the recommended minimum version for the :mod:`ctypes` module. -* ``liblzma``, for the :mod:`lzma` module. +* ``liblzma`` for the :mod:`lzma` module. * `libmpdec `_ 2.5.0 for the :mod:`decimal` module. -* ``libncurses`` or ``libncursesw``, - for the :mod:`curses` module. +* ``libncurses`` or ``libncursesw`` for the :mod:`curses` module. -* ``libpanel`` or ``libpanelw``, - for the :mod:`curses.panel` module. +* ``libpanel`` or ``libpanelw`` for the :mod:`curses.panel` module. * `libreadline `_ or `libedit `_ for the :mod:`readline` module. -* `libuuid `_, for the :mod:`uuid` module. +* `libuuid `_ for the :mod:`uuid` module. * `OpenSSL `_ 1.1.1 is the minimum version and OpenSSL 3.0.18 is the recommended minimum version for the @@ -57,7 +55,7 @@ To build optional modules: * `Tcl/Tk `_ 8.5.12 for the :mod:`tkinter` module. -* `zlib `_ 1.1.4 is the reccomended minimum version for the +* `zlib `_ 1.2.2.1 is the minimum version for the :mod:`zlib` module. * `zstd `_ 1.4.5 is the minimum version for diff --git a/Include/internal/pycore_interp_structs.h b/Include/internal/pycore_interp_structs.h index badc97808c6..2124e76514f 100644 --- a/Include/internal/pycore_interp_structs.h +++ b/Include/internal/pycore_interp_structs.h @@ -769,6 +769,12 @@ struct _is { * and should be placed at the beginning. */ struct _ceval_state ceval; + /* This structure is carefully allocated so that it's correctly aligned + * to avoid undefined behaviors during LOAD and STORE. The '_malloced' + * field stores the allocated pointer address that will later be freed. + */ + void *_malloced; + PyInterpreterState *next; int64_t id; diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-10-14-17-07-37.gh-issue-140067.ID2gOm.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-10-14-17-07-37.gh-issue-140067.ID2gOm.rst deleted file mode 100644 index 3c5a828101d..00000000000 --- a/Misc/NEWS.d/next/Core_and_Builtins/2025-10-14-17-07-37.gh-issue-140067.ID2gOm.rst +++ /dev/null @@ -1 +0,0 @@ -Fix memory leak in sub-interpreter creation. diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index c519485c1cc..a73bfff340c 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -1469,14 +1469,14 @@ bytearray_removesuffix_impl(PyByteArrayObject *self, Py_buffer *suffix) /*[clinic input] bytearray.resize size: Py_ssize_t - New size to resize to.. + New size to resize to. / Resize the internal buffer of bytearray to len. [clinic start generated code]*/ static PyObject * bytearray_resize_impl(PyByteArrayObject *self, Py_ssize_t size) -/*[clinic end generated code: output=f73524922990b2d9 input=75fd4d17c4aa47d3]*/ +/*[clinic end generated code: output=f73524922990b2d9 input=6c9a260ca7f72071]*/ { Py_ssize_t start_size = PyByteArray_GET_SIZE(self); int result = PyByteArray_Resize((PyObject *)self, size); diff --git a/Objects/clinic/bytearrayobject.c.h b/Objects/clinic/bytearrayobject.c.h index ffb45ade11f..6f13865177d 100644 --- a/Objects/clinic/bytearrayobject.c.h +++ b/Objects/clinic/bytearrayobject.c.h @@ -599,7 +599,7 @@ PyDoc_STRVAR(bytearray_resize__doc__, "Resize the internal buffer of bytearray to len.\n" "\n" " size\n" -" New size to resize to.."); +" New size to resize to."); #define BYTEARRAY_RESIZE_METHODDEF \ {"resize", (PyCFunction)bytearray_resize, METH_O, bytearray_resize__doc__}, @@ -1796,4 +1796,4 @@ bytearray_sizeof(PyObject *self, PyObject *Py_UNUSED(ignored)) { return bytearray_sizeof_impl((PyByteArrayObject *)self); } -/*[clinic end generated code: output=be6d28193bc96a2c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=fdfe41139c91e409 input=a9049054013a1b77]*/ diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 9398bcb29c8..29233c1959c 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -81,7 +81,7 @@ class object "PyObject *" "&PyBaseObject_Type" #define END_TYPE_DICT_LOCK() Py_END_CRITICAL_SECTION2() -#ifdef Py_DEBUG +#ifndef NDEBUG // Return true if the world is currently stopped. static bool types_world_is_stopped(void) diff --git a/Python/pystate.c b/Python/pystate.c index bf6e4e56e6d..dbed609f29a 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -457,19 +457,16 @@ _PyInterpreterState_Enable(_PyRuntimeState *runtime) static PyInterpreterState * alloc_interpreter(void) { - // Aligned allocation for PyInterpreterState. - // the first word of the memory block is used to store - // the original pointer to be used later to free the memory. size_t alignment = _Alignof(PyInterpreterState); - size_t allocsize = sizeof(PyInterpreterState) + sizeof(void *) + alignment - 1; + size_t allocsize = sizeof(PyInterpreterState) + alignment - 1; void *mem = PyMem_RawCalloc(1, allocsize); if (mem == NULL) { return NULL; } - void *ptr = _Py_ALIGN_UP((char *)mem + sizeof(void *), alignment); - ((void **)ptr)[-1] = mem; - assert(_Py_IS_ALIGNED(ptr, alignment)); - return ptr; + PyInterpreterState *interp = _Py_ALIGN_UP(mem, alignment); + assert(_Py_IS_ALIGNED(interp, alignment)); + interp->_malloced = mem; + return interp; } static void @@ -484,7 +481,7 @@ free_interpreter(PyInterpreterState *interp) interp->obmalloc = NULL; } assert(_Py_IS_ALIGNED(interp, _Alignof(PyInterpreterState))); - PyMem_RawFree(((void **)interp)[-1]); + PyMem_RawFree(interp->_malloced); } } diff --git a/configure b/configure index 211f8439906..9757b3419d3 100755 --- a/configure +++ b/configure @@ -21736,19 +21736,19 @@ fi pkg_failed=no -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for zlib >= 1.2.0" >&5 -printf %s "checking for zlib >= 1.2.0... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for zlib >= 1.2.2.1" >&5 +printf %s "checking for zlib >= 1.2.2.1... " >&6; } if test -n "$ZLIB_CFLAGS"; then pkg_cv_ZLIB_CFLAGS="$ZLIB_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"zlib >= 1.2.0\""; } >&5 - ($PKG_CONFIG --exists --print-errors "zlib >= 1.2.0") 2>&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"zlib >= 1.2.2.1\""; } >&5 + ($PKG_CONFIG --exists --print-errors "zlib >= 1.2.2.1") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_ZLIB_CFLAGS=`$PKG_CONFIG --cflags "zlib >= 1.2.0" 2>/dev/null` + pkg_cv_ZLIB_CFLAGS=`$PKG_CONFIG --cflags "zlib >= 1.2.2.1" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -21760,12 +21760,12 @@ if test -n "$ZLIB_LIBS"; then pkg_cv_ZLIB_LIBS="$ZLIB_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"zlib >= 1.2.0\""; } >&5 - ($PKG_CONFIG --exists --print-errors "zlib >= 1.2.0") 2>&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"zlib >= 1.2.2.1\""; } >&5 + ($PKG_CONFIG --exists --print-errors "zlib >= 1.2.2.1") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_ZLIB_LIBS=`$PKG_CONFIG --libs "zlib >= 1.2.0" 2>/dev/null` + pkg_cv_ZLIB_LIBS=`$PKG_CONFIG --libs "zlib >= 1.2.2.1" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -21786,9 +21786,9 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - ZLIB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "zlib >= 1.2.0" 2>&1` + ZLIB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "zlib >= 1.2.2.1" 2>&1` else - ZLIB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "zlib >= 1.2.0" 2>&1` + ZLIB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "zlib >= 1.2.2.1" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$ZLIB_PKG_ERRORS" >&5 diff --git a/configure.ac b/configure.ac index 35bf153a898..f244e0b71a6 100644 --- a/configure.ac +++ b/configure.ac @@ -5424,7 +5424,7 @@ AH_TEMPLATE([HAVE_ZLIB_COPY], [Define if the zlib library has inflateCopy]) dnl detect zlib from Emscripten emport PY_CHECK_EMSCRIPTEN_PORT([ZLIB], [-sUSE_ZLIB]) -PKG_CHECK_MODULES([ZLIB], [zlib >= 1.2.0], [ +PKG_CHECK_MODULES([ZLIB], [zlib >= 1.2.2.1], [ have_zlib=yes dnl zlib 1.2.0 (2003) added inflateCopy AC_DEFINE([HAVE_ZLIB_COPY], [1])