3 Commits

Author SHA256 Message Date
152a6ee9c6 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-10 23:12:15 +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 857 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,83 @@
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/test/support/__init__.py | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
index 3a639497fa1272..9c113a6c137e52 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -3303,3 +3303,10 @@ def linked_to_musl():
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"]
From 58591540fc2140bd1a79e292af1ceea607ba957a Mon Sep 17 00:00:00 2001
From: Seth Michael Larson <seth@python.org>
Date: Tue, 30 Dec 2025 11:03:02 -0600
Subject: [PATCH 2/2] gh-143923: Reject control characters in POP3 commands
---
Lib/poplib.py | 2 ++
Lib/test/test_poplib.py | 8 ++++++++
.../2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst | 1 +
3 files changed, 11 insertions(+)
create mode 100644 Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst
diff --git a/Lib/poplib.py b/Lib/poplib.py
index 4469bff44b4c45..b97274c5c32ee6 100644
--- a/Lib/poplib.py
+++ b/Lib/poplib.py
@@ -122,6 +122,8 @@ def _putline(self, line):
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)
diff --git a/Lib/test/test_poplib.py b/Lib/test/test_poplib.py
index ef2da97f86734a..18ca7cb556836e 100644
--- a/Lib/test/test_poplib.py
+++ b/Lib/test/test_poplib.py
@@ -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 @@ def test_quit(self):
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()
diff --git a/Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst b/Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst
new file mode 100644
index 00000000000000..3cde4df3e0069f
--- /dev/null
+++ b/Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst
@@ -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>
- 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
Content-Length per default as the length.
- Add CVE-2025-12084-minidom-quad-search.patch prevent quadratic
behavior in node ID cache clearing (CVE-2025-12084,
bsc#1254997).
- Add CVE-2025-13837-plistlib-mailicious-length.patch protect
against OOM when loading malicious content (CVE-2025-13837,
bsc#1254401).
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
-------------------------------------------------------------------
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
- gh-59022: Add tests for pkgutil.extend_path(). Patch by
Andreas Stocker.
- 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-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-121084: Fix test_typing random leaks. Clear typing ABC
caches when running tests for refleaks (-R option): call
_abc_caches_clear() on typing abstract classes and their
subclasses. Patch by Victor Stinner.
- 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.
- 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.
- Security
- gh-121957: Fixed missing audit events around interactive
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
Tran.
- gh-122311: Fix some error messages in pickle.
- gh-121650: 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 gh-121650; bsc#1228780,
CVE-2024-6923).
- 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-122332: Fixed segfault with asyncio.Task.get_coro() when
using an eager task factory.
- 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.
- gh-120732: Fix name passing to unittest.mock.Mock object
when using unittest.mock.create_autospec().
- gh-120495: Fix incorrect exception handling in Tab
Nanny. Patch by Wulian233.
- gh-120495: Fix incorrect exception handling in Tab Nanny.
Patch by Wulian233.
- gh-120343: Fix column offset reporting for tokens that come
after multiline f-strings in the tokenize module.
- 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
disallowing disable() and clear() in external timers.
- gh-114053: Fix edge-case bug where typing.get_type_hints()
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
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
enabled. Patch by Alex Waygood.
- gh-114053: Fix erroneous NameError when calling
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-65454: unittest.mock.Mock.attach_mock() no longer
triggers a call to a PropertyMock being attached.
- 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-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
describes unconditionally returning True in a future
version rather than raising an exception in Python 3.14.
- 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.SimpleQueue.empty() on closed queues. Patch
by Bénédikt Tran.
- gh-121871: Documentation HTML varies from timestamp. Patch by
Bernhard M. Wiedemann (bsc#1227999).
- gh-121871: Documentation HTML varies from timestamp. Patch
by Bernhard M. Wiedemann (bsc#1227999).
- Core and Builtins
- gh-122208: Dictionary watchers now only deliver the
PyDict_EVENT_ADDED event when the insertion is in a known
good state to succeed.
- gh-122300: Preserve AST nodes for f-string with
single-element format specifiers. Patch by Pablo Galindo
- gh-122029: Emit c_call events in sys.setprofile() when a
PyMethodObject pointing to a PyCFunction is called.
- gh-122029: Emit c_call events in sys.setprofile() when
a PyMethodObject pointing to a PyCFunction is called.
- gh-122026: Fix a bug that caused the tokenizer to not
correctly identify mismatched parentheses inside f-strings
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
list_ass_subscript, which could be invoked via some
specificly tailored input: including concurrent
modification of a list object, where one thread assigns a
slice and another clears it.
modification of a list object, where one thread assigns
a slice and another clears it.
- gh-120380: Fix Python implementation of pickle.Pickler for
bytes and bytearray objects when using protocol version
5. Patch by Bénédikt Tran.
bytes and bytearray objects when using protocol version 5.
Patch by Bénédikt Tran.
- gh-93691: Fix source locations of instructions generated
for the iterator of a for statement.
- gh-120198: Fix a crash when multiple threads read and write

View File

@@ -204,6 +204,25 @@ Patch50: CVE-2025-12084-minidom-quad-search.patch
# PATCH-FIX-UPSTREAM CVE-2025-13837-plistlib-mailicious-length.patch bsc#1254401 mcepl@suse.com
# protect against OOM when loading malicious content
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
### END OF PATCHES
BuildRequires: autoconf-archive
BuildRequires: automake
BuildRequires: fdupes