From 6e06723682a0da6a2bff5f0c5563784128c2f0c580ccfcb180b25720cc96a473 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C4=9Bj=20Cepl?= Date: Wed, 11 Feb 2026 23:12:02 +0100 Subject: [PATCH] Update to 3.15.0a6: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Tests - gh-144415: The Android testbed now distinguishes between stdout/stderr messages which were triggered by a newline, and those triggered by a manual call to flush. This fixes logging of progress indicators and similar content. - gh-65784: Add support for parametrized resource wantobjects in regrtests, which allows to run Tkinter tests with the specified value of tkinter.wantobjects, for example -u wantobjects=0. - Security - CVE-2024-6923: BytesGenerator will now refuse to serialize (write) headers that are unsafely folded or delimited; see verify_generated_headers. (Contributed by Bas Bloemsaat and Petr Viktorin in gh-121650). (bsc#1228780, gh-144125) - CVE-2025-11468: Fixed a bug in the folding of comments when flattening an email message using a modern email policy. Comments consisting of a very long sequence of non-foldable characters could trigger a forced line wrap that omitted the required leading space on the continuation line, causing the remainder of the comment to be interpreted as a new header field. This enabled header injection with carefully crafted inputs. (bsc#1257029, gh-143935) - CVE-2025-15282: Reject control characters in data: URL media types. (bsc#1257046, gh-143925) - CVE-2025-15367: Reject control characters in POP3 commands. (bsc#1257041, gh-143923) - CVE-2025-15366: Reject control characters in IMAP commands. (bsc#1257044, gh-143921) - CVE-2026-0672: Reject control characters in http.cookies.Morsel fields and values. (bsc#1257031, gh-143919) - CVE-2026-0865: Reject C0 control characters within wsgiref.headers.Headers fields, values, and parameters. (bsc#1257042, gh-143916) - Library - gh-144538: Bump the version of pip bundled in ensurepip to version 26.0.1 - gh-144493: Improve an exception error message in _overlapped.BindLocal() that is raised when asyncio.loop.sock_connect() is called on a asyncio.ProactorEventLoop with a socket that has an invalid address family. - gh-144386: Add support for arbitrary descriptors __enter__(), __exit__(), __aenter__(), and __aexit__() in contextlib.ExitStack and contextlib.AsyncExitStack, for consistency with the with and async with statements. - gh-123471: Make concurrent iteration over itertools.combinations_with_replacement and itertools.permutations safe under free-threading. - gh-74453: Deprecate os.path.commonprefix() in favor of os.path.commonpath() for path segment prefixes. - The os.path.commonprefix() function is being deprecated due to having a misleading name and module. The function is not safe to use for path prefixes despite being included in a module about path manipulation, meaning it is easy to accidentally introduce path traversal vulnerabilities into Python programs by using this function. - gh-144380: Improve performance of io.BufferedReader line iteration by ~49%. - gh-144363: Update bundled libexpat to 2.7.4 - gh-140824: When faulthandler dumps the list of third-party extension modules, ignore sub-modules of stdlib packages. Patch by Victor Stinner. - gh-144206: Improve error messages for buffer overflow in fcntl.fcntl() and fcntl.ioctl(). - gh-144264: Speed up Base64 decoding of data containing ignored characters (both in non-strict mode and with an explicit ignorechars argument). It is now up to 2 times faster for multiline Base64 data. - gh-144249: Add filename context to OSError exceptions raised by ssl.SSLContext.load_cert_chain(), allowing users to have more context. - gh-132888: Fix incorrect use of ctypes.GetLastError() and add missing error checks for Windows API calls in _pyrepl.windows_console. - gh-142956: Updated tomllib to parse TOML 1.1.0. - gh-144217: mimetypes: Add support for DICOM files (for medical imaging) with the official MIME type application/dicom. Patch by Benedikt Johannes. - gh-144212: Mime type image/jxl is now supported by mimetypes. - gh-143594: Add symtable.Function.get_cells() and symtable.Symbol.is_cell() methods. - gh-144169: Fix three crashes when non-string keyword arguments are supplied to objects in the ast module. - gh-144128: Fix a crash in array.array.fromlist() when an element’s __index__() method mutates the input list during conversion. - gh-144100: Fixed a crash in ctypes when using a deprecated POINTER(str) type in argtypes. Instead of aborting, ctypes now raises a proper Python exception when the pointer target type is unresolved. - gh-143658: importlib.metadata: Use str.lower() and str.replace() to further improve performance of importlib.metadata.Prepared.normalize(). Patch by Hugo van Kemenade and Henry Schreiner. - gh-144050: Fix stat.filemode() in the pure-Python implementation to avoid misclassifying invalid mode values as block devices. - gh-83069: subprocess.Popen.wait(): when timeout is not None, an efficient event-driven mechanism now waits for process termination, if available. Linux >= 5.3 uses os.pidfd_open() + select.poll(). macOS and other BSD variants use select.kqueue() + KQ_FILTER_PROC + KQ_NOTE_EXIT. Windows keeps using WaitForSingleObject (unchanged). If none of these mechanisms are available, the function falls back to the traditional busy loop (non-blocking call and short sleeps). Patch by Giampaolo Rodola. - gh-144030: The Python implementation of functools.lru_cache() differed from the default C implementation in that it did not check that its argument is callable. This discrepancy is now fixed and both raise a TypeError. - gh-144001: Added the ignorechars parameter in binascii.a2b_base64() and base64.b64decode(). - gh-144023: Fixed validation of file descriptor 0 in posix functions when used with follow_symlinks parameter. - gh-143999: Fix an issue where inspect.getgeneratorstate() and inspect.getcoroutinestate() could fail for generators wrapped by types.coroutine() in the suspended state. - gh-143952: Fixed asyncio debugging tools to work with new remote debugging API. Patch by Bartosz Sławecki. - gh-143904: struct.pack_into() now raises OverflowError instead of IndexError for too large offset argument. - gh-143897: Remove the isxidstart() and isxidcontinue() methods of unicodedata.ucd_3_2_0. They are now only exposed as unicodedata.isxidstart() and unicodedata.isxidcontinue(). - gh-143831: annotationlib.ForwardRef objects are now hashable when created from annotation scopes with closures. Previously, hashing such objects would throw an exception. Patch by Bartosz Sławecki. - gh-143874: Fixed a bug in pdb where expression results were not sent back to remote client. - gh-143754: Add new tkinter widget methods pack_content(), place_content() and grid_content() which are alternative spelling of old *_slaves() methods. - gh-143756: Fix potential thread safety issues in ssl module. - gh-132604: Previously, Protocol classes that were not decorated with @~typing.runtime_checkable, but that inherited from another Protocol class that did have this decorator, could be used in isinstance() and issubclass() checks. This behavior is now deprecated and such checks will throw a TypeError in Python 3.20. Patch by Bartosz Sławecki. - gh-143543: Fix a crash in itertools.groupby that could occur when a user-defined __eq__() method re-enters the iterator during key comparison. - gh-143689: Fix io.BufferedReader.read1() state cleanup on buffer allocation failure. - gh-143602: Fix a inconsistency issue in write() that leads to unexpected buffer overwrite by deduplicating the buffer exports. - gh-142434: Use ppoll() if available in select.poll() to have a timeout resolution of 1 nanosecond, instead of a resolution of 1 ms. Patch by Victor Stinner. - gh-140557: array.array buffers now have the same alignment when empty as when allocated. Unaligned buffers can still be created by slicing. - gh-143423: Fix free-threaded build detection in the sampling profiler when Py_GIL_DISABLED is set to 0. - gh-101178: Add Ascii85, Base85, and Z85 support to binascii and improve the performance of the base-85 converters in base64. - gh-142966: Fix ctypes.POINTER.set_type() not updating the format string to match the type. - gh-142555: array: fix a crash in a[i] = v when converting i to an index via i.__index__ or i.__float__ mutates the array. - gh-142438: Fix _decimal builds configured with EXTRA_FUNCTIONALITY by correcting the Context.apply wrapper to pass the right argument. - gh-141860: Add an on_error keyword-only parameter to multiprocessing.set_forkserver_preload() to control how import failures during module preloading are handled. Accepts 'ignore' (default, silent), 'warn' (emit ImportWarning), or 'fail' (raise exception). Contributed by Nick Neumann and Gregory P. Smith. - CVE-2025-12781: Accepting + and / characters with an alternative alphabet in base64.b64decode() and base64.urlsafe_b64decode() is now deprecated. In future Python versions they will be errors in the strict mode and discarded in the non-strict mode. (bsc#1257108, gh-125346) - gh-140715: Add '%F' support to strptime(). - gh-67041: Add the missing_as_none parameter to urlparse(), urlsplit() and urldefrag() functions. Add the keep_empty parameter to urlunparse() and urlunsplit() functions. This allows to distinguish between empty and not defined URI components and preserve empty components. - gh-77188: The pickle module now properly handles name-mangled private methods. - IDLE - gh-143774: Better explain the operation of Format / Format Paragraph. - Core and Builtins - gh-134584: Optimize and eliminate ref-counting in _BINARY_OP_SUBSCR_LIST_SLICE - gh-144563: Fix interaction of the Tachyon profiler and ctypes and other modules that load the Python shared library (if present) in an independent map as this was causing the mechanism that loads the binary information to be confused. Patch by Pablo Galindo - gh-144601: Fix crash when importing a module whose PyInit function raises an exception from a subinterpreter. - gh-144549: Fix building the tail calling interpreter on Visual Studio 2026 with free-threading. - gh-144513: Fix potential deadlock when using critical sections during stop-the-world pauses in the free-threaded build. - gh-131798: Optimise _GUARD_TOS_SLICE in the JIT. - gh-144330: Move classmethod and staticmethod initialization from __init__() to __new__(). Patch by Victor Stinner. - gh-144446: Fix data races in the free-threaded build when reading frame object attributes while another thread is executing the frame. - gh-120321: Add gi_state, cr_state, and ag_state attributes to generators, coroutines, and async generators that return the current state as a string (e.g., GEN_RUNNING). The inspect module functions getgeneratorstate(), getcoroutinestate(), and getasyncgenstate() now return these attributes directly. - gh-141563: Fix thread safety of PyDateTime_IMPORT. - gh-144280: Fix a bug in JIT where the predicate symbol had no truthiness - gh-140550: In PyModuleDef.m_slots, allow slots that repeat information present in PyModuleDef. - gh-139103: Improve scaling of namedtuple() instantiation in the free-threaded build. - gh-144307: Prevent a reference leak in module teardown at interpreter finalization. - gh-144319: Add huge pages support for the pymalloc allocator. Patch by Pablo Galindo - gh-120321: Made gi_yieldfrom thread-safe in the free-threading build by using a lightweight lock on the frame state. - gh-144194: Fix error handling in perf jitdump initialization on memory allocation failure. - gh-143962: Name suggestion for not normalized name suggests now the normalized name or the closest name to the normalized name. If the suggested name is not ASCII, include also its ASCII representation. - gh-144157: bytes.translate() now allows the compiler to unroll its loop more usefully for a 2x speedup in the common no-deletions specified case. - gh-144068: Fix JIT tracer memory leak, ensure the JIT tracer state is freed when daemon threads are cleaned up during interpreter shutdown. - gh-144012: Check if the result is NULL in BINARY_OP_EXTENT opcode. - gh-144007: Eliminate redundant refcounting in the JIT for BINARY_OP. - gh-144005: Eliminate redundant refcounting from BINARY_OP_EXTEND. - gh-143939: Fix erroneous “cannot reuse already awaited coroutine” error that could occur when a generator was run during the process of clearing a coroutine’s frame. - gh-141805: Fix crash in set when objects with the same hash are concurrently added to the set after removing an element with the same hash while the set still contains elements with the same hash. - gh-143670: Fixes a crash in ga_repr_items_list function. - gh-143650: Fix race condition in importlib where a thread could receive a stale module reference when another thread’s import fails. - gh-143569: Generator expressions in 3.15 now conform to the documented behavior when the iterable does not support iteration. This matches the behavior in 3.14 and earlier - gh-143192: Improve performance of bitwise operations on multi-digit ints. - gh-132657: If we are specializing to LOAD_GLOBAL_MODULE or LOAD_ATTR_MODULE, try to enable deferred reference counting for the value, if the object is owned by a different thread. This applies to the free-threaded build only and should improve scaling of multi-threaded programs. Note that when deferred reference counting is enabled, the object will be deallocated by the GC, rather than by Py_DECREF(). - gh-143055: Implement PEP 798 (Unpacking in Comprehensions). Patch by Adam Hartz. - gh-142037: Improve error messages for printf-style formatting. For errors in the format string, always include the position of the start of the format unit. For errors related to the formatted arguments, always include the number or the name of the argument. Raise more specific errors and include more information (type and number of arguments, most probable causes of error). - gh-140557: bytearray buffers now have the same alignment when empty as when allocated. Unaligned buffers can still be created by slicing. - gh-140232: Frozenset objects with immutable elements are no longer tracked by the garbage collector. - gh-115231: Setup __module__ attribute for built-in static methods. Patch by Sergey B Kirpichev. - C API - gh-143869: Added PyLong_GetNativeLayout(), PyLongLayout, PyLongExport, PyLong_Export(), PyLong_FreeExport(), PyLongWriter, PyLongWriter_Create(), PyLongWriter_Finish() and PyLongWriter_Discard() to the limited API. - gh-141070: Renamed PyUnstable_Object_Dump() to PyObject_Dump(). - Build - gh-140421: Disable the perf trampoline on older macOS versions where it cannot be built. - gh-144309: Build Python with POSIX 2024, instead of POSIX 2008. Patch by Victor Stinner. - gh-144278: Enables defining the _PY_IMPL_NAME and _PY_IMPL_CACHE_TAG preprocessor definitions to override sys.implementation at build time. Definitions need to include quotes when setting to a string literal. Setting the cache tag to NULL has the effect of completely disabling automatic creation and use of .pyc files. - gh-143960: Add support for OpenSSL 3.6, drop EOL 3.2. Patch by Hugo van Kemenade. - gh-143941: Move WASI-related files to Platforms/WASI. Along the way, leave a deprecated Tools/wasm/wasi/__main__.py behind for backwards-compatibility. - gh-143842: Prevent static builds from clashing with curses by making the optimizer COLORS table static. Remove upstreamed patches: - CVE-2024-6923-follow-up-EOL-email-headers.patch - CVE-2025-11468-email-hdr-fold-comment.patch - CVE-2025-12781-b64decode-alt-chars.patch - CVE-2025-15282-urllib-ctrl-chars.patch - CVE-2025-15366-imap-ctrl-chars.patch - CVE-2025-15367-poplib-ctrl-chars.patch - CVE-2026-0672-http-hdr-inject-cookie-Morsel.patch - CVE-2026-0865-wsgiref-ctrl-chars.patch --- ...024-6923-follow-up-EOL-email-headers.patch | 110 ------ CVE-2025-11468-email-hdr-fold-comment.patch | 97 ----- CVE-2025-12781-b64decode-alt-chars.patch | 217 ------------ CVE-2025-15282-urllib-ctrl-chars.patch | 44 +-- CVE-2025-15366-imap-ctrl-chars.patch | 56 --- CVE-2025-15367-poplib-ctrl-chars.patch | 56 --- ...6-0672-http-hdr-inject-cookie-Morsel.patch | 191 ---------- CVE-2026-0865-wsgiref-ctrl-chars.patch | 68 ---- Python-3.15.0a5.tar.xz | 3 - Python-3.15.0a5.tar.xz.sigstore | 1 - Python-3.15.0a6.tar.xz | 3 + Python-3.15.0a6.tar.xz.sigstore | 1 + bpo-31046_ensurepip_honours_prefix.patch | 38 +- python315.changes | 334 ++++++++++++++++++ python315.spec | 29 +- 15 files changed, 377 insertions(+), 871 deletions(-) delete mode 100644 CVE-2024-6923-follow-up-EOL-email-headers.patch delete mode 100644 CVE-2025-11468-email-hdr-fold-comment.patch delete mode 100644 CVE-2025-12781-b64decode-alt-chars.patch delete mode 100644 CVE-2025-15366-imap-ctrl-chars.patch delete mode 100644 CVE-2025-15367-poplib-ctrl-chars.patch delete mode 100644 CVE-2026-0672-http-hdr-inject-cookie-Morsel.patch delete mode 100644 CVE-2026-0865-wsgiref-ctrl-chars.patch delete mode 100644 Python-3.15.0a5.tar.xz delete mode 100644 Python-3.15.0a5.tar.xz.sigstore create mode 100644 Python-3.15.0a6.tar.xz create mode 100644 Python-3.15.0a6.tar.xz.sigstore diff --git a/CVE-2024-6923-follow-up-EOL-email-headers.patch b/CVE-2024-6923-follow-up-EOL-email-headers.patch deleted file mode 100644 index e2e5fa1..0000000 --- a/CVE-2024-6923-follow-up-EOL-email-headers.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 1132e45e8b588cd89bd168583afa37ba7c9f0afa Mon Sep 17 00:00:00 2001 -From: Denis Ledoux -Date: Mon, 27 Oct 2025 17:47:59 +0100 -Subject: [PATCH 1/3] gh-144125: email: verify headers are sound in - BytesGenerator - -GH-122233 added an implementation to `Generator` -to refuse to serialize (write) headers that -are unsafely folded or delimited. - -This revision adds the same implementation -to `BytesGenerator`, so it gets the same safety protections -for unsafely folded or delimited headers - -Co-authored-by: Denis Ledoux <5822488+beledouxdenis@users.noreply.github.com> -Co-authored-by: Petr Viktorin <302922+encukou@users.noreply.github.com> -Co-authored-by: Bas Bloemsaat <1586868+basbloemsaat@users.noreply.github.com> ---- - Lib/email/generator.py | 12 +++++++++- - Lib/test/test_email/test_generator.py | 4 ++- - Lib/test/test_email/test_policy.py | 6 ++++- - Misc/NEWS.d/next/Security/2026-01-21-12-34-05.gh-issue-144125.TAz5uo.rst | 4 +++ - 4 files changed, 23 insertions(+), 3 deletions(-) - create mode 100644 Misc/NEWS.d/next/Security/2026-01-21-12-34-05.gh-issue-144125.TAz5uo.rst - -Index: Python-3.15.0a3/Lib/email/generator.py -=================================================================== ---- Python-3.15.0a3.orig/Lib/email/generator.py 2026-01-27 17:26:06.289940190 +0100 -+++ Python-3.15.0a3/Lib/email/generator.py 2026-01-27 17:26:14.361081031 +0100 -@@ -22,6 +22,7 @@ - NLCRE = re.compile(r'\r\n|\r|\n') - fcre = re.compile(r'^From ', re.MULTILINE) - NEWLINE_WITHOUT_FWSP = re.compile(r'\r\n[^ \t]|\r[^ \n\t]|\n[^ \t]') -+NEWLINE_WITHOUT_FWSP_BYTES = re.compile(br'\r\n[^ \t]|\r[^ \n\t]|\n[^ \t]') - - - class Generator: -@@ -429,7 +430,16 @@ - # This is almost the same as the string version, except for handling - # strings with 8bit bytes. - for h, v in msg.raw_items(): -- self._fp.write(self.policy.fold_binary(h, v)) -+ folded = self.policy.fold_binary(h, v) -+ if self.policy.verify_generated_headers: -+ linesep = self.policy.linesep.encode() -+ if not folded.endswith(linesep): -+ raise HeaderWriteError( -+ f'folded header does not end with {linesep!r}: {folded!r}') -+ if NEWLINE_WITHOUT_FWSP_BYTES.search(folded.removesuffix(linesep)): -+ raise HeaderWriteError( -+ f'folded header contains newline: {folded!r}') -+ self._fp.write(folded) - # A blank line always separates headers from body - self.write(self._NL) - -Index: Python-3.15.0a3/Lib/test/test_email/test_generator.py -=================================================================== ---- Python-3.15.0a3.orig/Lib/test/test_email/test_generator.py 2026-01-27 17:26:08.009520772 +0100 -+++ Python-3.15.0a3/Lib/test/test_email/test_generator.py 2026-01-27 17:26:14.363103139 +0100 -@@ -313,7 +313,7 @@ - self.assertEqual(s.getvalue(), self.typ(expected)) - - def test_verify_generated_headers(self): -- """gh-121650: by default the generator prevents header injection""" -+ # gh-121650: by default the generator prevents header injection - class LiteralHeader(str): - name = 'Header' - def fold(self, **kwargs): -@@ -334,6 +334,8 @@ - - with self.assertRaises(email.errors.HeaderWriteError): - message.as_string() -+ with self.assertRaises(email.errors.HeaderWriteError): -+ message.as_bytes() - - - class TestBytesGenerator(TestGeneratorBase, TestEmailBase): -Index: Python-3.15.0a3/Lib/test/test_email/test_policy.py -=================================================================== ---- Python-3.15.0a3.orig/Lib/test/test_email/test_policy.py 2026-01-27 17:26:08.021649854 +0100 -+++ Python-3.15.0a3/Lib/test/test_email/test_policy.py 2026-01-27 17:26:14.363238384 +0100 -@@ -296,7 +296,7 @@ - policy.fold("Subject", subject) - - def test_verify_generated_headers(self): -- """Turning protection off allows header injection""" -+ # Turning protection off allows header injection - policy = email.policy.default.clone(verify_generated_headers=False) - for text in ( - 'Header: Value\r\nBad: Injection\r\n', -@@ -319,6 +319,10 @@ - message.as_string(), - f"{text}\nBody", - ) -+ self.assertEqual( -+ message.as_bytes(), -+ f"{text}\nBody".encode(), -+ ) - - # XXX: Need subclassing tests. - # For adding subclassed objects, make sure the usual rules apply (subclass -Index: Python-3.15.0a3/Misc/NEWS.d/next/Security/2026-01-21-12-34-05.gh-issue-144125.TAz5uo.rst -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ Python-3.15.0a3/Misc/NEWS.d/next/Security/2026-01-21-12-34-05.gh-issue-144125.TAz5uo.rst 2026-01-27 17:26:14.362392400 +0100 -@@ -0,0 +1,4 @@ -+:mod:`~email.generator.BytesGenerator` will now refuse to serialize (write) headers -+that are unsafely folded or delimited; see -+:attr:`~email.policy.Policy.verify_generated_headers`. (Contributed by Bas -+Bloemsaat and Petr Viktorin in :gh:`121650`). diff --git a/CVE-2025-11468-email-hdr-fold-comment.patch b/CVE-2025-11468-email-hdr-fold-comment.patch deleted file mode 100644 index dc05af3..0000000 --- a/CVE-2025-11468-email-hdr-fold-comment.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 0b64fd5f8854703eb47ed89a3b0d472a13d0d651 Mon Sep 17 00:00:00 2001 -From: Denis Ledoux -Date: Thu, 6 Nov 2025 17:42:34 +0100 -Subject: [PATCH 1/5] email: correctly indent with a least one space folded - comments - ---- - Lib/email/_header_value_parser.py | 15 ++++++ - Lib/test/test_email/test__header_value_parser.py | 23 ++++++++++ - Misc/NEWS.d/next/Security/2026-01-16-14-40-31.gh-issue-143935.U2YtKl.rst | 6 ++ - 3 files changed, 43 insertions(+), 1 deletion(-) - -Index: Python-3.15.0a3/Lib/email/_header_value_parser.py -=================================================================== ---- Python-3.15.0a3.orig/Lib/email/_header_value_parser.py 2026-01-29 13:44:51.429261309 +0100 -+++ Python-3.15.0a3/Lib/email/_header_value_parser.py 2026-01-29 13:45:04.109091639 +0100 -@@ -101,6 +101,12 @@ - return str(value).replace('\\', '\\\\').replace('"', '\\"') - - -+def make_parenthesis_pairs(value): -+ """Escape parenthesis and backslash for use within a comment.""" -+ return str(value).replace('\\', '\\\\') \ -+ .replace('(', '\\(').replace(')', '\\)') -+ -+ - def quote_string(value): - escaped = make_quoted_pairs(value) - return f'"{escaped}"' -@@ -943,7 +949,7 @@ - return ' ' - - def startswith_fws(self): -- return True -+ return self and self[0] in WSP - - - class ValueTerminal(Terminal): -@@ -2963,6 +2969,13 @@ - [ValueTerminal(make_quoted_pairs(p), 'ptext') - for p in newparts] + - [ValueTerminal('"', 'ptext')]) -+ if part.token_type == 'comment': -+ newparts = ( -+ [ValueTerminal('(', 'ptext')] + -+ [ValueTerminal(make_parenthesis_pairs(p), 'ptext') -+ if p.token_type == 'ptext' else p -+ for p in newparts] + -+ [ValueTerminal(')', 'ptext')]) - if not part.as_ew_allowed: - wrap_as_ew_blocked += 1 - newparts.append(end_ew_not_allowed) -Index: Python-3.15.0a3/Lib/test/test_email/test__header_value_parser.py -=================================================================== ---- Python-3.15.0a3.orig/Lib/test/test_email/test__header_value_parser.py 2026-01-29 13:44:53.065308861 +0100 -+++ Python-3.15.0a3/Lib/test/test_email/test__header_value_parser.py 2026-01-29 13:45:04.109478618 +0100 -@@ -3294,6 +3294,29 @@ - with self.subTest(to=to): - self._test(parser.get_address_list(to)[0], folded, policy=policy) - -+ def test_address_list_with_long_unwrapable_comment(self): -+ policy = self.policy.clone(max_line_length=40) -+ cases = [ -+ # (to, folded) -+ ('(loremipsumdolorsitametconsecteturadipi)', -+ '(loremipsumdolorsitametconsecteturadipi)\n'), -+ ('(loremipsumdolorsitametconsecteturadipi)', -+ '(loremipsumdolorsitametconsecteturadipi)\n'), -+ ('(loremipsum dolorsitametconsecteturadipi)', -+ '(loremipsum dolorsitametconsecteturadipi)\n'), -+ ('(loremipsum dolorsitametconsecteturadipi)', -+ '(loremipsum\n dolorsitametconsecteturadipi)\n'), -+ ('(Escaped \\( \\) chars \\\\ in comments stay escaped)', -+ '(Escaped \\( \\) chars \\\\ in comments stay\n escaped)\n'), -+ ('((loremipsum)(loremipsum)(loremipsum)(loremipsum))', -+ '((loremipsum)(loremipsum)(loremipsum)(loremipsum))\n'), -+ ('((loremipsum)(loremipsum)(loremipsum) (loremipsum))', -+ '((loremipsum)(loremipsum)(loremipsum)\n (loremipsum))\n'), -+ ] -+ for (to, folded) in cases: -+ with self.subTest(to=to): -+ self._test(parser.get_address_list(to)[0], folded, policy=policy) -+ - # XXX Need tests with comments on various sides of a unicode token, - # and with unicode tokens in the comments. Spaces inside the quotes - # currently don't do the right thing. -Index: Python-3.15.0a3/Misc/NEWS.d/next/Security/2026-01-16-14-40-31.gh-issue-143935.U2YtKl.rst -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ Python-3.15.0a3/Misc/NEWS.d/next/Security/2026-01-16-14-40-31.gh-issue-143935.U2YtKl.rst 2026-01-29 13:45:04.109846601 +0100 -@@ -0,0 +1,6 @@ -+Fixed a bug in the folding of comments when flattening an email message -+using a modern email policy. Comments consisting of a very long sequence of -+non-foldable characters could trigger a forced line wrap that omitted the -+required leading space on the continuation line, causing the remainder of -+the comment to be interpreted as a new header field. This enabled header -+injection with carefully crafted inputs. diff --git a/CVE-2025-12781-b64decode-alt-chars.patch b/CVE-2025-12781-b64decode-alt-chars.patch deleted file mode 100644 index c528204..0000000 --- a/CVE-2025-12781-b64decode-alt-chars.patch +++ /dev/null @@ -1,217 +0,0 @@ -From f922c02c529d25d61aa9c28a8192639c1fce8d4d Mon Sep 17 00:00:00 2001 -From: Serhiy Storchaka -Date: Wed, 5 Nov 2025 20:12:31 +0200 -Subject: [PATCH] gh-125346: Add more base64 tests - -Add more tests for the altchars argument of b64decode() and for the map01 -argument of b32decode(). ---- - Doc/library/base64.rst | 18 ++-- - Doc/whatsnew/3.15.rst | 9 ++ - Lib/base64.py | 40 +++++++- - Lib/test/test_base64.py | 45 ++++++++-- - Misc/NEWS.d/next/Library/2025-11-06-12-03-29.gh-issue-125346.7Gfpgw.rst | 5 + - 5 files changed, 100 insertions(+), 17 deletions(-) - -Index: Python-3.15.0a5/Doc/library/base64.rst -=================================================================== ---- Python-3.15.0a5.orig/Doc/library/base64.rst 2026-01-14 15:41:32.000000000 +0100 -+++ Python-3.15.0a5/Doc/library/base64.rst 2026-02-08 14:34:01.166782651 +0100 -@@ -84,15 +84,20 @@ - A :exc:`binascii.Error` exception is raised - if *s* is incorrectly padded. - -- If *validate* is ``False`` (the default), characters that are neither -+ If *validate* is false (the default), characters that are neither - in the normal base-64 alphabet nor the alternative alphabet are -- discarded prior to the padding check. If *validate* is ``True``, -- these non-alphabet characters in the input result in a -- :exc:`binascii.Error`. -+ discarded prior to the padding check, but the ``+`` and ``/`` characters -+ keep their meaning if they are not in *altchars* (they will be discarded -+ in future Python versions). -+ If *validate* is true, these non-alphabet characters in the input -+ result in a :exc:`binascii.Error`. - - For more information about the strict base64 check, see :func:`binascii.a2b_base64` - -- May assert or raise a :exc:`ValueError` if the length of *altchars* is not 2. -+ .. deprecated:: next -+ Accepting the ``+`` and ``/`` characters with an alternative alphabet -+ is now deprecated. -+ - - .. function:: standard_b64encode(s) - -@@ -123,6 +128,9 @@ - ``/`` in the standard Base64 alphabet, and return the decoded - :class:`bytes`. - -+ .. deprecated:: next -+ Accepting the ``+`` and ``/`` characters is now deprecated. -+ - - .. function:: b32encode(s) - -Index: Python-3.15.0a5/Doc/whatsnew/3.15.rst -=================================================================== ---- Python-3.15.0a5.orig/Doc/whatsnew/3.15.rst 2026-01-14 15:41:32.000000000 +0100 -+++ Python-3.15.0a5/Doc/whatsnew/3.15.rst 2026-02-08 14:34:01.167289075 +0100 -@@ -1143,6 +1143,15 @@ - New deprecations - ---------------- - -+* :mod:`base64`: -+ -+ * Accepting the ``+`` and ``/`` characters with an alternative alphabet in -+ :func:`~base64.b64decode` and :func:`~base64.urlsafe_b64decode` is now -+ deprecated. -+ In future Python versions they will be errors in the strict mode and -+ discarded in the non-strict mode. -+ (Contributed by Serhiy Storchaka in :gh:`125346`.) -+ - * CLI: - - * Deprecate :option:`-b` and :option:`!-bb` command-line options -Index: Python-3.15.0a5/Lib/base64.py -=================================================================== ---- Python-3.15.0a5.orig/Lib/base64.py 2026-02-08 14:31:45.441967463 +0100 -+++ Python-3.15.0a5/Lib/base64.py 2026-02-08 14:34:01.167638994 +0100 -@@ -72,20 +72,39 @@ - The result is returned as a bytes object. A binascii.Error is raised if - s is incorrectly padded. - -- If validate is False (the default), characters that are neither in the -+ If validate is false (the default), characters that are neither in the - normal base-64 alphabet nor the alternative alphabet are discarded prior -- to the padding check. If validate is True, these non-alphabet characters -+ to the padding check. If validate is true, these non-alphabet characters - in the input result in a binascii.Error. - For more information about the strict base64 check, see: - - https://docs.python.org/3.11/library/binascii.html#binascii.a2b_base64 - """ - s = _bytes_from_decode_data(s) -+ badchar = None - if altchars is not None: - altchars = _bytes_from_decode_data(altchars) -- assert len(altchars) == 2, repr(altchars) -+ if len(altchars) != 2: -+ raise ValueError(f'invalid altchars: {altchars!r}') -+ for b in b'+/': -+ if b not in altchars and b in s: -+ badchar = b -+ break - s = s.translate(bytes.maketrans(altchars, b'+/')) -- return binascii.a2b_base64(s, strict_mode=validate) -+ result = binascii.a2b_base64(s, strict_mode=validate) -+ if badchar is not None: -+ import warnings -+ if validate: -+ warnings.warn(f'invalid character {chr(badchar)!a} in Base64 data ' -+ f'with altchars={altchars!r} and validate=True ' -+ f'will be an error in future Python versions', -+ DeprecationWarning, stacklevel=2) -+ else: -+ warnings.warn(f'invalid character {chr(badchar)!a} in Base64 data ' -+ f'with altchars={altchars!r} and validate=False ' -+ f'will be discarded in future Python versions', -+ FutureWarning, stacklevel=2) -+ return result - - - def standard_b64encode(s): -@@ -130,8 +149,19 @@ - The alphabet uses '-' instead of '+' and '_' instead of '/'. - """ - s = _bytes_from_decode_data(s) -+ badchar = None -+ for b in b'+/': -+ if b in s: -+ badchar = b -+ break - s = s.translate(_urlsafe_decode_translation) -- return b64decode(s) -+ result = binascii.a2b_base64(s, strict_mode=False) -+ if badchar is not None: -+ import warnings -+ warnings.warn(f'invalid character {chr(badchar)!a} in URL-safe Base64 data ' -+ f'will be discarded in future Python versions', -+ FutureWarning, stacklevel=2) -+ return result - - - -Index: Python-3.15.0a5/Lib/test/test_base64.py -=================================================================== ---- Python-3.15.0a5.orig/Lib/test/test_base64.py 2026-02-08 14:31:46.996351782 +0100 -+++ Python-3.15.0a5/Lib/test/test_base64.py 2026-02-08 14:34:01.168029250 +0100 -@@ -292,6 +292,25 @@ - eq(base64.b64decode(data, altchars=altchars_str), res) - eq(base64.b64decode(data_str, altchars=altchars_str), res) - -+ def test_b64decode_altchars(self): -+ # Test with arbitrary alternative characters -+ eq = self.assertEqual -+ res = b'\xd3V\xbeo\xf7\x1d' -+ for altchars in b'*$', b'+/', b'/+', b'+_', b'-+', b'-/', b'/_': -+ data = b'01a%cb%ccd' % tuple(altchars) -+ data_str = data.decode('ascii') -+ altchars_str = altchars.decode('ascii') -+ -+ eq(base64.b64decode(data, altchars=altchars), res) -+ eq(base64.b64decode(data_str, altchars=altchars), res) -+ eq(base64.b64decode(data, altchars=altchars_str), res) -+ eq(base64.b64decode(data_str, altchars=altchars_str), res) -+ -+ self.assertRaises(ValueError, base64.b64decode, b'', altchars=b'+') -+ self.assertRaises(ValueError, base64.b64decode, b'', altchars=b'+/-') -+ self.assertRaises(ValueError, base64.b64decode, '', altchars='+') -+ self.assertRaises(ValueError, base64.b64decode, '', altchars='+/-') -+ - def test_b64decode_padding_error(self): - self.assertRaises(binascii.Error, base64.b64decode, b'abc') - self.assertRaises(binascii.Error, base64.b64decode, 'abc') -@@ -323,13 +342,25 @@ - with self.assertRaises(binascii.Error): - base64.b64decode(bstr.decode('ascii'), validate=True) - -- # Normal alphabet characters not discarded when alternative given -- res = b'\xfb\xef\xff' -- self.assertEqual(base64.b64decode(b'++//', validate=True), res) -- self.assertEqual(base64.b64decode(b'++//', '-_', validate=True), res) -- self.assertEqual(base64.b64decode(b'--__', '-_', validate=True), res) -- self.assertEqual(base64.urlsafe_b64decode(b'++//'), res) -- self.assertEqual(base64.urlsafe_b64decode(b'--__'), res) -+ # Normal alphabet characters will be discarded when alternative given -+ with self.assertWarns(FutureWarning): -+ self.assertEqual(base64.b64decode(b'++++', altchars=b'-_'), -+ b'\xfb\xef\xbe') -+ with self.assertWarns(FutureWarning): -+ self.assertEqual(base64.b64decode(b'////', altchars=b'-_'), -+ b'\xff\xff\xff') -+ with self.assertWarns(DeprecationWarning): -+ self.assertEqual(base64.b64decode(b'++++', altchars=b'-_', validate=True), -+ b'\xfb\xef\xbe') -+ with self.assertWarns(DeprecationWarning): -+ self.assertEqual(base64.b64decode(b'////', altchars=b'-_', validate=True), -+ b'\xff\xff\xff') -+ with self.assertWarns(FutureWarning): -+ self.assertEqual(base64.urlsafe_b64decode(b'++++'), b'\xfb\xef\xbe') -+ with self.assertWarns(FutureWarning): -+ self.assertEqual(base64.urlsafe_b64decode(b'////'), b'\xff\xff\xff') -+ with self.assertRaises(binascii.Error): -+ base64.b64decode(b'+/!', altchars=b'-_') - - def _altchars_strategy(): - """Generate 'altchars' for base64 encoding.""" -Index: Python-3.15.0a5/Misc/NEWS.d/next/Library/2025-11-06-12-03-29.gh-issue-125346.7Gfpgw.rst -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ Python-3.15.0a5/Misc/NEWS.d/next/Library/2025-11-06-12-03-29.gh-issue-125346.7Gfpgw.rst 2026-02-08 14:34:01.168413634 +0100 -@@ -0,0 +1,5 @@ -+Accepting ``+`` and ``/`` characters with an alternative alphabet in -+:func:`base64.b64decode` and :func:`base64.urlsafe_b64decode` is now -+deprecated. -+In future Python versions they will be errors in the strict mode and -+discarded in the non-strict mode. diff --git a/CVE-2025-15282-urllib-ctrl-chars.patch b/CVE-2025-15282-urllib-ctrl-chars.patch index 0c723c5..32f6d8b 100644 --- a/CVE-2025-15282-urllib-ctrl-chars.patch +++ b/CVE-2025-15282-urllib-ctrl-chars.patch @@ -4,26 +4,18 @@ Date: Fri, 16 Jan 2026 10:54:09 -0600 Subject: [PATCH 1/2] Add 'test.support' fixture for C0 control characters --- - Lib/test/test_urllib.py | 8 ++++++++ + Lib/test/test_urllib.py | 7 +++++++ Lib/urllib/request.py | 5 +++++ Misc/NEWS.d/next/Security/2026-01-16-11-51-19.gh-issue-143925.mrtcHW.rst | 1 + - 3 files changed, 14 insertions(+) + 3 files changed, 13 insertions(+) -Index: Python-3.15.0a5/Lib/test/test_urllib.py +Index: Python-3.15.0a6/Lib/test/test_urllib.py =================================================================== ---- Python-3.15.0a5.orig/Lib/test/test_urllib.py 2026-02-08 14:31:49.004578010 +0100 -+++ Python-3.15.0a5/Lib/test/test_urllib.py 2026-02-08 14:34:10.667653549 +0100 -@@ -10,6 +10,7 @@ - from test import support - from test.support import os_helper - from test.support import socket_helper -+from test.support import control_characters_c0 - import os - import socket - try: -@@ -590,6 +591,13 @@ - # missing padding character - self.assertRaises(ValueError,urllib.request.urlopen,'data:;base64,Cg=') +--- Python-3.15.0a6.orig/Lib/test/test_urllib.py 2026-02-11 22:31:19.832904633 +0100 ++++ Python-3.15.0a6/Lib/test/test_urllib.py 2026-02-11 22:57:02.393345971 +0100 +@@ -513,6 +513,13 @@ + self.assertFalse(e.exception.filename) + self.assertTrue(e.exception.reason) + def test_invalid_mediatype(self): + for c0 in control_characters_c0(): @@ -33,15 +25,15 @@ Index: Python-3.15.0a5/Lib/test/test_urllib.py + self.assertRaises(ValueError,urllib.request.urlopen, + f'data:text/html{c0};base64,ZGF0YQ==') - class urlretrieve_FileTests(unittest.TestCase): - """Test urllib.urlretrieve() on local files""" -Index: Python-3.15.0a5/Lib/urllib/request.py + class urlopen_DataTests(unittest.TestCase): + """Test urlopen() opening a data URL.""" +Index: Python-3.15.0a6/Lib/urllib/request.py =================================================================== ---- Python-3.15.0a5.orig/Lib/urllib/request.py 2026-02-08 14:31:49.344934070 +0100 -+++ Python-3.15.0a5/Lib/urllib/request.py 2026-02-08 14:34:10.668244681 +0100 -@@ -1636,6 +1636,11 @@ - scheme, data = url.split(":",1) - mediatype, data = data.split(",",1) +--- Python-3.15.0a6.orig/Lib/urllib/request.py 2026-02-11 22:31:20.220618979 +0100 ++++ Python-3.15.0a6/Lib/urllib/request.py 2026-02-11 22:57:02.393916978 +0100 +@@ -1641,6 +1641,11 @@ + raise ValueError( + "Control characters not allowed in data: mediatype") + # Disallow control characters within mediatype. + if re.search(r"[\x00-\x1F\x7F]", mediatype): @@ -51,9 +43,9 @@ Index: Python-3.15.0a5/Lib/urllib/request.py # even base64 encoded data URLs might be quoted so unquote in any case: data = unquote_to_bytes(data) if mediatype.endswith(";base64"): -Index: Python-3.15.0a5/Misc/NEWS.d/next/Security/2026-01-16-11-51-19.gh-issue-143925.mrtcHW.rst +Index: Python-3.15.0a6/Misc/NEWS.d/next/Security/2026-01-16-11-51-19.gh-issue-143925.mrtcHW.rst =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ Python-3.15.0a5/Misc/NEWS.d/next/Security/2026-01-16-11-51-19.gh-issue-143925.mrtcHW.rst 2026-02-08 14:34:10.668611672 +0100 ++++ Python-3.15.0a6/Misc/NEWS.d/next/Security/2026-01-16-11-51-19.gh-issue-143925.mrtcHW.rst 2026-02-11 22:57:02.394304909 +0100 @@ -0,0 +1 @@ +Reject control characters in ``data:`` URL media types. diff --git a/CVE-2025-15366-imap-ctrl-chars.patch b/CVE-2025-15366-imap-ctrl-chars.patch deleted file mode 100644 index 3c1d93b..0000000 --- a/CVE-2025-15366-imap-ctrl-chars.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 7485ee5e2cf81d3e5ad0d9c3be73cecd2ab4eec7 Mon Sep 17 00:00:00 2001 -From: Seth Michael Larson -Date: Fri, 16 Jan 2026 10:54:09 -0600 -Subject: [PATCH 1/2] Add 'test.support' fixture for C0 control characters - ---- - Lib/imaplib.py | 4 +++- - Lib/test/test_imaplib.py | 6 ++++++ - Misc/NEWS.d/next/Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst | 1 + - 3 files changed, 10 insertions(+), 1 deletion(-) - -Index: Python-3.15.0a3/Lib/imaplib.py -=================================================================== ---- Python-3.15.0a3.orig/Lib/imaplib.py 2026-02-04 10:33:17.226345322 +0100 -+++ Python-3.15.0a3/Lib/imaplib.py 2026-02-04 10:33:45.757970971 +0100 -@@ -129,7 +129,7 @@ - # We compile these in _mode_xxx. - _Literal = br'.*{(?P\d+)}$' - _Untagged_status = br'\* (?P\d+) (?P[A-Z-]+)( (?P.*))?' -- -+_control_chars = re.compile(b'[\x00-\x1F\x7F]') - - - class IMAP4: -@@ -1105,6 +1105,8 @@ - if arg is None: continue - if isinstance(arg, str): - arg = bytes(arg, self._encoding) -+ if _control_chars.search(arg): -+ raise ValueError("Control characters not allowed in commands") - data = data + b' ' + arg - - literal = self.literal -Index: Python-3.15.0a3/Lib/test/test_imaplib.py -=================================================================== ---- Python-3.15.0a3.orig/Lib/test/test_imaplib.py 2026-02-04 10:33:18.559328359 +0100 -+++ Python-3.15.0a3/Lib/test/test_imaplib.py 2026-02-04 10:33:45.758227151 +0100 -@@ -657,6 +657,12 @@ - self.assertEqual(data[0], b'Returned to authenticated state. (Success)') - self.assertEqual(client.state, 'AUTH') - -+ def test_control_characters(self): -+ client, _ = self._setup(SimpleIMAPHandler) -+ for c0 in support.control_characters_c0(): -+ with self.assertRaises(ValueError): -+ client.login(f'user{c0}', 'pass') -+ - # property tests - - def test_file_property_should_not_be_accessed(self): -Index: Python-3.15.0a3/Misc/NEWS.d/next/Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ Python-3.15.0a3/Misc/NEWS.d/next/Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst 2026-02-04 10:33:45.758408531 +0100 -@@ -0,0 +1 @@ -+Reject control characters in IMAP commands. diff --git a/CVE-2025-15367-poplib-ctrl-chars.patch b/CVE-2025-15367-poplib-ctrl-chars.patch deleted file mode 100644 index f96a86b..0000000 --- a/CVE-2025-15367-poplib-ctrl-chars.patch +++ /dev/null @@ -1,56 +0,0 @@ -From b6f733b285b1c4f27dacb5c2e1f292c914e8b933 Mon Sep 17 00:00:00 2001 -From: Seth Michael Larson -Date: Fri, 16 Jan 2026 10:54:09 -0600 -Subject: [PATCH 1/2] Add 'test.support' fixture for C0 control characters - ---- - Lib/poplib.py | 2 ++ - Lib/test/test_poplib.py | 8 ++++++++ - Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst | 1 + - 3 files changed, 11 insertions(+) - -Index: Python-3.15.0a3/Lib/poplib.py -=================================================================== ---- Python-3.15.0a3.orig/Lib/poplib.py 2026-02-04 20:53:38.757990472 +0100 -+++ Python-3.15.0a3/Lib/poplib.py 2026-02-04 20:53:46.764343586 +0100 -@@ -122,6 +122,8 @@ - def _putcmd(self, line): - if self._debugging: print('*cmd*', repr(line)) - line = bytes(line, self.encoding) -+ if re.search(b'[\x00-\x1F\x7F]', line): -+ raise ValueError('Control characters not allowed in commands') - self._putline(line) - - -Index: Python-3.15.0a3/Lib/test/test_poplib.py -=================================================================== ---- Python-3.15.0a3.orig/Lib/test/test_poplib.py 2026-02-04 20:53:40.553673802 +0100 -+++ Python-3.15.0a3/Lib/test/test_poplib.py 2026-02-04 20:53:46.764523568 +0100 -@@ -17,6 +17,7 @@ - from test.support import threading_helper - from test.support import asynchat - from test.support import asyncore -+from test.support import control_characters_c0 - - - test_support.requires_working_socket(module=True) -@@ -395,6 +396,13 @@ - self.assertIsNone(self.client.sock) - self.assertIsNone(self.client.file) - -+ def test_control_characters(self): -+ for c0 in control_characters_c0(): -+ with self.assertRaises(ValueError): -+ self.client.user(f'user{c0}') -+ with self.assertRaises(ValueError): -+ self.client.pass_(f'{c0}pass') -+ - @requires_ssl - def test_stls_capa(self): - capa = self.client.capa() -Index: Python-3.15.0a3/Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ Python-3.15.0a3/Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst 2026-02-04 20:53:46.764674776 +0100 -@@ -0,0 +1 @@ -+Reject control characters in POP3 commands. diff --git a/CVE-2026-0672-http-hdr-inject-cookie-Morsel.patch b/CVE-2026-0672-http-hdr-inject-cookie-Morsel.patch deleted file mode 100644 index bdcd2a1..0000000 --- a/CVE-2026-0672-http-hdr-inject-cookie-Morsel.patch +++ /dev/null @@ -1,191 +0,0 @@ -From ef01008e47a7741808ab223087a458f33e4dd922 Mon Sep 17 00:00:00 2001 -From: Seth Michael Larson -Date: Fri, 16 Jan 2026 10:54:09 -0600 -Subject: [PATCH 1/5] Add 'test.support' fixture for C0 control characters - ---- - Doc/library/http.cookies.rst | 4 - Lib/http/cookies.py | 25 ++++ - Lib/test/support/__init__.py | 7 + - Lib/test/test_http_cookies.py | 52 +++++++++- - Misc/NEWS.d/next/Security/2026-01-16-11-13-15.gh-issue-143919.kchwZV.rst | 1 - 5 files changed, 80 insertions(+), 9 deletions(-) - -Index: Python-3.15.0a5/Doc/library/http.cookies.rst -=================================================================== ---- Python-3.15.0a5.orig/Doc/library/http.cookies.rst 2026-01-14 15:41:32.000000000 +0100 -+++ Python-3.15.0a5/Doc/library/http.cookies.rst 2026-02-08 14:33:55.253456803 +0100 -@@ -294,9 +294,9 @@ - Set-Cookie: chips=ahoy - Set-Cookie: vienna=finger - >>> C = cookies.SimpleCookie() -- >>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=\\012;";') -+ >>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=;";') - >>> print(C) -- Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=\012;" -+ Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=;" - >>> C = cookies.SimpleCookie() - >>> C["oreo"] = "doublestuff" - >>> C["oreo"]["path"] = "/" -Index: Python-3.15.0a5/Lib/http/cookies.py -=================================================================== ---- Python-3.15.0a5.orig/Lib/http/cookies.py 2026-02-08 14:31:45.957689947 +0100 -+++ Python-3.15.0a5/Lib/http/cookies.py 2026-02-08 14:33:55.254433224 +0100 -@@ -87,9 +87,9 @@ - such trickeries do not confuse it. - - >>> C = cookies.SimpleCookie() -- >>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=\\012;";') -+ >>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=;";') - >>> print(C) -- Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=\012;" -+ Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=;" - - Each element of the Cookie also supports all of the RFC 2109 - Cookie attributes. Here's an example which sets the Path -@@ -170,6 +170,15 @@ - }) - - _is_legal_key = re.compile('[%s]+' % re.escape(_LegalChars)).fullmatch -+_control_character_re = re.compile(r'[\x00-\x1F\x7F]') -+ -+ -+def _has_control_character(*val): -+ """Detects control characters within a value. -+ Supports any type, as header values can be any type. -+ """ -+ return any(_control_character_re.search(str(v)) for v in val) -+ - - def _quote(str): - r"""Quote a string for use in a cookie header. -@@ -294,12 +303,16 @@ - K = K.lower() - if not K in self._reserved: - raise CookieError("Invalid attribute %r" % (K,)) -+ if _has_control_character(K, V): -+ raise CookieError(f"Control characters are not allowed in cookies {K!r} {V!r}") - dict.__setitem__(self, K, V) - - def setdefault(self, key, val=None): - key = key.lower() - if key not in self._reserved: - raise CookieError("Invalid attribute %r" % (key,)) -+ if _has_control_character(key, val): -+ raise CookieError("Control characters are not allowed in cookies %r %r" % (key, val,)) - return dict.setdefault(self, key, val) - - def __eq__(self, morsel): -@@ -335,6 +348,9 @@ - raise CookieError('Attempt to set a reserved key %r' % (key,)) - if not _is_legal_key(key): - raise CookieError('Illegal key %r' % (key,)) -+ if _has_control_character(key, val, coded_val): -+ raise CookieError( -+ "Control characters are not allowed in cookies %r %r %r" % (key, val, coded_val,)) - - # It's a good key, so save it. - self._key = key -@@ -488,7 +504,10 @@ - result = [] - items = sorted(self.items()) - for key, value in items: -- result.append(value.output(attrs, header)) -+ value_output = value.output(attrs, header) -+ if _has_control_character(value_output): -+ raise CookieError("Control characters are not allowed in cookies") -+ result.append(value_output) - return sep.join(result) - - __str__ = output -Index: Python-3.15.0a5/Lib/test/support/__init__.py -=================================================================== ---- Python-3.15.0a5.orig/Lib/test/support/__init__.py 2026-02-08 14:31:46.798817229 +0100 -+++ Python-3.15.0a5/Lib/test/support/__init__.py 2026-02-08 14:33:55.255194468 +0100 -@@ -3303,3 +3303,10 @@ - return _linked_to_musl - _linked_to_musl = tuple(map(int, version.split('.'))) - return _linked_to_musl -+ -+ -+def control_characters_c0() -> list[str]: -+ """Returns a list of C0 control characters as strings. -+ C0 control characters defined as the byte range 0x00-0x1F, and 0x7F. -+ """ -+ return [chr(c) for c in range(0x00, 0x20)] + ["\x7F"] -Index: Python-3.15.0a5/Lib/test/test_http_cookies.py -=================================================================== ---- Python-3.15.0a5.orig/Lib/test/test_http_cookies.py 2026-02-08 14:31:47.771034298 +0100 -+++ Python-3.15.0a5/Lib/test/test_http_cookies.py 2026-02-08 14:33:55.255867707 +0100 -@@ -17,10 +17,10 @@ - 'repr': "", - 'output': 'Set-Cookie: chips=ahoy\nSet-Cookie: vienna=finger'}, - -- {'data': 'keebler="E=mc2; L=\\"Loves\\"; fudge=\\012;"', -- 'dict': {'keebler' : 'E=mc2; L="Loves"; fudge=\012;'}, -- 'repr': '''''', -- 'output': 'Set-Cookie: keebler="E=mc2; L=\\"Loves\\"; fudge=\\012;"'}, -+ {'data': 'keebler="E=mc2; L=\\"Loves\\"; fudge=;"', -+ 'dict': {'keebler' : 'E=mc2; L="Loves"; fudge=;'}, -+ 'repr': '''''', -+ 'output': 'Set-Cookie: keebler="E=mc2; L=\\"Loves\\"; fudge=;"'}, - - # Check illegal cookies that have an '=' char in an unquoted value - {'data': 'keebler=E=mc2', -@@ -594,6 +594,50 @@ - r'Set-Cookie: key=coded_val; ' - r'expires=\w+, \d+ \w+ \d+ \d+:\d+:\d+ \w+') - -+ def test_control_characters(self): -+ for c0 in support.control_characters_c0(): -+ morsel = cookies.Morsel() -+ -+ # .__setitem__() -+ with self.assertRaises(cookies.CookieError): -+ morsel[c0] = "val" -+ with self.assertRaises(cookies.CookieError): -+ morsel["path"] = c0 -+ -+ # .setdefault() -+ with self.assertRaises(cookies.CookieError): -+ morsel.setdefault("path", c0) -+ with self.assertRaises(cookies.CookieError): -+ morsel.setdefault(c0, "val") -+ -+ # .set() -+ with self.assertRaises(cookies.CookieError): -+ morsel.set(c0, "val", "coded-value") -+ with self.assertRaises(cookies.CookieError): -+ morsel.set("path", c0, "coded-value") -+ with self.assertRaises(cookies.CookieError): -+ morsel.set("path", "val", c0) -+ -+ def test_control_characters_output(self): -+ # Tests that even if the internals of Morsel are modified -+ # that a call to .output() has control character safeguards. -+ for c0 in support.control_characters_c0(): -+ morsel = cookies.Morsel() -+ morsel.set("key", "value", "coded-value") -+ morsel._key = c0 # Override private variable. -+ cookie = cookies.SimpleCookie() -+ cookie["cookie"] = morsel -+ with self.assertRaises(cookies.CookieError): -+ cookie.output() -+ -+ morsel = cookies.Morsel() -+ morsel.set("key", "value", "coded-value") -+ morsel._coded_value = c0 # Override private variable. -+ cookie = cookies.SimpleCookie() -+ cookie["cookie"] = morsel -+ with self.assertRaises(cookies.CookieError): -+ cookie.output() -+ - - def load_tests(loader, tests, pattern): - tests.addTest(doctest.DocTestSuite(cookies)) -Index: Python-3.15.0a5/Misc/NEWS.d/next/Security/2026-01-16-11-13-15.gh-issue-143919.kchwZV.rst -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ Python-3.15.0a5/Misc/NEWS.d/next/Security/2026-01-16-11-13-15.gh-issue-143919.kchwZV.rst 2026-02-08 14:33:55.256114682 +0100 -@@ -0,0 +1 @@ -+Reject control characters in :class:`http.cookies.Morsel` fields and values. diff --git a/CVE-2026-0865-wsgiref-ctrl-chars.patch b/CVE-2026-0865-wsgiref-ctrl-chars.patch deleted file mode 100644 index ec419c2..0000000 --- a/CVE-2026-0865-wsgiref-ctrl-chars.patch +++ /dev/null @@ -1,68 +0,0 @@ -From e7f180b4c21576f52c08933a184d84dc4b47e00e Mon Sep 17 00:00:00 2001 -From: Seth Michael Larson -Date: Fri, 16 Jan 2026 10:54:09 -0600 -Subject: [PATCH 1/2] Add 'test.support' fixture for C0 control characters - ---- - Lib/test/test_wsgiref.py | 12 +++++++++- - Lib/wsgiref/headers.py | 3 ++ - Misc/NEWS.d/next/Security/2026-01-16-11-07-36.gh-issue-143916.dpWeOD.rst | 2 + - 3 files changed, 16 insertions(+), 1 deletion(-) - -Index: Python-3.15.0a3/Lib/test/test_wsgiref.py -=================================================================== ---- Python-3.15.0a3.orig/Lib/test/test_wsgiref.py 2026-02-04 01:52:45.393433768 +0100 -+++ Python-3.15.0a3/Lib/test/test_wsgiref.py 2026-02-04 01:52:52.928458181 +0100 -@@ -1,6 +1,6 @@ - from unittest import mock - from test import support --from test.support import socket_helper -+from test.support import socket_helper, control_characters_c0 - from test.test_httpservers import NoLogRequestHandler - from unittest import TestCase - from wsgiref.util import setup_testing_defaults -@@ -503,6 +503,16 @@ - '\r\n' - ) - -+ def testRaisesControlCharacters(self): -+ headers = Headers() -+ for c0 in control_characters_c0(): -+ self.assertRaises(ValueError, headers.__setitem__, f"key{c0}", "val") -+ self.assertRaises(ValueError, headers.__setitem__, "key", f"val{c0}") -+ self.assertRaises(ValueError, headers.add_header, f"key{c0}", "val", param="param") -+ self.assertRaises(ValueError, headers.add_header, "key", f"val{c0}", param="param") -+ self.assertRaises(ValueError, headers.add_header, "key", "val", param=f"param{c0}") -+ -+ - class ErrorHandler(BaseCGIHandler): - """Simple handler subclass for testing BaseHandler""" - -Index: Python-3.15.0a3/Lib/wsgiref/headers.py -=================================================================== ---- Python-3.15.0a3.orig/Lib/wsgiref/headers.py 2026-02-04 01:52:45.666384529 +0100 -+++ Python-3.15.0a3/Lib/wsgiref/headers.py 2026-02-04 01:52:52.928606420 +0100 -@@ -9,6 +9,7 @@ - # existence of which force quoting of the parameter value. - import re - tspecials = re.compile(r'[ \(\)<>@,;:\\"/\[\]\?=]') -+_control_chars_re = re.compile(r'[\x00-\x1F\x7F]') - - def _formatparam(param, value=None, quote=1): - """Convenience function to format and return a key=value pair. -@@ -41,6 +42,8 @@ - def _convert_string_type(self, value): - """Convert/check value type.""" - if type(value) is str: -+ if _control_chars_re.search(value): -+ raise ValueError("Control characters not allowed in headers") - return value - raise AssertionError("Header names/values must be" - " of type str (got {0})".format(repr(value))) -Index: Python-3.15.0a3/Misc/NEWS.d/next/Security/2026-01-16-11-07-36.gh-issue-143916.dpWeOD.rst -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ Python-3.15.0a3/Misc/NEWS.d/next/Security/2026-01-16-11-07-36.gh-issue-143916.dpWeOD.rst 2026-02-04 01:52:52.928707130 +0100 -@@ -0,0 +1,2 @@ -+Reject C0 control characters within wsgiref.headers.Headers fields, values, -+and parameters. diff --git a/Python-3.15.0a5.tar.xz b/Python-3.15.0a5.tar.xz deleted file mode 100644 index dec3912..0000000 --- a/Python-3.15.0a5.tar.xz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fee40da6450b67547c079dcb2852e8a03db6d57e06415466b2d3294449db22ef -size 34829268 diff --git a/Python-3.15.0a5.tar.xz.sigstore b/Python-3.15.0a5.tar.xz.sigstore deleted file mode 100644 index 70d84d7..0000000 --- a/Python-3.15.0a5.tar.xz.sigstore +++ /dev/null @@ -1 +0,0 @@ -{"mediaType": "application/vnd.dev.sigstore.bundle.v0.3+json", "verificationMaterial": {"certificate": {"rawBytes": "MIICzjCCAlSgAwIBAgIUNydHzA8NuStXPHYfFtZbUO/FE/wwCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjYwMTE0MTczMTIzWhcNMjYwMTE0MTc0MTIzWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEtFxtwtbzhueHbwhLZa6tv+X63uNEvvbefKOCviZrgCW1m3h+8mkS1uh8ORC25lQgK73+P/VMr4k3he1AVFfzi6OCAXMwggFvMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQU5T673oJkZCMB6O11SKvJ9RPbFLwwHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wHQYDVR0RAQH/BBMwEYEPaHVnb0BweXRob24ub3JnMCwGCisGAQQBg78wAQEEHmh0dHBzOi8vZ2l0aHViLmNvbS9sb2dpbi9vYXV0aDAuBgorBgEEAYO/MAEIBCAMHmh0dHBzOi8vZ2l0aHViLmNvbS9sb2dpbi9vYXV0aDCBigYKKwYBBAHWeQIEAgR8BHoAeAB2AN09MGrGxxEyYxkeHJlnNwKiSl643jyt/4eKcoAvKe6OAAABm72P500AAAQDAEcwRQIhALw4Whh9h50mPAu48QCxBvQcqEB/b8G3vBE30hEjBKMfAiBYr9v+ajMTxRSpa3Xt6K8dmmLS5BcUzrPWOv9nONjPoTAKBggqhkjOPQQDAwNoADBlAjEA8Vig7Ev7um4rc1zUEwCsRvE/Li98T70rLMwxgZ4LUZ60yw9zRzOXaQ3HGAk+R5/3AjBq4Nl7Zz3HNdJuZZtPPjUpYan7jFBs4TvX6/1Eidl5P4JFvk95THfkWOhmlXuUqQY="}, "tlogEntries": [{"logIndex": "821799310", "logId": {"keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="}, "kindVersion": {"kind": "hashedrekord", "version": "0.0.1"}, "integratedTime": "1768411883", "inclusionPromise": {"signedEntryTimestamp": "MEYCIQDmSC4cCWW1mbjsg/BwMeTXrJ2dVR3Ur6EAM19DmOJbIAIhAIiYV024cQbxs58MjNVUt9Oxg/BiwkPccSZduuAOM0dN"}, "inclusionProof": {"logIndex": "699895048", "rootHash": "r0u4eImXX/q/6JGKmwD7yKfaj3MGgiQ4BQCtTc3iSbY=", "treeSize": "699895073", "hashes": ["d4QxwkQxm1ZuvCwbT6+m1xD9lPRM/qHH9jHRsxmtqzA=", "0qzZMMseSqLUaEhVwKJpPootPDog54psnSFu6dbXEZs=", "xN2ZJUm8O1loc0UQed+ADkAdcKmsox9APOMiBEfTGAM=", "I3HYsO47xZGMgQHeaFRUFwgJu70BtATO71B5wD7bbbI=", "WC2EQiEd27rwG/IoGRH/DYgKSBT7FN8S49aiBhFSpCU=", "9KduzXbjWNMO9DoybnjVj706C82sIlozxGxIILmSJF4=", "iuMU09Wl1Xs26PCP+3OerATC2/2dPZfLsTigUGR99K8=", "taftcJBIOZWhfeXDqEjXL8vBSY2OBYKB+KYBI7Z7z/U=", "tYVuNS2lJsS2mhGPLFZfkXSsayd+wARHACMvU9WwxJs=", "Rwdu5EmklN0Fe3v6L3jQCHCmFH/tiD9eg6Al/EcltSo=", "PXObE0woFoIqkyQKsgq1oHokE/hR4eDZmGPg16eAghA=", "CenHn7nf8L82Fm9P6PVG7lG5Y1+Wv8S/YBmQ7wDupYc=", "onJvFRaPQoYZ/9t6reYnUemdJzG6s8v1qMrxyVTYbQs=", "OF30SIPB0jF4SbsZGV5gH3NC9Br3sWvdaNlSjfHZq+c=", "uixTjY7pYOJF0tNUl1m1bWtkzaemNOzxQBsfI5xU8Aw=", "o8NA5tG30D0SaRZq1Bibcm3MllrwYNV8h6/lk4h6HLA=", "QNOCa/MdLF4/Y/DKU/ooSDjdTKqdDNpm5oSFffy3ExE=", "F9MSQ5SmoFr+hoADclpdFY52/TLfHDnNPYb9ZNYO5gI=", "T4DqWD42hAtN+vX8jKCWqoC4meE4JekI9LxYGCcPy1M="], "checkpoint": {"envelope": "rekor.sigstore.dev - 1193050959916656506\n699895073\nr0u4eImXX/q/6JGKmwD7yKfaj3MGgiQ4BQCtTc3iSbY=\n\n\u2014 rekor.sigstore.dev wNI9ajBFAiAucj7zBN+dhxi2/xL1+Sj5iK5FSfY/uO+kW+VQ2te65gIhAJBu6HxJBS3imKFNQjPUTxJjcoWWPsHuF1DouJJ/gtBN\n"}}, "canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiJmZWU0MGRhNjQ1MGI2NzU0N2MwNzlkY2IyODUyZThhMDNkYjZkNTdlMDY0MTU0NjZiMmQzMjk0NDQ5ZGIyMmVmIn19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FWUNJUUN2M0hXVlhYZDNVSWxoLzhmUDRIeVZodW5DNkpVSHUxMTVwZndKQXAwOXh3SWhBSlFyYVdmNFN6eVFoVFl2RU94TFNVUzJiYTQ0Tkk3M0I1VW40SUR5cHo3LyIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVTjZha05EUVd4VFowRjNTVUpCWjBsVlRubGtTSHBCT0U1MVUzUllVRWhaWmtaMFdtSlZUeTlHUlM5M2QwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcFpkMDFVUlRCTlZHTjZUVlJKZWxkb1kwNU5hbGwzVFZSRk1FMVVZekJOVkVsNlYycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVYwUm5oMGQzUmllbWgxWlVoaWQyaE1XbUUyZEhZcldEWXpkVTVGZG5aaVpXWkxUME1LZG1sYWNtZERWekZ0TTJnck9HMXJVekYxYURoUFVrTXlOV3hSWjBzM015dFFMMVpOY2pSck0yaGxNVUZXUm1aNmFUWlBRMEZZVFhkblowWjJUVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXUkNaMDVXU0ZFMFJVWm5VVlUxVkRZM0NqTnZTbXRhUTAxQ05rOHhNVk5MZGtvNVVsQmlSa3gzZDBoM1dVUldVakJxUWtKbmQwWnZRVlV6T1ZCd2VqRlphMFZhWWpWeFRtcHdTMFpYYVhocE5Ga0tXa1E0ZDBoUldVUldVakJTUVZGSUwwSkNUWGRGV1VWUVlVaFdibUl3UW5kbFdGSnZZakkwZFdJelNtNU5RM2RIUTJselIwRlJVVUpuTnpoM1FWRkZSUXBJYldnd1pFaENlazlwT0haYU1td3dZVWhXYVV4dFRuWmlVemx6WWpKa2NHSnBPWFpaV0ZZd1lVUkJkVUpuYjNKQ1owVkZRVmxQTDAxQlJVbENRMEZOQ2todGFEQmtTRUo2VDJrNGRsb3liREJoU0ZacFRHMU9kbUpUT1hOaU1tUndZbWs1ZGxsWVZqQmhSRU5DYVdkWlMwdDNXVUpDUVVoWFpWRkpSVUZuVWpnS1FraHZRV1ZCUWpKQlRqQTVUVWR5UjNoNFJYbFplR3RsU0Vwc2JrNTNTMmxUYkRZME0ycDVkQzgwWlV0amIwRjJTMlUyVDBGQlFVSnROekpRTlRBd1FRcEJRVkZFUVVWamQxSlJTV2hCVEhjMFYyaG9PV2cxTUcxUVFYVTBPRkZEZUVKMlVXTnhSVUl2WWpoSE0zWkNSVE13YUVWcVFrdE5aa0ZwUWxseU9YWXJDbUZxVFZSNFVsTndZVE5ZZERaTE9HUnRiVXhUTlVKalZYcHlVRmRQZGpsdVQwNXFVRzlVUVV0Q1oyZHhhR3RxVDFCUlVVUkJkMDV2UVVSQ2JFRnFSVUVLT0ZacFp6ZEZkamQxYlRSeVl6RjZWVVYzUTNOU2RrVXZUR2s1T0ZRM01ISk1UWGQ0WjFvMFRGVmFOakI1ZHpsNlVucFBXR0ZSTTBoSFFXc3JValV2TXdwQmFrSnhORTVzTjFwNk0waE9aRXAxV2xwMFVGQnFWWEJaWVc0M2FrWkNjelJVZGxnMkx6RkZhV1JzTlZBMFNrWjJhemsxVkVobWExZFBhRzFzV0hWVkNuRlJXVDBLTFMwdExTMUZUa1FnUTBWU1ZFbEdTVU5CVkVVdExTMHRMUW89In19fX0="}], "timestampVerificationData": {}}, "messageSignature": {"messageDigest": {"algorithm": "SHA2_256", "digest": "/uQNpkULZ1R8B53LKFLooD221X4GQVRmstMpREnbIu8="}, "signature": "MEYCIQCv3HWVXXd3UIlh/8fP4HyVhunC6JUHu115pfwJAp09xwIhAJQraWf4SzyQhTYvEOxLSUS2ba44NI73B5Un4IDypz7/"}} diff --git a/Python-3.15.0a6.tar.xz b/Python-3.15.0a6.tar.xz new file mode 100644 index 0000000..398ee6a --- /dev/null +++ b/Python-3.15.0a6.tar.xz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e2a4e1b2afb93a84d659d431b1f384544b3da00a4b8ff5bf3580f07ad4ff989 +size 34950024 diff --git a/Python-3.15.0a6.tar.xz.sigstore b/Python-3.15.0a6.tar.xz.sigstore new file mode 100644 index 0000000..1761cf0 --- /dev/null +++ b/Python-3.15.0a6.tar.xz.sigstore @@ -0,0 +1 @@ +{"mediaType": "application/vnd.dev.sigstore.bundle.v0.3+json", "verificationMaterial": {"certificate": {"rawBytes": "MIICzzCCAlWgAwIBAgIUM4E9f31J8D05rxmEes5C4ZtVGrcwCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjYwMjExMTUzNTUxWhcNMjYwMjExMTU0NTUxWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE0gRzggG+at5kfEhimphXQslOlWolDRjH+23hy9Wg2+3z8X2bYyFjjCvtiIHUOgnatkyTA1OvrE+eQzZr42dGQqOCAXQwggFwMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUBtDi138i+mGbHcAxWp/jjbc1EZMwHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wHQYDVR0RAQH/BBMwEYEPaHVnb0BweXRob24ub3JnMCwGCisGAQQBg78wAQEEHmh0dHBzOi8vZ2l0aHViLmNvbS9sb2dpbi9vYXV0aDAuBgorBgEEAYO/MAEIBCAMHmh0dHBzOi8vZ2l0aHViLmNvbS9sb2dpbi9vYXV0aDCBiwYKKwYBBAHWeQIEAgR9BHsAeQB3AN09MGrGxxEyYxkeHJlnNwKiSl643jyt/4eKcoAvKe6OAAABnE1YMvsAAAQDAEgwRgIhAIQIRCC0X5drUPC+pwC1LdZqVP+EzawveI3Ye4Y1Z0xrAiEAz6yycV2DXDY0JjvIS87ACRhwH8qa6c3SsBoD3x9i4kkwCgYIKoZIzj0EAwMDaAAwZQIxAOu3MUJ1vH9WDyzJ7A3Zcp/MXWfsPFeyoZUUPqzLqlPLVGSXoqSad2+A6ve9JVQh2gIwTPKFPdVl19/g2SZLKbC/fFUyAv4wNZg3g9PS/2nXf2Nqj3K+1ySVAjyPDtoxzATX"}, "tlogEntries": [{"logIndex": "940931233", "logId": {"keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="}, "kindVersion": {"kind": "hashedrekord", "version": "0.0.1"}, "integratedTime": "1770824152", "inclusionPromise": {"signedEntryTimestamp": "MEUCIH8S9gegPihVW+E3mLSEFK4WfDgEQ/6SnOY/U/kIg/uIAiEArXt97zUCofrbPkPrcJetUupsK3dLPCnJkSpU8wEZYvM="}, "inclusionProof": {"logIndex": "819026971", "rootHash": "M8j94C6UX7/oy0ZlmGSulZsLUsWnkWxqJ2ikG5/2Xhk=", "treeSize": "819026987", "hashes": ["fTy5RiTKQa+9P0Ocm5CJp8nZuHHDx2JDv15Nr8kjc3o=", "SbTBDriq6YXMOt7/ATsf46OWq4ROsLyC4etCQCrfrXk=", "z9UzgKi/lXCO0Q5r/wD+g2x6n646UnBh7TWUKmnnjGA=", "uvJRSj+Q957RjvYcTDIs8y3gALOHkyfrLMPvooU9EQ8=", "2ZHJFeTKgkDiMnEjnT4cFobAl0O0MtLbWJSREXOMP6g=", "/epY3FSzqliqSt7cXQi0D2xjWM4dZkMg+q5/jGfSZK8=", "B98jgUauyFGa8ubG1Dg+5Xi5Cj2do+hsd3QSONuPK8s=", "Qe9iKvDT/XpBqxm/pWmhGuMLktq2npILWRcVRUQ+tvs=", "mVdOAh+BjqIKkr4eTrpxPm1g2XF3Qof6LzAyxIEQ1/k=", "jxPmIRawk9pgID3Djibht+hApWQ67ObzEGVgpgysUt4=", "YMMNiuhCccadLU83/s5zqFrSYfVMTHd1P+axcpuHGSw=", "Bj7QWk/N0hyTN7trCCM8EWSQ6uznKaTCQYIRS9Nhr9E=", "nJFkltrYorA3pbdEp3EAqaE8c78OAa+UyI4VGPJZRuI=", "LXrDK2LAS1TD+XldaquvnWdZsSlzyZSkeb3An58rP2Q=", "fLAvE46NqCVV86EpB2pKkwJlFjjFk7ntX3lC+PiZuIo=", "T4DqWD42hAtN+vX8jKCWqoC4meE4JekI9LxYGCcPy1M="], "checkpoint": {"envelope": "rekor.sigstore.dev - 1193050959916656506\n819026987\nM8j94C6UX7/oy0ZlmGSulZsLUsWnkWxqJ2ikG5/2Xhk=\n\n\u2014 rekor.sigstore.dev wNI9ajBGAiEAqGLNpw4rM5WQsxzgTkxz0a1DFNaK/kfBAGDzyoguztcCIQCYSuZZ/OLOb/sJbSj7vr7hi2fc73fqIvGstX7vsF1XGw==\n"}}, "canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI4ZTJhNGUxYjJhZmI5M2E4NGQ2NTlkNDMxYjFmMzg0NTQ0YjNkYTAwYTRiOGZmNWJmMzU4MGYwN2FkNGZmOTg5In19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FUUNJQWx5SW1ndFhXVC93VVliQ21XM2FTQXB5dGV1MzRjTVg2dEQ0eUZPUklkaEFpQXlMbmVtSk81ZDRJSkR4Y3ZWeEVuUkFuTDZqOThXQ2V4VGFaSzdzZkpWR1E9PSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVTjZla05EUVd4WFowRjNTVUpCWjBsVlRUUkZPV1l6TVVvNFJEQTFjbmh0UldWek5VTTBXblJXUjNKamQwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcFpkMDFxUlhoTlZGVjZUbFJWZUZkb1kwNU5hbGwzVFdwRmVFMVVWVEJPVkZWNFYycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVV3WjFKNloyZEhLMkYwTld0bVJXaHBiWEJvV0ZGemJFOXNWMjlzUkZKcVNDc3lNMmdLZVRsWFp6SXJNM280V0RKaVdYbEdhbXBEZG5ScFNVaFZUMmR1WVhScmVWUkJNVTkyY2tVclpWRjZXbkkwTW1SSFVYRlBRMEZZVVhkblowWjNUVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXUkNaMDVXU0ZFMFJVWm5VVlZDZEVScENqRXpPR2tyYlVkaVNHTkJlRmR3TDJwcVltTXhSVnBOZDBoM1dVUldVakJxUWtKbmQwWnZRVlV6T1ZCd2VqRlphMFZhWWpWeFRtcHdTMFpYYVhocE5Ga0tXa1E0ZDBoUldVUldVakJTUVZGSUwwSkNUWGRGV1VWUVlVaFdibUl3UW5kbFdGSnZZakkwZFdJelNtNU5RM2RIUTJselIwRlJVVUpuTnpoM1FWRkZSUXBJYldnd1pFaENlazlwT0haYU1td3dZVWhXYVV4dFRuWmlVemx6WWpKa2NHSnBPWFpaV0ZZd1lVUkJkVUpuYjNKQ1owVkZRVmxQTDAxQlJVbENRMEZOQ2todGFEQmtTRUo2VDJrNGRsb3liREJoU0ZacFRHMU9kbUpUT1hOaU1tUndZbWs1ZGxsWVZqQmhSRU5DYVhkWlMwdDNXVUpDUVVoWFpWRkpSVUZuVWprS1FraHpRV1ZSUWpOQlRqQTVUVWR5UjNoNFJYbFplR3RsU0Vwc2JrNTNTMmxUYkRZME0ycDVkQzgwWlV0amIwRjJTMlUyVDBGQlFVSnVSVEZaVFhaelFRcEJRVkZFUVVWbmQxSm5TV2hCU1ZGSlVrTkRNRmcxWkhKVlVFTXJjSGRETVV4a1duRldVQ3RGZW1GM2RtVkpNMWxsTkZreFdqQjRja0ZwUlVGNk5ubDVDbU5XTWtSWVJGa3dTbXAyU1ZNNE4wRkRVbWgzU0RoeFlUWmpNMU56UW05RU0zZzVhVFJyYTNkRFoxbEpTMjlhU1hwcU1FVkJkMDFFWVVGQmQxcFJTWGdLUVU5MU0wMVZTakYyU0RsWFJIbDZTamRCTTFwamNDOU5XRmRtYzFCR1pYbHZXbFZWVUhGNlRIRnNVRXhXUjFOWWIzRlRZV1F5SzBFMmRtVTVTbFpSYUFveVowbDNWRkJMUmxCa1Ztd3hPUzluTWxOYVRFdGlReTltUmxWNVFYWTBkMDVhWnpObk9WQlRMekp1V0dZeVRuRnFNMHNyTVhsVFZrRnFlVkJFZEc5NENucEJWRmdLTFMwdExTMUZUa1FnUTBWU1ZFbEdTVU5CVkVVdExTMHRMUW89In19fX0="}], "timestampVerificationData": {}}, "messageSignature": {"messageDigest": {"algorithm": "SHA2_256", "digest": "jipOGyr7k6hNZZ1DGx84RUSz2gCkuP9b81gPB61P+Yk="}, "signature": "MEQCIAlyImgtXWT/wUYbCmW3aSApyteu34cMX6tD4yFORIdhAiAyLnemJO5d4IJDxcvVxEnRAnL6j98WCexTaZK7sfJVGQ=="}} diff --git a/bpo-31046_ensurepip_honours_prefix.patch b/bpo-31046_ensurepip_honours_prefix.patch index 42ce303..a63d336 100644 --- a/bpo-31046_ensurepip_honours_prefix.patch +++ b/bpo-31046_ensurepip_honours_prefix.patch @@ -13,10 +13,10 @@ Co-Authored-By: Xavier de Gaye 5 files changed, 37 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/Build/2019-12-16-17-50-42.bpo-31046.XA-Qfr.rst -Index: Python-3.15.0a3/Doc/library/ensurepip.rst +Index: Python-3.15.0a6/Doc/library/ensurepip.rst =================================================================== ---- Python-3.15.0a3.orig/Doc/library/ensurepip.rst 2025-12-16 13:26:12.000000000 +0100 -+++ Python-3.15.0a3/Doc/library/ensurepip.rst 2026-01-21 18:16:58.317178174 +0100 +--- Python-3.15.0a6.orig/Doc/library/ensurepip.rst 2026-02-11 13:23:15.000000000 +0100 ++++ Python-3.15.0a6/Doc/library/ensurepip.rst 2026-02-11 22:31:31.431727460 +0100 @@ -65,7 +65,11 @@ By default, ``pip`` is installed into the current virtual environment (if one is active) or into the system site packages (if there is no @@ -57,10 +57,10 @@ Index: Python-3.15.0a3/Doc/library/ensurepip.rst .. audit-event:: ensurepip.bootstrap root ensurepip.bootstrap .. note:: -Index: Python-3.15.0a3/Lib/ensurepip/__init__.py +Index: Python-3.15.0a6/Lib/ensurepip/__init__.py =================================================================== ---- Python-3.15.0a3.orig/Lib/ensurepip/__init__.py 2026-01-21 18:16:36.646076159 +0100 -+++ Python-3.15.0a3/Lib/ensurepip/__init__.py 2026-01-21 18:16:58.317562933 +0100 +--- Python-3.15.0a6.orig/Lib/ensurepip/__init__.py 2026-02-11 22:31:16.427291070 +0100 ++++ Python-3.15.0a6/Lib/ensurepip/__init__.py 2026-02-11 22:31:31.432196835 +0100 @@ -106,27 +106,27 @@ os.environ['PIP_CONFIG_FILE'] = os.devnull @@ -103,7 +103,7 @@ Index: Python-3.15.0a3/Lib/ensurepip/__init__.py if upgrade: args += ["--upgrade"] if user: -@@ -247,6 +249,11 @@ +@@ -249,6 +251,11 @@ help="Install everything relative to this alternate root directory.", ) parser.add_argument( @@ -115,7 +115,7 @@ Index: Python-3.15.0a3/Lib/ensurepip/__init__.py "--altinstall", action="store_true", default=False, -@@ -265,6 +272,7 @@ +@@ -267,6 +274,7 @@ return _bootstrap( root=args.root, @@ -123,11 +123,11 @@ Index: Python-3.15.0a3/Lib/ensurepip/__init__.py upgrade=args.upgrade, user=args.user, verbosity=args.verbosity, -Index: Python-3.15.0a3/Lib/test/test_ensurepip.py +Index: Python-3.15.0a6/Lib/test/test_ensurepip.py =================================================================== ---- Python-3.15.0a3.orig/Lib/test/test_ensurepip.py 2026-01-21 18:16:38.055385060 +0100 -+++ Python-3.15.0a3/Lib/test/test_ensurepip.py 2026-01-21 18:16:58.317858155 +0100 -@@ -105,6 +105,17 @@ +--- Python-3.15.0a6.orig/Lib/test/test_ensurepip.py 2026-02-11 22:31:18.221732997 +0100 ++++ Python-3.15.0a6/Lib/test/test_ensurepip.py 2026-02-11 22:31:31.432493024 +0100 +@@ -111,6 +111,17 @@ unittest.mock.ANY, ) @@ -145,11 +145,11 @@ Index: Python-3.15.0a3/Lib/test/test_ensurepip.py def test_bootstrapping_with_user(self): ensurepip.bootstrap(user=True) -Index: Python-3.15.0a3/Makefile.pre.in +Index: Python-3.15.0a6/Makefile.pre.in =================================================================== ---- Python-3.15.0a3.orig/Makefile.pre.in 2026-01-21 18:16:49.104742043 +0100 -+++ Python-3.15.0a3/Makefile.pre.in 2026-01-21 18:16:58.318353823 +0100 -@@ -2391,7 +2391,7 @@ +--- Python-3.15.0a6.orig/Makefile.pre.in 2026-02-11 22:31:29.094685981 +0100 ++++ Python-3.15.0a6/Makefile.pre.in 2026-02-11 22:31:31.433002555 +0100 +@@ -2412,7 +2412,7 @@ install|*) ensurepip="" ;; \ esac; \ $(RUNSHARED) $(PYTHON_FOR_BUILD) -m ensurepip \ @@ -158,7 +158,7 @@ Index: Python-3.15.0a3/Makefile.pre.in fi .PHONY: altinstall -@@ -2402,7 +2402,7 @@ +@@ -2423,7 +2423,7 @@ install|*) ensurepip="--altinstall" ;; \ esac; \ $(RUNSHARED) $(PYTHON_FOR_BUILD) -m ensurepip \ @@ -167,9 +167,9 @@ Index: Python-3.15.0a3/Makefile.pre.in fi .PHONY: commoninstall -Index: Python-3.15.0a3/Misc/NEWS.d/next/Build/2019-12-16-17-50-42.bpo-31046.XA-Qfr.rst +Index: Python-3.15.0a6/Misc/NEWS.d/next/Build/2019-12-16-17-50-42.bpo-31046.XA-Qfr.rst =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ Python-3.15.0a3/Misc/NEWS.d/next/Build/2019-12-16-17-50-42.bpo-31046.XA-Qfr.rst 2026-01-21 18:16:58.318910394 +0100 ++++ Python-3.15.0a6/Misc/NEWS.d/next/Build/2019-12-16-17-50-42.bpo-31046.XA-Qfr.rst 2026-02-11 22:31:31.433524319 +0100 @@ -0,0 +1 @@ +A directory prefix can now be specified when using :mod:`ensurepip`. diff --git a/python315.changes b/python315.changes index b088bc7..f7b15e0 100644 --- a/python315.changes +++ b/python315.changes @@ -1,3 +1,337 @@ +------------------------------------------------------------------- +Wed Feb 11 20:26:47 UTC 2026 - Matej Cepl + +- Update to 3.15.0a6: + - Tests + - gh-144415: The Android testbed now distinguishes between + stdout/stderr messages which were triggered by a newline, + and those triggered by a manual call to flush. This fixes + logging of progress indicators and similar content. + - gh-65784: Add support for parametrized resource wantobjects + in regrtests, which allows to run Tkinter tests with the + specified value of tkinter.wantobjects, for example -u + wantobjects=0. + - Security + - CVE-2024-6923: BytesGenerator will now refuse to serialize + (write) headers that are unsafely folded or delimited; see + verify_generated_headers. (Contributed by Bas Bloemsaat and + Petr Viktorin in gh-121650). (bsc#1228780, gh-144125) + - CVE-2025-11468: Fixed a bug in the folding of comments when + flattening an email message using a modern email policy. + Comments consisting of a very long sequence of non-foldable + characters could trigger a forced line wrap that omitted + the required leading space on the continuation line, + causing the remainder of the comment to be interpreted as + a new header field. This enabled header injection with + carefully crafted inputs. (bsc#1257029, gh-143935) + - CVE-2025-15282: Reject control characters in data: URL + media types. (bsc#1257046, gh-143925) + - CVE-2025-15367: Reject control characters in POP3 commands. + (bsc#1257041, gh-143923) + - CVE-2025-15366: Reject control characters in IMAP commands. + (bsc#1257044, gh-143921) + - CVE-2026-0672: Reject control characters in + http.cookies.Morsel fields and values. (bsc#1257031, + gh-143919) + - CVE-2026-0865: Reject C0 control characters within + wsgiref.headers.Headers fields, values, and parameters. + (bsc#1257042, gh-143916) + - Library + - gh-144538: Bump the version of pip bundled in ensurepip to + version 26.0.1 + - gh-144493: Improve an exception error message in + _overlapped.BindLocal() that is raised when + asyncio.loop.sock_connect() is called on + a asyncio.ProactorEventLoop with a socket that has an + invalid address family. + - gh-144386: Add support for arbitrary descriptors + __enter__(), __exit__(), __aenter__(), and __aexit__() in + contextlib.ExitStack and contextlib.AsyncExitStack, for + consistency with the with and async with statements. + - gh-123471: Make concurrent iteration over + itertools.combinations_with_replacement and + itertools.permutations safe under free-threading. + - gh-74453: Deprecate os.path.commonprefix() in favor of + os.path.commonpath() for path segment prefixes. + - The os.path.commonprefix() function is being deprecated due + to having a misleading name and module. The function is not + safe to use for path prefixes despite being included in + a module about path manipulation, meaning it is easy to + accidentally introduce path traversal vulnerabilities into + Python programs by using this function. + - gh-144380: Improve performance of io.BufferedReader line + iteration by ~49%. + - gh-144363: Update bundled libexpat to 2.7.4 + - gh-140824: When faulthandler dumps the list of third-party + extension modules, ignore sub-modules of stdlib packages. + Patch by Victor Stinner. + - gh-144206: Improve error messages for buffer overflow in + fcntl.fcntl() and fcntl.ioctl(). + - gh-144264: Speed up Base64 decoding of data containing + ignored characters (both in non-strict mode and with an + explicit ignorechars argument). It is now up to 2 times + faster for multiline Base64 data. + - gh-144249: Add filename context to OSError exceptions + raised by ssl.SSLContext.load_cert_chain(), allowing users + to have more context. + - gh-132888: Fix incorrect use of ctypes.GetLastError() and + add missing error checks for Windows API calls in + _pyrepl.windows_console. + - gh-142956: Updated tomllib to parse TOML 1.1.0. + - gh-144217: mimetypes: Add support for DICOM files (for + medical imaging) with the official MIME type + application/dicom. Patch by Benedikt Johannes. + - gh-144212: Mime type image/jxl is now supported by + mimetypes. + - gh-143594: Add symtable.Function.get_cells() and + symtable.Symbol.is_cell() methods. + - gh-144169: Fix three crashes when non-string keyword + arguments are supplied to objects in the ast module. + - gh-144128: Fix a crash in array.array.fromlist() when an + element’s __index__() method mutates the input list during + conversion. + - gh-144100: Fixed a crash in ctypes when using a deprecated + POINTER(str) type in argtypes. Instead of aborting, ctypes + now raises a proper Python exception when the pointer + target type is unresolved. + - gh-143658: importlib.metadata: Use str.lower() and + str.replace() to further improve performance of + importlib.metadata.Prepared.normalize(). Patch by Hugo van + Kemenade and Henry Schreiner. + - gh-144050: Fix stat.filemode() in the pure-Python + implementation to avoid misclassifying invalid mode values + as block devices. + - gh-83069: subprocess.Popen.wait(): when timeout is not + None, an efficient event-driven mechanism now waits for + process termination, if available. Linux >= 5.3 uses + os.pidfd_open() + select.poll(). macOS and other BSD + variants use select.kqueue() + KQ_FILTER_PROC + + KQ_NOTE_EXIT. Windows keeps using WaitForSingleObject + (unchanged). If none of these mechanisms are available, the + function falls back to the traditional busy loop + (non-blocking call and short sleeps). Patch by Giampaolo + Rodola. + - gh-144030: The Python implementation of + functools.lru_cache() differed from the default + C implementation in that it did not check that its argument + is callable. This discrepancy is now fixed and both raise + a TypeError. + - gh-144001: Added the ignorechars parameter in + binascii.a2b_base64() and base64.b64decode(). + - gh-144023: Fixed validation of file descriptor 0 in posix + functions when used with follow_symlinks parameter. + - gh-143999: Fix an issue where inspect.getgeneratorstate() + and inspect.getcoroutinestate() could fail for generators + wrapped by types.coroutine() in the suspended state. + - gh-143952: Fixed asyncio debugging tools to work with new + remote debugging API. Patch by Bartosz Sławecki. + - gh-143904: struct.pack_into() now raises OverflowError + instead of IndexError for too large offset argument. + - gh-143897: Remove the isxidstart() and isxidcontinue() + methods of unicodedata.ucd_3_2_0. They are now only exposed + as unicodedata.isxidstart() and + unicodedata.isxidcontinue(). + - gh-143831: annotationlib.ForwardRef objects are now + hashable when created from annotation scopes with closures. + Previously, hashing such objects would throw an exception. + Patch by Bartosz Sławecki. + - gh-143874: Fixed a bug in pdb where expression results were + not sent back to remote client. + - gh-143754: Add new tkinter widget methods pack_content(), + place_content() and grid_content() which are alternative + spelling of old *_slaves() methods. + - gh-143756: Fix potential thread safety issues in ssl + module. + - gh-132604: Previously, Protocol classes that were not + decorated with @~typing.runtime_checkable, but that + inherited from another Protocol class that did have this + decorator, could be used in isinstance() and issubclass() + checks. This behavior is now deprecated and such checks + will throw a TypeError in Python 3.20. Patch by Bartosz + Sławecki. + - gh-143543: Fix a crash in itertools.groupby that could + occur when a user-defined __eq__() method re-enters the + iterator during key comparison. + - gh-143689: Fix io.BufferedReader.read1() state cleanup on + buffer allocation failure. + - gh-143602: Fix a inconsistency issue in write() that leads + to unexpected buffer overwrite by deduplicating the buffer + exports. + - gh-142434: Use ppoll() if available in select.poll() to + have a timeout resolution of 1 nanosecond, instead of + a resolution of 1 ms. Patch by Victor Stinner. + - gh-140557: array.array buffers now have the same alignment + when empty as when allocated. Unaligned buffers can still + be created by slicing. + - gh-143423: Fix free-threaded build detection in the + sampling profiler when Py_GIL_DISABLED is set to 0. + - gh-101178: Add Ascii85, Base85, and Z85 support to binascii + and improve the performance of the base-85 converters in + base64. + - gh-142966: Fix ctypes.POINTER.set_type() not updating the + format string to match the type. + - gh-142555: array: fix a crash in a[i] = v when converting + i to an index via i.__index__ or i.__float__ mutates the + array. + - gh-142438: Fix _decimal builds configured with + EXTRA_FUNCTIONALITY by correcting the Context.apply wrapper + to pass the right argument. + - gh-141860: Add an on_error keyword-only parameter to + multiprocessing.set_forkserver_preload() to control how + import failures during module preloading are handled. + Accepts 'ignore' (default, silent), 'warn' (emit + ImportWarning), or 'fail' (raise exception). Contributed by + Nick Neumann and Gregory P. Smith. + - CVE-2025-12781: Accepting + and / characters with an + alternative alphabet in base64.b64decode() and + base64.urlsafe_b64decode() is now deprecated. In future + Python versions they will be errors in the strict mode and + discarded in the non-strict mode. (bsc#1257108, gh-125346) + - gh-140715: Add '%F' support to strptime(). + - gh-67041: Add the missing_as_none parameter to urlparse(), + urlsplit() and urldefrag() functions. Add the keep_empty + parameter to urlunparse() and urlunsplit() functions. This + allows to distinguish between empty and not defined URI + components and preserve empty components. + - gh-77188: The pickle module now properly handles + name-mangled private methods. + - IDLE + - gh-143774: Better explain the operation of Format / Format + Paragraph. + - Core and Builtins + - gh-134584: Optimize and eliminate ref-counting in + _BINARY_OP_SUBSCR_LIST_SLICE + - gh-144563: Fix interaction of the Tachyon profiler and + ctypes and other modules that load the Python shared + library (if present) in an independent map as this was + causing the mechanism that loads the binary information to + be confused. Patch by Pablo Galindo + - gh-144601: Fix crash when importing a module whose PyInit + function raises an exception from a subinterpreter. + - gh-144549: Fix building the tail calling interpreter on + Visual Studio 2026 with free-threading. + - gh-144513: Fix potential deadlock when using critical + sections during stop-the-world pauses in the free-threaded + build. + - gh-131798: Optimise _GUARD_TOS_SLICE in the JIT. + - gh-144330: Move classmethod and staticmethod initialization + from __init__() to __new__(). Patch by Victor Stinner. + - gh-144446: Fix data races in the free-threaded build when + reading frame object attributes while another thread is + executing the frame. + - gh-120321: Add gi_state, cr_state, and ag_state attributes + to generators, coroutines, and async generators that return + the current state as a string (e.g., GEN_RUNNING). The + inspect module functions getgeneratorstate(), + getcoroutinestate(), and getasyncgenstate() now return + these attributes directly. + - gh-141563: Fix thread safety of PyDateTime_IMPORT. + - gh-144280: Fix a bug in JIT where the predicate symbol had + no truthiness + - gh-140550: In PyModuleDef.m_slots, allow slots that repeat + information present in PyModuleDef. + - gh-139103: Improve scaling of namedtuple() instantiation in + the free-threaded build. + - gh-144307: Prevent a reference leak in module teardown at + interpreter finalization. + - gh-144319: Add huge pages support for the pymalloc + allocator. Patch by Pablo Galindo + - gh-120321: Made gi_yieldfrom thread-safe in the + free-threading build by using a lightweight lock on the + frame state. + - gh-144194: Fix error handling in perf jitdump + initialization on memory allocation failure. + - gh-143962: Name suggestion for not normalized name suggests + now the normalized name or the closest name to the + normalized name. If the suggested name is not ASCII, + include also its ASCII representation. + - gh-144157: bytes.translate() now allows the compiler to + unroll its loop more usefully for a 2x speedup in the + common no-deletions specified case. + - gh-144068: Fix JIT tracer memory leak, ensure the JIT + tracer state is freed when daemon threads are cleaned up + during interpreter shutdown. + - gh-144012: Check if the result is NULL in BINARY_OP_EXTENT + opcode. + - gh-144007: Eliminate redundant refcounting in the JIT for + BINARY_OP. + - gh-144005: Eliminate redundant refcounting from + BINARY_OP_EXTEND. + - gh-143939: Fix erroneous “cannot reuse already awaited + coroutine” error that could occur when a generator was run + during the process of clearing a coroutine’s frame. + - gh-141805: Fix crash in set when objects with the same hash + are concurrently added to the set after removing an element + with the same hash while the set still contains elements + with the same hash. + - gh-143670: Fixes a crash in ga_repr_items_list function. + - gh-143650: Fix race condition in importlib where a thread + could receive a stale module reference when another + thread’s import fails. + - gh-143569: Generator expressions in 3.15 now conform to the + documented behavior when the iterable does not support + iteration. This matches the behavior in 3.14 and earlier + - gh-143192: Improve performance of bitwise operations on + multi-digit ints. + - gh-132657: If we are specializing to LOAD_GLOBAL_MODULE or + LOAD_ATTR_MODULE, try to enable deferred reference counting + for the value, if the object is owned by a different + thread. This applies to the free-threaded build only and + should improve scaling of multi-threaded programs. Note + that when deferred reference counting is enabled, the + object will be deallocated by the GC, rather than by + Py_DECREF(). + - gh-143055: Implement PEP 798 (Unpacking in Comprehensions). + Patch by Adam Hartz. + - gh-142037: Improve error messages for printf-style + formatting. For errors in the format string, always include + the position of the start of the format unit. For errors + related to the formatted arguments, always include the + number or the name of the argument. Raise more specific + errors and include more information (type and number of + arguments, most probable causes of error). + - gh-140557: bytearray buffers now have the same alignment + when empty as when allocated. Unaligned buffers can still + be created by slicing. + - gh-140232: Frozenset objects with immutable elements are no + longer tracked by the garbage collector. + - gh-115231: Setup __module__ attribute for built-in static + methods. Patch by Sergey B Kirpichev. + - C API + - gh-143869: Added PyLong_GetNativeLayout(), PyLongLayout, + PyLongExport, PyLong_Export(), PyLong_FreeExport(), + PyLongWriter, PyLongWriter_Create(), PyLongWriter_Finish() + and PyLongWriter_Discard() to the limited API. + - gh-141070: Renamed PyUnstable_Object_Dump() to + PyObject_Dump(). + - Build + - gh-140421: Disable the perf trampoline on older macOS + versions where it cannot be built. + - gh-144309: Build Python with POSIX 2024, instead of POSIX + 2008. Patch by Victor Stinner. + - gh-144278: Enables defining the _PY_IMPL_NAME and + _PY_IMPL_CACHE_TAG preprocessor definitions to override + sys.implementation at build time. Definitions need to + include quotes when setting to a string literal. Setting + the cache tag to NULL has the effect of completely + disabling automatic creation and use of .pyc files. + - gh-143960: Add support for OpenSSL 3.6, drop EOL 3.2. Patch + by Hugo van Kemenade. + - gh-143941: Move WASI-related files to Platforms/WASI. Along + the way, leave a deprecated Tools/wasm/wasi/__main__.py + behind for backwards-compatibility. + - gh-143842: Prevent static builds from clashing with curses + by making the optimizer COLORS table static. +- Remove upstreamed patches: + - CVE-2024-6923-follow-up-EOL-email-headers.patch + - CVE-2025-11468-email-hdr-fold-comment.patch + - CVE-2025-12781-b64decode-alt-chars.patch + - CVE-2025-15282-urllib-ctrl-chars.patch + - CVE-2025-15366-imap-ctrl-chars.patch + - CVE-2025-15367-poplib-ctrl-chars.patch + - CVE-2026-0672-http-hdr-inject-cookie-Morsel.patch + - CVE-2026-0865-wsgiref-ctrl-chars.patch + ------------------------------------------------------------------- Sun Feb 8 13:34:32 UTC 2026 - Matej Cepl diff --git a/python315.spec b/python315.spec index 4bc44d7..551000f 100644 --- a/python315.spec +++ b/python315.spec @@ -162,8 +162,8 @@ # _md5.cpython-38m-x86_64-linux-gnu.so %define dynlib() %{sitedir}/lib-dynload/%{1}.cpython-%{abi_tag}-%{archname}-%{_os}%{?_gnu}%{?armsuffix}.so Name: %{python_pkg_name}%{psuffix} -Version: 3.15.0~a5 -%define tarversion 3.15.0a5 +Version: 3.15.0~a6 +%define tarversion 3.15.0a6 %define tarname Python-%{tarversion} Release: 0 Summary: Python 3 Interpreter @@ -225,31 +225,6 @@ Patch40: fix-test-recursion-limit-15.6.patch Patch41: bsc1243155-sphinx-non-determinism.patch # PATCH-FIX-OPENSUSE gh139257-Support-docutils-0.22.patch gh#python/cpython#139257 daniel.garcia@suse.com Patch42: gh139257-Support-docutils-0.22.patch -# PATCH-FIX-UPSTREAM CVE-2024-6923-follow-up-EOL-email-headers.patch bsc#1257181 mcepl@suse.com -# Encode newlines in headers when using ByteGenerator -# patch from gh#python/cpython#144125 -Patch44: CVE-2024-6923-follow-up-EOL-email-headers.patch -# PATCH-FIX-UPSTREAM CVE-2025-11468-email-hdr-fold-comment.patch bsc#1257029 mcepl@suse.com -# Email preserve parens when folding comments -Patch45: CVE-2025-11468-email-hdr-fold-comment.patch -# PATCH-FIX-UPSTREAM CVE-2026-0672-http-hdr-inject-cookie-Morsel.patch bsc#1257031 mcepl@suse.com -# Reject control characters in http cookies -Patch46: CVE-2026-0672-http-hdr-inject-cookie-Morsel.patch -# PATCH-FIX-UPSTREAM CVE-2025-12781-b64decode-alt-chars.patch bsc#1257108 mcepl@suse.com -# Fix decoding with non-standard Base64 alphabet gh#python/cpython#125346 -Patch47: CVE-2025-12781-b64decode-alt-chars.patch -# PATCH-FIX-UPSTREAM CVE-2026-0865-wsgiref-ctrl-chars.patch bsc#1257042 mcepl@suse.com -# Reject control characters in wsgiref.headers.Headers -Patch48: CVE-2026-0865-wsgiref-ctrl-chars.patch -# PATCH-FIX-UPSTREAM CVE-2025-15366-imap-ctrl-chars.patch bsc#1257044 mcepl@suse.com -# Reject control characters in wsgiref.headers.Headers -Patch49: CVE-2025-15366-imap-ctrl-chars.patch -# PATCH-FIX-UPSTREAM CVE-2025-15282-urllib-ctrl-chars.patch bsc#1257046 mcepl@suse.com -# Reject control characters in wsgiref.headers.Headers -Patch50: CVE-2025-15282-urllib-ctrl-chars.patch -# PATCH-FIX-UPSTREAM CVE-2025-15367-poplib-ctrl-chars.patch bsc#1257041 mcepl@suse.com -# Reject control characters in poplib -Patch51: CVE-2025-15367-poplib-ctrl-chars.patch #### Python 3.15 DEVELOPMENT PATCHES BuildRequires: autoconf-archive BuildRequires: automake