Compare commits

3 Commits

Author SHA256 Message Date
07beab470d Fix eight bugs (mostly rejecting ctrl chars in various protocols)
CVE-2025-11468: to preserve parens when folding comments.
  (bsc#1257029, gh#python/cpython#143935)
  CVE-2025-11468-email-hdr-fold-comment.patch
CVE-2025-12781: fix decoding with non-standard Base64 alphabet
  (bsc#1257108, gh#python/cpython#125346)
  CVE-2025-12781-b64decode-alt-chars.patch
CVE-2026-0672: rejects control characters in http cookies.
  (bsc#1257031, gh#python/cpython#143919)
  CVE-2026-0672-http-hdr-inject-cookie-Morsel.patch
CVE-2026-0865: rejecting control characters in
  wsgiref.headers.Headers, which could be abused for injecting
  false HTTP headers. (bsc#1257042, gh#python/cpython#143916)
  CVE-2026-0865-wsgiref-ctrl-chars.patch
CVE-2025-15366: basically the same as the previous patch for
  IMAP protocol. (bsc#1257044, gh#python/cpython#143921)
  CVE-2025-15366-imap-ctrl-chars.patch
CVE-2025-15282: basically the same as the previous patch for
  urllib library. (bsc#1257046, gh#python/cpython#143925)
  CVE-2025-15282-urllib-ctrl-chars.patch
CVE-2025-15367: basically the same as the previous patch for
  poplib library. (bsc#1257041, gh#python/cpython#143923)
  CVE-2025-15367-poplib-ctrl-chars.patch
CVE-2025-13836: to prevent reading an HTTP response from
  Content-Length per default as the length. (bsc#1254400,
  gh#python/cpython#119451)
  CVE-2025-13836-http-resp-cont-len.patch
CVE-2025-12084: prevent quadratic behavior in node ID cache
  clearing. (bsc#1254997, gh#python/cpython#142145)
  CVE-2025-12084-minidom-quad-search.patch
CVE-2025-13837: protect against OOM when loading malicious
  content. (bsc#1254401, gh#python/cpython#119342)
  CVE-2025-13837-plistlib-mailicious-length.patch
    - gh-99242: os.getloadavg() may throw OSError when running
      regression tests under certain conditions (e.g. chroot).
      This error is now caught and ignored, since reporting load
      average is optional.
    - gh-121160: Add a test for readline.set_history_length().
      Note that this test may fail on readline libraries.
    - gh-121200: Fix test_expanduser_pwd2() of test_posixpath.
      Call getpwnam() to get pw_dir, since it can be different
      than getpwall() pw_dir. Patch by Victor Stinner.
    - gh-121188: When creating the JUnit XML file, regrtest now
      escapes characters which are invalid in XML, such as the
      chr(27) control character used in ANSI escape sequences.
      Patch by Victor Stinner.
    - CVE-2026-1299 and CVE-2024-6923: email headers with
      embedded newlines are now quoted on output. The generator
      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
      bsc#1228780, gh-121650; bsc#1257181, gh-121650).
    - gh-120495: Fix incorrect exception handling in Tab Nanny.
      Patch by Wulian233.
      would produce incorrect results if type parameters in
      a class scope were overridden by assignments in a class
      scope and from __future__ import annotations semantics were
    - gh-81936: help() and showtopic() methods now respect
      a configured output argument to pydoc.Helper and not use
      the pager in such cases. Patch by Enrico Tröger.
    - gh-119577: The DeprecationWarning emitted when testing the
      truth value of an xml.etree.ElementTree.Element now
    - gh-121871: Documentation HTML varies from timestamp. Patch
      by Bernhard M. Wiedemann (bsc#1227999).
    - gh-122029: Emit c_call events in sys.setprofile() when
      a PyMethodObject pointing to a PyCFunction is called.
      modification of a list object, where one thread assigns
      a slice and another clears it.
      bytes and bytearray objects when using protocol version 5.
      Patch by Bénédikt Tran.
2026-02-11 23:47:18 +01:00
f7e1518c94 Add CVE-2025-11468-email-hdr-fold-comment.patch (bsc#1257029,
CVE-2025-11468) to preserve parens when folding comments.
2026-02-06 00:08:58 +01:00
2e0653fc8e doc: mention that bsc#1257181 has been already fixed 2026-02-05 22:58:49 +01:00
9 changed files with 833 additions and 48 deletions

View File

@@ -0,0 +1,108 @@
From 3900a2cb7d8321629717b8483179263a968bf552 Mon Sep 17 00:00:00 2001
From: Seth Michael Larson <seth@python.org>
Date: Mon, 19 Jan 2026 06:38:22 -0600
Subject: [PATCH] gh-143935: Email preserve parens when folding comments
(GH-143936)
Fix 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.
(cherry picked from commit 17d1490aa97bd6b98a42b1a9b324ead84e7fd8a2)
Co-authored-by: Seth Michael Larson <seth@python.org>
Co-authored-by: Denis Ledoux <dle@odoo.com>
---
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(-)
create mode 100644 Misc/NEWS.d/next/Security/2026-01-16-14-40-31.gh-issue-143935.U2YtKl.rst
Index: Python-3.12.12/Lib/email/_header_value_parser.py
===================================================================
--- Python-3.12.12.orig/Lib/email/_header_value_parser.py 2026-02-06 00:08:35.667684507 +0100
+++ Python-3.12.12/Lib/email/_header_value_parser.py 2026-02-06 00:08:40.746286971 +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}"'
@@ -933,7 +939,7 @@
return ' '
def startswith_fws(self):
- return True
+ return self and self[0] in WSP
class ValueTerminal(Terminal):
@@ -2922,6 +2928,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.12.12/Lib/test/test_email/test__header_value_parser.py
===================================================================
--- Python-3.12.12.orig/Lib/test/test_email/test__header_value_parser.py 2026-02-06 00:08:37.343959625 +0100
+++ Python-3.12.12/Lib/test/test_email/test__header_value_parser.py 2026-02-06 00:08:40.747102748 +0100
@@ -3141,6 +3141,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)<spy@example.org>',
+ '(loremipsumdolorsitametconsecteturadipi)<spy@example.org>\n'),
+ ('<spy@example.org>(loremipsumdolorsitametconsecteturadipi)',
+ '<spy@example.org>(loremipsumdolorsitametconsecteturadipi)\n'),
+ ('(loremipsum dolorsitametconsecteturadipi)<spy@example.org>',
+ '(loremipsum dolorsitametconsecteturadipi)<spy@example.org>\n'),
+ ('<spy@example.org>(loremipsum dolorsitametconsecteturadipi)',
+ '<spy@example.org>(loremipsum\n dolorsitametconsecteturadipi)\n'),
+ ('(Escaped \\( \\) chars \\\\ in comments stay escaped)<spy@example.org>',
+ '(Escaped \\( \\) chars \\\\ in comments stay\n escaped)<spy@example.org>\n'),
+ ('((loremipsum)(loremipsum)(loremipsum)(loremipsum))<spy@example.org>',
+ '((loremipsum)(loremipsum)(loremipsum)(loremipsum))<spy@example.org>\n'),
+ ('((loremipsum)(loremipsum)(loremipsum) (loremipsum))<spy@example.org>',
+ '((loremipsum)(loremipsum)(loremipsum)\n (loremipsum))<spy@example.org>\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.12.12/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.12.12/Misc/NEWS.d/next/Security/2026-01-16-14-40-31.gh-issue-143935.U2YtKl.rst 2026-02-06 00:08:40.747576711 +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.

View File

@@ -0,0 +1,193 @@
From f922c02c529d25d61aa9c28a8192639c1fce8d4d Mon Sep 17 00:00:00 2001
From: Serhiy Storchaka <storchaka@gmail.com>
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 +++-
Lib/base64.py | 40 ++++++++-
Lib/test/test_base64.py | 42 +++++++++-
Misc/NEWS.d/next/Library/2025-11-06-12-03-29.gh-issue-125346.7Gfpgw.rst | 5 +
4 files changed, 91 insertions(+), 14 deletions(-)
Index: Python-3.12.12/Doc/library/base64.rst
===================================================================
--- Python-3.12.12.orig/Doc/library/base64.rst 2025-10-09 13:07:00.000000000 +0200
+++ Python-3.12.12/Doc/library/base64.rst 2026-02-10 22:15:41.801235355 +0100
@@ -74,15 +74,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)
@@ -113,6 +118,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.12.12/Lib/base64.py
===================================================================
--- Python-3.12.12.orig/Lib/base64.py 2026-02-10 22:15:02.534016402 +0100
+++ Python-3.12.12/Lib/base64.py 2026-02-10 22:15:41.801591556 +0100
@@ -71,20 +71,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):
@@ -129,8 +148,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.12.12/Lib/test/test_base64.py
===================================================================
--- Python-3.12.12.orig/Lib/test/test_base64.py 2026-02-10 22:15:04.364274059 +0100
+++ Python-3.12.12/Lib/test/test_base64.py 2026-02-10 22:17:42.445725550 +0100
@@ -232,6 +232,25 @@
b'\xd3V\xbeo\xf7\x1d')
self.check_decode_type_errors(base64.urlsafe_b64decode)
+ 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')
@@ -263,10 +282,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\xBE\xFF\xFF\xFF'
- self.assertEqual(base64.b64decode(b'++[[//]]', 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 test_b32encode(self):
eq = self.assertEqual
Index: Python-3.12.12/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.12.12/Misc/NEWS.d/next/Library/2025-11-06-12-03-29.gh-issue-125346.7Gfpgw.rst 2026-02-10 22:15:41.802353823 +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.

View File

@@ -0,0 +1,64 @@
From f336af1c4b103297de1322bbe00f920f3e58b899 Mon Sep 17 00:00:00 2001
From: Seth Michael Larson <seth@python.org>
Date: Tue, 20 Jan 2026 14:45:58 -0600
Subject: [PATCH 1/2] [3.12] gh-143925: Reject control characters in data: URL
mediatypes (cherry picked from commit
f25509e78e8be6ea73c811ac2b8c928c28841b9f) (cherry picked from commit
2c9c746077d8119b5bcf5142316992e464594946)
Co-authored-by: Seth Michael Larson <seth@python.org>
---
Lib/test/test_urllib.py | 8 ++++++++
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(+)
create mode 100644 Misc/NEWS.d/next/Security/2026-01-16-11-51-19.gh-issue-143925.mrtcHW.rst
Index: Python-3.12.12/Lib/test/test_urllib.py
===================================================================
--- Python-3.12.12.orig/Lib/test/test_urllib.py 2026-02-10 22:15:06.355594386 +0100
+++ Python-3.12.12/Lib/test/test_urllib.py 2026-02-10 22:18:23.820760279 +0100
@@ -12,6 +12,7 @@
from test.support import os_helper
from test.support import socket_helper
from test.support import warnings_helper
+from test.support import control_characters_c0
import os
try:
import ssl
@@ -688,6 +689,13 @@
# missing padding character
self.assertRaises(ValueError,urllib.request.urlopen,'data:;base64,Cg=')
+ def test_invalid_mediatype(self):
+ for c0 in control_characters_c0():
+ self.assertRaises(ValueError,urllib.request.urlopen,
+ f'data:text/html;{c0},data')
+ for c0 in control_characters_c0():
+ 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.12.12/Lib/urllib/request.py
===================================================================
--- Python-3.12.12.orig/Lib/urllib/request.py 2026-02-10 22:15:06.739534061 +0100
+++ Python-3.12.12/Lib/urllib/request.py 2026-02-10 22:18:23.819325524 +0100
@@ -1655,6 +1655,11 @@
scheme, data = url.split(":",1)
mediatype, data = data.split(",",1)
+ # Disallow control characters within mediatype.
+ if re.search(r"[\x00-\x1F\x7F]", mediatype):
+ raise ValueError(
+ "Control characters not allowed in data: mediatype")
+
# 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.12.12/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.12.12/Misc/NEWS.d/next/Security/2026-01-16-11-51-19.gh-issue-143925.mrtcHW.rst 2026-02-10 22:18:23.819830797 +0100
@@ -0,0 +1 @@
+Reject control characters in ``data:`` URL media types.

View File

@@ -0,0 +1,38 @@
From 7485ee5e2cf81d3e5ad0d9c3be73cecd2ab4eec7 Mon Sep 17 00:00:00 2001
From: Seth Michael Larson <seth@python.org>
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 +++-
Misc/NEWS.d/next/Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst | 1 +
2 files changed, 4 insertions(+), 1 deletion(-)
Index: Python-3.12.12/Lib/imaplib.py
===================================================================
--- Python-3.12.12.orig/Lib/imaplib.py 2026-02-10 22:15:03.417592955 +0100
+++ Python-3.12.12/Lib/imaplib.py 2026-02-10 22:18:02.094605035 +0100
@@ -132,7 +132,7 @@
# We compile these in _mode_xxx.
_Literal = br'.*{(?P<size>\d+)}$'
_Untagged_status = br'\* (?P<data>\d+) (?P<type>[A-Z-]+)( (?P<data2>.*))?'
-
+_control_chars = re.compile(b'[\x00-\x1F\x7F]')
class IMAP4:
@@ -994,6 +994,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.12.12/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.12.12/Misc/NEWS.d/next/Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst 2026-02-10 22:18:02.095167966 +0100
@@ -0,0 +1 @@
+Reject control characters in IMAP commands.

View File

@@ -0,0 +1,56 @@
From b6f733b285b1c4f27dacb5c2e1f292c914e8b933 Mon Sep 17 00:00:00 2001
From: Seth Michael Larson <seth@python.org>
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.12.12/Lib/poplib.py
===================================================================
--- Python-3.12.12.orig/Lib/poplib.py 2026-02-11 23:46:29.442215955 +0100
+++ Python-3.12.12/Lib/poplib.py 2026-02-11 23:46:46.713251058 +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.12.12/Lib/test/test_poplib.py
===================================================================
--- Python-3.12.12.orig/Lib/test/test_poplib.py 2026-02-11 23:46:31.636412813 +0100
+++ Python-3.12.12/Lib/test/test_poplib.py 2026-02-11 23:46:46.713442229 +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.12.12/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.12.12/Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst 2026-02-11 23:46:46.713620996 +0100
@@ -0,0 +1 @@
+Reject control characters in POP3 commands.

View File

@@ -0,0 +1,183 @@
From 9729bdf210967c806f3364c76663fc2ade58e389 Mon Sep 17 00:00:00 2001
From: Seth Michael Larson <seth@python.org>
Date: Tue, 20 Jan 2026 15:23:42 -0600
Subject: [PATCH] gh-143919: Reject control characters in http cookies (cherry
picked from commit 95746b3a13a985787ef53b977129041971ed7f70)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Seth Michael Larson <seth@python.org>
Co-authored-by: Bartosz Sławecki <bartosz@ilikepython.com>
Co-authored-by: sobolevn <mail@sobolevn.me>
---
Doc/library/http.cookies.rst | 4
Lib/http/cookies.py | 25 ++++
Lib/test/test_http_cookies.py | 52 +++++++++-
Misc/NEWS.d/next/Security/2026-01-16-11-13-15.gh-issue-143919.kchwZV.rst | 1
4 files changed, 73 insertions(+), 9 deletions(-)
create mode 100644 Misc/NEWS.d/next/Security/2026-01-16-11-13-15.gh-issue-143919.kchwZV.rst
Index: Python-3.12.12/Doc/library/http.cookies.rst
===================================================================
--- Python-3.12.12.orig/Doc/library/http.cookies.rst 2025-10-09 13:07:00.000000000 +0200
+++ Python-3.12.12/Doc/library/http.cookies.rst 2026-02-10 22:17:53.970413039 +0100
@@ -272,9 +272,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.12.12/Lib/http/cookies.py
===================================================================
--- Python-3.12.12.orig/Lib/http/cookies.py 2026-02-10 22:15:03.102916960 +0100
+++ Python-3.12.12/Lib/http/cookies.py 2026-02-10 22:17:53.970584713 +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.
@@ -292,12 +301,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):
@@ -333,6 +346,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
@@ -486,7 +502,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.12.12/Lib/test/test_http_cookies.py
===================================================================
--- Python-3.12.12.orig/Lib/test/test_http_cookies.py 2026-02-10 22:15:05.120676729 +0100
+++ Python-3.12.12/Lib/test/test_http_cookies.py 2026-02-10 22:17:53.970780833 +0100
@@ -17,10 +17,10 @@
'repr': "<SimpleCookie: chips='ahoy' vienna='finger'>",
'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': '''<SimpleCookie: keebler='E=mc2; L="Loves"; fudge=\\n;'>''',
- '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': '''<SimpleCookie: keebler='E=mc2; L="Loves"; fudge=;'>''',
+ 'output': 'Set-Cookie: keebler="E=mc2; L=\\"Loves\\"; fudge=;"'},
# Check illegal cookies that have an '=' char in an unquoted value
{'data': 'keebler=E=mc2',
@@ -563,6 +563,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.12.12/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.12.12/Misc/NEWS.d/next/Security/2026-01-16-11-13-15.gh-issue-143919.kchwZV.rst 2026-02-10 22:17:53.970970320 +0100
@@ -0,0 +1 @@
+Reject control characters in :class:`http.cookies.Morsel` fields and values.

View File

@@ -0,0 +1,96 @@
From 03a7342c9e2bbdab20a6d882bf334608dc7a5d4b Mon Sep 17 00:00:00 2001
From: "Gregory P. Smith" <68491+gpshead@users.noreply.github.com>
Date: Sat, 17 Jan 2026 10:23:57 -0800
Subject: [PATCH] [3.12] gh-143916: Reject control characters in
wsgiref.headers.Headers (GH-143917) (GH-143973)
gh-143916: Reject control characters in wsgiref.headers.Headers (GH-143917)
* Add 'test.support' fixture for C0 control characters
* gh-143916: Reject control characters in wsgiref.headers.Headers
(cherry picked from commit f7fceed79ca1bceae8dbe5ba5bc8928564da7211)
(cherry picked from commit 22e4d55285cee52bc4dbe061324e5f30bd4dee58)
Co-authored-by: Gregory P. Smith <68491+gpshead@users.noreply.github.com>
Co-authored-by: Seth Michael Larson <seth@python.org>
---
Lib/test/support/__init__.py | 7 +++++
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 +
4 files changed, 23 insertions(+), 1 deletion(-)
create mode 100644 Misc/NEWS.d/next/Security/2026-01-16-11-07-36.gh-issue-143916.dpWeOD.rst
Index: Python-3.12.12/Lib/test/support/__init__.py
===================================================================
--- Python-3.12.12.orig/Lib/test/support/__init__.py 2026-02-10 22:15:04.163026806 +0100
+++ Python-3.12.12/Lib/test/support/__init__.py 2026-02-10 22:17:57.451276662 +0100
@@ -2591,3 +2591,10 @@
if self.iter_raises:
1/0
return self
+
+
+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.12.12/Lib/test/test_wsgiref.py
===================================================================
--- Python-3.12.12.orig/Lib/test/test_wsgiref.py 2026-02-10 22:15:06.432657502 +0100
+++ Python-3.12.12/Lib/test/test_wsgiref.py 2026-02-10 22:17:57.451566378 +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.12.12/Lib/wsgiref/headers.py
===================================================================
--- Python-3.12.12.orig/Lib/wsgiref/headers.py 2026-02-10 22:15:06.773169140 +0100
+++ Python-3.12.12/Lib/wsgiref/headers.py 2026-02-10 22:17:57.451729575 +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.12.12/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.12.12/Misc/NEWS.d/next/Security/2026-01-16-11-07-36.gh-issue-143916.dpWeOD.rst 2026-02-10 22:17:57.451848490 +0100
@@ -0,0 +1,2 @@
+Reject C0 control characters within wsgiref.headers.Headers fields, values,
+and parameters.

View File

@@ -1,16 +1,43 @@
-------------------------------------------------------------------
Fri Feb 6 00:07:20 CET 2026 - Matej Cepl <mcepl@suse.com>
- CVE-2025-11468: to preserve parens when folding comments.
(bsc#1257029, gh#python/cpython#143935)
CVE-2025-11468-email-hdr-fold-comment.patch
- CVE-2025-12781: fix decoding with non-standard Base64 alphabet
(bsc#1257108, gh#python/cpython#125346)
CVE-2025-12781-b64decode-alt-chars.patch
- CVE-2026-0672: rejects control characters in http cookies.
(bsc#1257031, gh#python/cpython#143919)
CVE-2026-0672-http-hdr-inject-cookie-Morsel.patch
- CVE-2026-0865: rejecting control characters in
wsgiref.headers.Headers, which could be abused for injecting
false HTTP headers. (bsc#1257042, gh#python/cpython#143916)
CVE-2026-0865-wsgiref-ctrl-chars.patch
- CVE-2025-15366: basically the same as the previous patch for
IMAP protocol. (bsc#1257044, gh#python/cpython#143921)
CVE-2025-15366-imap-ctrl-chars.patch
- CVE-2025-15282: basically the same as the previous patch for
urllib library. (bsc#1257046, gh#python/cpython#143925)
CVE-2025-15282-urllib-ctrl-chars.patch
- CVE-2025-15367: basically the same as the previous patch for
poplib library. (bsc#1257041, gh#python/cpython#143923)
CVE-2025-15367-poplib-ctrl-chars.patch
------------------------------------------------------------------- -------------------------------------------------------------------
Thu Dec 18 10:33:44 UTC 2025 - Matej Cepl <mcepl@cepl.eu> Thu Dec 18 10:33:44 UTC 2025 - Matej Cepl <mcepl@cepl.eu>
- Add CVE-2025-13836-http-resp-cont-len.patch (bsc#1254400, - CVE-2025-13836: to prevent reading an HTTP response from
CVE-2025-13836) to prevent reading an HTTP response from
a server, if no read amount is specified, with using a server, if no read amount is specified, with using
Content-Length per default as the length. Content-Length per default as the length. (bsc#1254400,
- Add CVE-2025-12084-minidom-quad-search.patch prevent quadratic gh#python/cpython#119451)
behavior in node ID cache clearing (CVE-2025-12084, CVE-2025-13836-http-resp-cont-len.patch
bsc#1254997). - CVE-2025-12084: prevent quadratic behavior in node ID cache
- Add CVE-2025-13837-plistlib-mailicious-length.patch protect clearing. (bsc#1254997, gh#python/cpython#142145)
against OOM when loading malicious content (CVE-2025-13837, CVE-2025-12084-minidom-quad-search.patch
bsc#1254401). - CVE-2025-13837: protect against OOM when loading malicious
content. (bsc#1254401, gh#python/cpython#119342)
CVE-2025-13837-plistlib-mailicious-length.patch
------------------------------------------------------------------- -------------------------------------------------------------------
Wed Nov 19 19:21:41 UTC 2025 - Matej Cepl <mcepl@suse.com> Wed Nov 19 19:21:41 UTC 2025 - Matej Cepl <mcepl@suse.com>
@@ -1208,25 +1235,23 @@ Wed Aug 7 18:05:57 UTC 2024 - Matej Cepl <mcepl@cepl.eu>
- Tests - Tests
- gh-59022: Add tests for pkgutil.extend_path(). Patch by - gh-59022: Add tests for pkgutil.extend_path(). Patch by
Andreas Stocker. Andreas Stocker.
- gh-99242: os.getloadavg() may throw OSError when - gh-99242: os.getloadavg() may throw OSError when running
running regression tests under certain conditions (e.g. regression tests under certain conditions (e.g. chroot).
chroot). This error is now caught and ignored, since This error is now caught and ignored, since reporting load
reporting load average is optional. average is optional.
- gh-121084: Fix test_typing random leaks. Clear typing ABC - gh-121084: Fix test_typing random leaks. Clear typing ABC
caches when running tests for refleaks (-R option): call caches when running tests for refleaks (-R option): call
_abc_caches_clear() on typing abstract classes and their _abc_caches_clear() on typing abstract classes and their
subclasses. Patch by Victor Stinner. subclasses. Patch by Victor Stinner.
- gh-121160: Add a test for - gh-121160: Add a test for readline.set_history_length().
readline.set_history_length(). Note that this test may fail Note that this test may fail on readline libraries.
on readline libraries. - gh-121200: Fix test_expanduser_pwd2() of test_posixpath.
- gh-121200: Fix test_expanduser_pwd2() of Call getpwnam() to get pw_dir, since it can be different
test_posixpath. Call getpwnam() to get pw_dir, since it than getpwall() pw_dir. Patch by Victor Stinner.
can be different than getpwall() pw_dir. Patch by Victor - gh-121188: When creating the JUnit XML file, regrtest now
Stinner. escapes characters which are invalid in XML, such as the
- gh-121188: When creating the JUnit XML file, regrtest chr(27) control character used in ANSI escape sequences.
now escapes characters which are invalid in XML, such Patch by Victor Stinner.
as the chr(27) control character used in ANSI escape
sequences. Patch by Victor Stinner.
- Security - Security
- gh-121957: Fixed missing audit events around interactive - gh-121957: Fixed missing audit events around interactive
use of Python, now also properly firing for python -i, as use of Python, now also properly firing for python -i, as
@@ -1249,12 +1274,12 @@ Wed Aug 7 18:05:57 UTC 2024 - Matej Cepl <mcepl@cepl.eu>
filecmp.dircmp and filecmp.cmpfiles(). Patch by Bénédikt filecmp.dircmp and filecmp.cmpfiles(). Patch by Bénédikt
Tran. Tran.
- gh-122311: Fix some error messages in pickle. - gh-122311: Fix some error messages in pickle.
- gh-121650: email headers with embedded newlines are - CVE-2026-1299 and CVE-2024-6923: email headers with
now quoted on output. The generator will now refuse to embedded newlines are now quoted on output. The generator
serialize (write) headers that are unsafely folded or will now refuse to serialize (write) headers that are
delimited; see verify_generated_headers. (Contributed by unsafely folded or delimited; see verify_generated_headers.
Bas Bloemsaat and Petr Viktorin in gh-121650; bsc#1228780, (Contributed by Bas Bloemsaat and Petr Viktorin in
CVE-2024-6923). bsc#1228780, gh-121650; bsc#1257181, gh-121650).
- gh-122332: Fixed segfault with asyncio.Task.get_coro() when - gh-122332: Fixed segfault with asyncio.Task.get_coro() when
using an eager task factory. using an eager task factory.
- gh-122170: Handle ValueErrors raised by os.stat() in - gh-122170: Handle ValueErrors raised by os.stat() in
@@ -1291,8 +1316,8 @@ Wed Aug 7 18:05:57 UTC 2024 - Matej Cepl <mcepl@cepl.eu>
even when the command is from cmdqueue. even when the command is from cmdqueue.
- gh-120732: Fix name passing to unittest.mock.Mock object - gh-120732: Fix name passing to unittest.mock.Mock object
when using unittest.mock.create_autospec(). when using unittest.mock.create_autospec().
- gh-120495: Fix incorrect exception handling in Tab - gh-120495: Fix incorrect exception handling in Tab Nanny.
Nanny. Patch by Wulian233. Patch by Wulian233.
- gh-120343: Fix column offset reporting for tokens that come - gh-120343: Fix column offset reporting for tokens that come
after multiline f-strings in the tokenize module. after multiline f-strings in the tokenize module.
- gh-119600: Fix unittest.mock.patch() to not read attributes - gh-119600: Fix unittest.mock.patch() to not read attributes
@@ -1301,9 +1326,9 @@ Wed Aug 7 18:05:57 UTC 2024 - Matej Cepl <mcepl@cepl.eu>
- gh-120289: Fixed the use-after-free issue in cProfile by - gh-120289: Fixed the use-after-free issue in cProfile by
disallowing disable() and clear() in external timers. disallowing disable() and clear() in external timers.
- gh-114053: Fix edge-case bug where typing.get_type_hints() - gh-114053: Fix edge-case bug where typing.get_type_hints()
would produce incorrect results if type parameters in a would produce incorrect results if type parameters in
class scope were overridden by assignments in a class scope a class scope were overridden by assignments in a class
and from __future__ import annotations semantics were scope and from __future__ import annotations semantics were
enabled. Patch by Alex Waygood. enabled. Patch by Alex Waygood.
- gh-114053: Fix erroneous NameError when calling - gh-114053: Fix erroneous NameError when calling
inspect.get_annotations() with eval_str=True` on a class inspect.get_annotations() with eval_str=True` on a class
@@ -1328,11 +1353,11 @@ Wed Aug 7 18:05:57 UTC 2024 - Matej Cepl <mcepl@cepl.eu>
- gh-112672: Support building tkinter with Tcl 9.0. - gh-112672: Support building tkinter with Tcl 9.0.
- gh-65454: unittest.mock.Mock.attach_mock() no longer - gh-65454: unittest.mock.Mock.attach_mock() no longer
triggers a call to a PropertyMock being attached. triggers a call to a PropertyMock being attached.
- gh-81936: help() and showtopic() methods now respect a - gh-81936: help() and showtopic() methods now respect
configured output argument to pydoc.Helper and not use the a configured output argument to pydoc.Helper and not use
pager in such cases. Patch by Enrico Tröger. the pager in such cases. Patch by Enrico Tröger.
- gh-119577: The DeprecationWarning emitted when testing - gh-119577: The DeprecationWarning emitted when testing the
the truth value of an xml.etree.ElementTree.Element now truth value of an xml.etree.ElementTree.Element now
describes unconditionally returning True in a future describes unconditionally returning True in a future
version rather than raising an exception in Python 3.14. version rather than raising an exception in Python 3.14.
- gh-119506: Fix io.TextIOWrapper.write() method breaks - gh-119506: Fix io.TextIOWrapper.write() method breaks
@@ -1361,16 +1386,16 @@ Wed Aug 7 18:05:57 UTC 2024 - Matej Cepl <mcepl@cepl.eu>
multiprocessing.Queue.empty() and multiprocessing.Queue.empty() and
multiprocessing.SimpleQueue.empty() on closed queues. Patch multiprocessing.SimpleQueue.empty() on closed queues. Patch
by Bénédikt Tran. by Bénédikt Tran.
- gh-121871: Documentation HTML varies from timestamp. Patch by - gh-121871: Documentation HTML varies from timestamp. Patch
Bernhard M. Wiedemann (bsc#1227999). by Bernhard M. Wiedemann (bsc#1227999).
- Core and Builtins - Core and Builtins
- gh-122208: Dictionary watchers now only deliver the - gh-122208: Dictionary watchers now only deliver the
PyDict_EVENT_ADDED event when the insertion is in a known PyDict_EVENT_ADDED event when the insertion is in a known
good state to succeed. good state to succeed.
- gh-122300: Preserve AST nodes for f-string with - gh-122300: Preserve AST nodes for f-string with
single-element format specifiers. Patch by Pablo Galindo single-element format specifiers. Patch by Pablo Galindo
- gh-122029: Emit c_call events in sys.setprofile() when a - gh-122029: Emit c_call events in sys.setprofile() when
PyMethodObject pointing to a PyCFunction is called. a PyMethodObject pointing to a PyCFunction is called.
- gh-122026: Fix a bug that caused the tokenizer to not - gh-122026: Fix a bug that caused the tokenizer to not
correctly identify mismatched parentheses inside f-strings correctly identify mismatched parentheses inside f-strings
in some situations. Patch by Pablo Galindo in some situations. Patch by Pablo Galindo
@@ -1387,11 +1412,11 @@ Wed Aug 7 18:05:57 UTC 2024 - Matej Cepl <mcepl@cepl.eu>
- gh-120384: Fix an array out of bounds crash in - gh-120384: Fix an array out of bounds crash in
list_ass_subscript, which could be invoked via some list_ass_subscript, which could be invoked via some
specificly tailored input: including concurrent specificly tailored input: including concurrent
modification of a list object, where one thread assigns a modification of a list object, where one thread assigns
slice and another clears it. a slice and another clears it.
- gh-120380: Fix Python implementation of pickle.Pickler for - gh-120380: Fix Python implementation of pickle.Pickler for
bytes and bytearray objects when using protocol version bytes and bytearray objects when using protocol version 5.
5. Patch by Bénédikt Tran. Patch by Bénédikt Tran.
- gh-93691: Fix source locations of instructions generated - gh-93691: Fix source locations of instructions generated
for the iterator of a for statement. for the iterator of a for statement.
- gh-120198: Fix a crash when multiple threads read and write - gh-120198: Fix a crash when multiple threads read and write

View File

@@ -204,6 +204,28 @@ Patch50: CVE-2025-12084-minidom-quad-search.patch
# PATCH-FIX-UPSTREAM CVE-2025-13837-plistlib-mailicious-length.patch bsc#1254401 mcepl@suse.com # PATCH-FIX-UPSTREAM CVE-2025-13837-plistlib-mailicious-length.patch bsc#1254401 mcepl@suse.com
# protect against OOM when loading malicious content # protect against OOM when loading malicious content
Patch51: CVE-2025-13837-plistlib-mailicious-length.patch Patch51: CVE-2025-13837-plistlib-mailicious-length.patch
# PATCH-FIX-UPSTREAM CVE-2025-11468-email-hdr-fold-comment.patch bsc#1257029 mcepl@suse.com
# Email preserve parens when folding comments
Patch52: CVE-2025-11468-email-hdr-fold-comment.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
Patch53: CVE-2025-12781-b64decode-alt-chars.patch
# PATCH-FIX-UPSTREAM CVE-2026-0672-http-hdr-inject-cookie-Morsel.patch bsc#1257031 mcepl@suse.com
# Reject control characters in http cookies
Patch54: CVE-2026-0672-http-hdr-inject-cookie-Morsel.patch
# PATCH-FIX-UPSTREAM CVE-2026-0865-wsgiref-ctrl-chars.patch bsc#1257042 mcepl@suse.com
# Reject control characters in wsgiref.headers.Headers
Patch55: 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
Patch56: 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 urllib
Patch57: 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
Patch58: CVE-2025-15367-poplib-ctrl-chars.patch
### END OF PATCHES
BuildRequires: autoconf-archive BuildRequires: autoconf-archive
BuildRequires: automake BuildRequires: automake
BuildRequires: fdupes BuildRequires: fdupes