forked from pool/python311
Compare commits
1 Commits
factory
...
sle-15-sp6
| Author | SHA256 | Date | |
|---|---|---|---|
|
407aa84e9d
|
@@ -1,15 +1,15 @@
|
||||
---
|
||||
Lib/test/support/__init__.py | 22 ++++++++++++++++------
|
||||
Lib/test/support/__init__.py | 16 ++++++++++++++--
|
||||
Lib/test/test_minidom.py | 23 +++++++++--------------
|
||||
Lib/test/test_pyexpat.py | 12 +++++-------
|
||||
Lib/test/test_sax.py | 18 +++++++++---------
|
||||
Lib/test/test_xml_etree.py | 12 ------------
|
||||
5 files changed, 39 insertions(+), 48 deletions(-)
|
||||
5 files changed, 37 insertions(+), 44 deletions(-)
|
||||
|
||||
Index: Python-3.11.15/Lib/test/support/__init__.py
|
||||
Index: Python-3.11.14/Lib/test/support/__init__.py
|
||||
===================================================================
|
||||
--- Python-3.11.15.orig/Lib/test/support/__init__.py 2026-03-09 00:22:05.833623479 +0100
|
||||
+++ Python-3.11.15/Lib/test/support/__init__.py 2026-03-09 00:25:45.751482485 +0100
|
||||
--- Python-3.11.14.orig/Lib/test/support/__init__.py 2025-11-15 19:15:08.449938538 +0100
|
||||
+++ Python-3.11.14/Lib/test/support/__init__.py 2025-11-15 19:15:12.859120260 +0100
|
||||
@@ -8,6 +8,7 @@
|
||||
import functools
|
||||
import os
|
||||
@@ -18,7 +18,7 @@ Index: Python-3.11.15/Lib/test/support/__init__.py
|
||||
import stat
|
||||
import sys
|
||||
import sysconfig
|
||||
@@ -56,10 +57,9 @@
|
||||
@@ -56,7 +57,7 @@
|
||||
"run_with_tz", "PGO", "missing_compiler_executable",
|
||||
"ALWAYS_EQ", "NEVER_EQ", "LARGEST", "SMALLEST",
|
||||
"LOOPBACK_TIMEOUT", "INTERNET_TIMEOUT", "SHORT_TIMEOUT", "LONG_TIMEOUT",
|
||||
@@ -26,48 +26,39 @@ Index: Python-3.11.15/Lib/test/support/__init__.py
|
||||
+ "skip_on_s390x", "fails_with_expat_2_6_0", "is_expat_2_6_0"
|
||||
]
|
||||
|
||||
-
|
||||
# Timeout in seconds for tests using a network server listening on the network
|
||||
# local loopback interface like 127.0.0.1.
|
||||
#
|
||||
@@ -2279,10 +2279,20 @@
|
||||
|
||||
@@ -2279,6 +2280,17 @@
|
||||
}
|
||||
return ignored
|
||||
|
||||
-#Windows doesn't have os.uname() but it doesn't support s390x.
|
||||
-skip_on_s390x = unittest.skipIf(hasattr(os, 'uname') and os.uname().machine == 's390x',
|
||||
- 'skipped on s390x')
|
||||
-
|
||||
+
|
||||
+# Windows doesn't have os.uname() but it doesn't support s390x.
|
||||
+skip_on_s390x = unittest.skipIf(
|
||||
+ hasattr(os, 'uname') and os.uname().machine == 's390x',
|
||||
+ 'skipped on s390x')
|
||||
skip_on_s390x = unittest.skipIf(hasattr(os, 'uname') and os.uname().machine == 's390x',
|
||||
'skipped on s390x')
|
||||
+
|
||||
+
|
||||
+@functools.lru_cache
|
||||
+def _is_expat_2_6_0():
|
||||
+ return hasattr(pyexpat.ParserCreate(), 'SetReparseDeferralEnabled')
|
||||
+
|
||||
+is_expat_2_6_0 = _is_expat_2_6_0()
|
||||
+
|
||||
+fails_with_expat_2_6_0 = (unittest.expectedFailure
|
||||
+ if is_expat_2_6_0
|
||||
+ else lambda test: test)
|
||||
|
||||
def control_characters_c0() -> list[str]:
|
||||
"""Returns a list of C0 control characters as strings.
|
||||
Index: Python-3.11.15/Lib/test/test_minidom.py
|
||||
Index: Python-3.11.14/Lib/test/test_minidom.py
|
||||
===================================================================
|
||||
--- Python-3.11.15.orig/Lib/test/test_minidom.py 2026-03-09 00:22:01.870138109 +0100
|
||||
+++ Python-3.11.15/Lib/test/test_minidom.py 2026-03-09 00:22:05.864561664 +0100
|
||||
@@ -7,7 +7,6 @@
|
||||
--- Python-3.11.14.orig/Lib/test/test_minidom.py 2025-11-15 19:14:53.915952608 +0100
|
||||
+++ Python-3.11.14/Lib/test/test_minidom.py 2025-11-15 19:15:12.859877278 +0100
|
||||
@@ -6,7 +6,6 @@
|
||||
from test import support
|
||||
import unittest
|
||||
|
||||
-import pyexpat
|
||||
import xml.dom.minidom
|
||||
|
||||
from xml.dom.minidom import parse, Attr, Node, Document, Element, parseString
|
||||
@@ -1194,13 +1193,11 @@
|
||||
from xml.dom.minidom import parse, Attr, Node, Document, parseString
|
||||
@@ -1163,13 +1162,11 @@
|
||||
|
||||
# Verify that character decoding errors raise exceptions instead
|
||||
# of crashing
|
||||
@@ -86,7 +77,7 @@ Index: Python-3.11.15/Lib/test/test_minidom.py
|
||||
b'<fran\xe7ais>Comment \xe7a va ? Tr\xe8s bien ?</fran\xe7ais>')
|
||||
|
||||
doc.unlink()
|
||||
@@ -1662,12 +1659,10 @@
|
||||
@@ -1631,12 +1628,10 @@
|
||||
self.confirm(doc2.namespaceURI == xml.dom.EMPTY_NAMESPACE)
|
||||
|
||||
def testExceptionOnSpacesInXMLNSValue(self):
|
||||
@@ -103,11 +94,11 @@ Index: Python-3.11.15/Lib/test/test_minidom.py
|
||||
parseString('<element xmlns:abc="http:abc.com/de f g/hi/j k"><abc:foo /></element>')
|
||||
|
||||
def testDocRemoveChild(self):
|
||||
Index: Python-3.11.15/Lib/test/test_pyexpat.py
|
||||
Index: Python-3.11.14/Lib/test/test_pyexpat.py
|
||||
===================================================================
|
||||
--- Python-3.11.15.orig/Lib/test/test_pyexpat.py 2026-03-09 00:22:02.085337730 +0100
|
||||
+++ Python-3.11.15/Lib/test/test_pyexpat.py 2026-03-09 00:22:21.434819111 +0100
|
||||
@@ -18,8 +18,7 @@
|
||||
--- Python-3.11.14.orig/Lib/test/test_pyexpat.py 2025-11-15 19:14:53.915952608 +0100
|
||||
+++ Python-3.11.14/Lib/test/test_pyexpat.py 2025-11-15 19:15:12.860334045 +0100
|
||||
@@ -14,8 +14,7 @@
|
||||
from xml.parsers import expat
|
||||
from xml.parsers.expat import errors
|
||||
|
||||
@@ -117,7 +108,7 @@ Index: Python-3.11.15/Lib/test/test_pyexpat.py
|
||||
|
||||
class SetAttributeTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
@@ -810,9 +809,8 @@
|
||||
@@ -806,9 +805,8 @@
|
||||
self.assertIs(parser.GetReparseDeferralEnabled(), enabled)
|
||||
|
||||
def test_reparse_deferral_enabled(self):
|
||||
@@ -129,7 +120,7 @@ Index: Python-3.11.15/Lib/test/test_pyexpat.py
|
||||
|
||||
started = []
|
||||
|
||||
@@ -841,9 +839,9 @@
|
||||
@@ -837,9 +835,9 @@
|
||||
|
||||
parser = expat.ParserCreate()
|
||||
parser.StartElementHandler = start_element
|
||||
@@ -141,10 +132,10 @@ Index: Python-3.11.15/Lib/test/test_pyexpat.py
|
||||
|
||||
for chunk in (b'<doc', b'/>'):
|
||||
parser.Parse(chunk, False)
|
||||
Index: Python-3.11.15/Lib/test/test_sax.py
|
||||
Index: Python-3.11.14/Lib/test/test_sax.py
|
||||
===================================================================
|
||||
--- Python-3.11.15.orig/Lib/test/test_sax.py 2026-03-09 00:22:02.128712585 +0100
|
||||
+++ Python-3.11.15/Lib/test/test_sax.py 2026-03-09 00:22:21.434819111 +0100
|
||||
--- Python-3.11.14.orig/Lib/test/test_sax.py 2025-11-15 19:14:53.915952608 +0100
|
||||
+++ Python-3.11.14/Lib/test/test_sax.py 2025-11-15 19:15:12.860746114 +0100
|
||||
@@ -19,13 +19,11 @@
|
||||
from io import BytesIO, StringIO
|
||||
import codecs
|
||||
@@ -196,10 +187,10 @@ Index: Python-3.11.15/Lib/test/test_sax.py
|
||||
|
||||
self.assertFalse(parser._parser.GetReparseDeferralEnabled())
|
||||
|
||||
Index: Python-3.11.15/Lib/test/test_xml_etree.py
|
||||
Index: Python-3.11.14/Lib/test/test_xml_etree.py
|
||||
===================================================================
|
||||
--- Python-3.11.15.orig/Lib/test/test_xml_etree.py 2026-03-09 00:22:02.529714798 +0100
|
||||
+++ Python-3.11.15/Lib/test/test_xml_etree.py 2026-03-09 00:22:21.434819111 +0100
|
||||
--- Python-3.11.14.orig/Lib/test/test_xml_etree.py 2025-11-15 19:14:53.915952608 +0100
|
||||
+++ Python-3.11.14/Lib/test/test_xml_etree.py 2025-11-15 19:15:12.861491049 +0100
|
||||
@@ -13,7 +13,6 @@
|
||||
import operator
|
||||
import os
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
Lib/test/test_xml_etree.py | 2 ++
|
||||
3 files changed, 6 insertions(+)
|
||||
|
||||
Index: Python-3.11.15/Lib/test/test_pyexpat.py
|
||||
Index: Python-3.11.14/Lib/test/test_pyexpat.py
|
||||
===================================================================
|
||||
--- Python-3.11.15.orig/Lib/test/test_pyexpat.py 2026-03-06 16:07:07.713428031 +0100
|
||||
+++ Python-3.11.15/Lib/test/test_pyexpat.py 2026-03-06 18:23:34.307976750 +0100
|
||||
@@ -808,6 +808,7 @@
|
||||
--- Python-3.11.14.orig/Lib/test/test_pyexpat.py 2025-11-15 19:15:12.860334045 +0100
|
||||
+++ Python-3.11.14/Lib/test/test_pyexpat.py 2025-11-15 19:15:15.541090355 +0100
|
||||
@@ -804,6 +804,7 @@
|
||||
parser.SetReparseDeferralEnabled(True)
|
||||
self.assertIs(parser.GetReparseDeferralEnabled(), enabled)
|
||||
|
||||
@@ -16,7 +16,7 @@ Index: Python-3.11.15/Lib/test/test_pyexpat.py
|
||||
def test_reparse_deferral_enabled(self):
|
||||
if not is_expat_2_6_0:
|
||||
self.skipTest("Linked libexpat doesn't support reparse deferral")
|
||||
@@ -831,6 +832,7 @@
|
||||
@@ -827,6 +828,7 @@
|
||||
|
||||
self.assertEqual(started, ['doc'])
|
||||
|
||||
@@ -24,10 +24,10 @@ Index: Python-3.11.15/Lib/test/test_pyexpat.py
|
||||
def test_reparse_deferral_disabled(self):
|
||||
started = []
|
||||
|
||||
Index: Python-3.11.15/Lib/test/test_sax.py
|
||||
Index: Python-3.11.14/Lib/test/test_sax.py
|
||||
===================================================================
|
||||
--- Python-3.11.15.orig/Lib/test/test_sax.py 2026-03-06 16:07:07.713855947 +0100
|
||||
+++ Python-3.11.15/Lib/test/test_sax.py 2026-03-06 18:23:34.309155833 +0100
|
||||
--- Python-3.11.14.orig/Lib/test/test_sax.py 2025-11-15 19:15:12.860746114 +0100
|
||||
+++ Python-3.11.14/Lib/test/test_sax.py 2025-11-15 19:15:15.541608234 +0100
|
||||
@@ -1213,6 +1213,7 @@
|
||||
|
||||
self.assertEqual(result.getvalue(), start + b"<doc>text</doc>")
|
||||
@@ -44,10 +44,10 @@ Index: Python-3.11.15/Lib/test/test_sax.py
|
||||
def test_flush_reparse_deferral_disabled(self):
|
||||
if not is_expat_2_6_0:
|
||||
self.skipTest("Linked libexpat doesn't support reparse deferral")
|
||||
Index: Python-3.11.15/Lib/test/test_xml_etree.py
|
||||
Index: Python-3.11.14/Lib/test/test_xml_etree.py
|
||||
===================================================================
|
||||
--- Python-3.11.15.orig/Lib/test/test_xml_etree.py 2026-03-06 16:07:07.714503769 +0100
|
||||
+++ Python-3.11.15/Lib/test/test_xml_etree.py 2026-03-06 18:23:34.309977052 +0100
|
||||
--- Python-3.11.14.orig/Lib/test/test_xml_etree.py 2025-11-15 19:15:12.861491049 +0100
|
||||
+++ Python-3.11.14/Lib/test/test_xml_etree.py 2025-11-15 19:15:15.542327817 +0100
|
||||
@@ -1620,6 +1620,7 @@
|
||||
with self.assertRaises(ValueError):
|
||||
ET.XMLPullParser(events=('start', 'end', 'bogus'))
|
||||
|
||||
@@ -1,193 +0,0 @@
|
||||
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.11.15/Doc/library/base64.rst
|
||||
===================================================================
|
||||
--- Python-3.11.15.orig/Doc/library/base64.rst 2026-03-03 01:52:57.000000000 +0100
|
||||
+++ Python-3.11.15/Doc/library/base64.rst 2026-03-06 19:52:36.492967768 +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.11.15/Lib/base64.py
|
||||
===================================================================
|
||||
--- Python-3.11.15.orig/Lib/base64.py 2026-03-06 16:06:30.195774827 +0100
|
||||
+++ Python-3.11.15/Lib/base64.py 2026-03-06 19:52:36.493488040 +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.11.15/Lib/test/test_base64.py
|
||||
===================================================================
|
||||
--- Python-3.11.15.orig/Lib/test/test_base64.py 2026-03-06 16:06:32.552854037 +0100
|
||||
+++ Python-3.11.15/Lib/test/test_base64.py 2026-03-06 19:52:36.494050069 +0100
|
||||
@@ -228,6 +228,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')
|
||||
@@ -259,10 +278,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.11.15/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.11.15/Misc/NEWS.d/next/Library/2025-11-06-12-03-29.gh-issue-125346.7Gfpgw.rst 2026-03-06 19:52:36.494404708 +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.
|
||||
@@ -1,38 +0,0 @@
|
||||
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.11.15/Lib/imaplib.py
|
||||
===================================================================
|
||||
--- Python-3.11.15.orig/Lib/imaplib.py 2026-03-06 16:06:31.545110864 +0100
|
||||
+++ Python-3.11.15/Lib/imaplib.py 2026-03-06 19:51:51.838695961 +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.11.15/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.11.15/Misc/NEWS.d/next/Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst 2026-03-06 19:51:51.839096617 +0100
|
||||
@@ -0,0 +1 @@
|
||||
+Reject control characters in IMAP commands.
|
||||
@@ -1,56 +0,0 @@
|
||||
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.11.15/Lib/poplib.py
|
||||
===================================================================
|
||||
--- Python-3.11.15.orig/Lib/poplib.py 2026-03-06 16:06:32.025693538 +0100
|
||||
+++ Python-3.11.15/Lib/poplib.py 2026-03-06 19:52:31.051258464 +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.11.15/Lib/test/test_poplib.py
|
||||
===================================================================
|
||||
--- Python-3.11.15.orig/Lib/test/test_poplib.py 2026-03-06 16:06:33.708669394 +0100
|
||||
+++ Python-3.11.15/Lib/test/test_poplib.py 2026-03-06 19:52:31.052258474 +0100
|
||||
@@ -16,6 +16,7 @@
|
||||
from test.support import socket_helper
|
||||
from test.support import threading_helper
|
||||
from test.support import warnings_helper
|
||||
+from test.support import control_characters_c0
|
||||
|
||||
|
||||
asynchat = warnings_helper.import_deprecated('asynchat')
|
||||
@@ -367,6 +368,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.11.15/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.11.15/Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst 2026-03-06 19:52:31.053950556 +0100
|
||||
@@ -0,0 +1 @@
|
||||
+Reject control characters in POP3 commands.
|
||||
359
CVE-2025-6075-expandvars-perf-degrad.patch
Normal file
359
CVE-2025-6075-expandvars-perf-degrad.patch
Normal file
@@ -0,0 +1,359 @@
|
||||
From e717839989908ecea9c1c8f3bd17ec9fb1ac8963 Mon Sep 17 00:00:00 2001
|
||||
From: Serhiy Storchaka <storchaka@gmail.com>
|
||||
Date: Fri, 31 Oct 2025 15:49:51 +0200
|
||||
Subject: [PATCH] [3.11] gh-136065: Fix quadratic complexity in
|
||||
os.path.expandvars() (GH-134952) (cherry picked from commit
|
||||
f029e8db626ddc6e3a3beea4eff511a71aaceb5c)
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
|
||||
Co-authored-by: Łukasz Langa <lukasz@langa.pl>
|
||||
---
|
||||
Lib/ntpath.py | 126 +++-------
|
||||
Lib/posixpath.py | 43 +--
|
||||
Lib/test/test_genericpath.py | 14 +
|
||||
Lib/test/test_ntpath.py | 22 +
|
||||
Misc/NEWS.d/next/Security/2025-05-30-22-33-27.gh-issue-136065.bu337o.rst | 1
|
||||
5 files changed, 94 insertions(+), 112 deletions(-)
|
||||
create mode 100644 Misc/NEWS.d/next/Security/2025-05-30-22-33-27.gh-issue-136065.bu337o.rst
|
||||
|
||||
Index: Python-3.11.14/Lib/ntpath.py
|
||||
===================================================================
|
||||
--- Python-3.11.14.orig/Lib/ntpath.py 2025-11-15 19:14:27.424009612 +0100
|
||||
+++ Python-3.11.14/Lib/ntpath.py 2025-11-15 19:14:41.389069009 +0100
|
||||
@@ -378,17 +378,23 @@
|
||||
# XXX With COMMAND.COM you can use any characters in a variable name,
|
||||
# XXX except '^|<>='.
|
||||
|
||||
+_varpattern = r"'[^']*'?|%(%|[^%]*%?)|\$(\$|[-\w]+|\{[^}]*\}?)"
|
||||
+_varsub = None
|
||||
+_varsubb = None
|
||||
+
|
||||
def expandvars(path):
|
||||
"""Expand shell variables of the forms $var, ${var} and %var%.
|
||||
|
||||
Unknown variables are left unchanged."""
|
||||
path = os.fspath(path)
|
||||
+ global _varsub, _varsubb
|
||||
if isinstance(path, bytes):
|
||||
if b'$' not in path and b'%' not in path:
|
||||
return path
|
||||
- import string
|
||||
- varchars = bytes(string.ascii_letters + string.digits + '_-', 'ascii')
|
||||
- quote = b'\''
|
||||
+ if not _varsubb:
|
||||
+ import re
|
||||
+ _varsubb = re.compile(_varpattern.encode(), re.ASCII).sub
|
||||
+ sub = _varsubb
|
||||
percent = b'%'
|
||||
brace = b'{'
|
||||
rbrace = b'}'
|
||||
@@ -397,94 +403,44 @@
|
||||
else:
|
||||
if '$' not in path and '%' not in path:
|
||||
return path
|
||||
- import string
|
||||
- varchars = string.ascii_letters + string.digits + '_-'
|
||||
- quote = '\''
|
||||
+ if not _varsub:
|
||||
+ import re
|
||||
+ _varsub = re.compile(_varpattern, re.ASCII).sub
|
||||
+ sub = _varsub
|
||||
percent = '%'
|
||||
brace = '{'
|
||||
rbrace = '}'
|
||||
dollar = '$'
|
||||
environ = os.environ
|
||||
- res = path[:0]
|
||||
- index = 0
|
||||
- pathlen = len(path)
|
||||
- while index < pathlen:
|
||||
- c = path[index:index+1]
|
||||
- if c == quote: # no expansion within single quotes
|
||||
- path = path[index + 1:]
|
||||
- pathlen = len(path)
|
||||
- try:
|
||||
- index = path.index(c)
|
||||
- res += c + path[:index + 1]
|
||||
- except ValueError:
|
||||
- res += c + path
|
||||
- index = pathlen - 1
|
||||
- elif c == percent: # variable or '%'
|
||||
- if path[index + 1:index + 2] == percent:
|
||||
- res += c
|
||||
- index += 1
|
||||
- else:
|
||||
- path = path[index+1:]
|
||||
- pathlen = len(path)
|
||||
- try:
|
||||
- index = path.index(percent)
|
||||
- except ValueError:
|
||||
- res += percent + path
|
||||
- index = pathlen - 1
|
||||
- else:
|
||||
- var = path[:index]
|
||||
- try:
|
||||
- if environ is None:
|
||||
- value = os.fsencode(os.environ[os.fsdecode(var)])
|
||||
- else:
|
||||
- value = environ[var]
|
||||
- except KeyError:
|
||||
- value = percent + var + percent
|
||||
- res += value
|
||||
- elif c == dollar: # variable or '$$'
|
||||
- if path[index + 1:index + 2] == dollar:
|
||||
- res += c
|
||||
- index += 1
|
||||
- elif path[index + 1:index + 2] == brace:
|
||||
- path = path[index+2:]
|
||||
- pathlen = len(path)
|
||||
- try:
|
||||
- index = path.index(rbrace)
|
||||
- except ValueError:
|
||||
- res += dollar + brace + path
|
||||
- index = pathlen - 1
|
||||
- else:
|
||||
- var = path[:index]
|
||||
- try:
|
||||
- if environ is None:
|
||||
- value = os.fsencode(os.environ[os.fsdecode(var)])
|
||||
- else:
|
||||
- value = environ[var]
|
||||
- except KeyError:
|
||||
- value = dollar + brace + var + rbrace
|
||||
- res += value
|
||||
- else:
|
||||
- var = path[:0]
|
||||
- index += 1
|
||||
- c = path[index:index + 1]
|
||||
- while c and c in varchars:
|
||||
- var += c
|
||||
- index += 1
|
||||
- c = path[index:index + 1]
|
||||
- try:
|
||||
- if environ is None:
|
||||
- value = os.fsencode(os.environ[os.fsdecode(var)])
|
||||
- else:
|
||||
- value = environ[var]
|
||||
- except KeyError:
|
||||
- value = dollar + var
|
||||
- res += value
|
||||
- if c:
|
||||
- index -= 1
|
||||
+
|
||||
+ def repl(m):
|
||||
+ lastindex = m.lastindex
|
||||
+ if lastindex is None:
|
||||
+ return m[0]
|
||||
+ name = m[lastindex]
|
||||
+ if lastindex == 1:
|
||||
+ if name == percent:
|
||||
+ return name
|
||||
+ if not name.endswith(percent):
|
||||
+ return m[0]
|
||||
+ name = name[:-1]
|
||||
else:
|
||||
- res += c
|
||||
- index += 1
|
||||
- return res
|
||||
+ if name == dollar:
|
||||
+ return name
|
||||
+ if name.startswith(brace):
|
||||
+ if not name.endswith(rbrace):
|
||||
+ return m[0]
|
||||
+ name = name[1:-1]
|
||||
+
|
||||
+ try:
|
||||
+ if environ is None:
|
||||
+ return os.fsencode(os.environ[os.fsdecode(name)])
|
||||
+ else:
|
||||
+ return environ[name]
|
||||
+ except KeyError:
|
||||
+ return m[0]
|
||||
+
|
||||
+ return sub(repl, path)
|
||||
|
||||
|
||||
# Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A\B.
|
||||
Index: Python-3.11.14/Lib/posixpath.py
|
||||
===================================================================
|
||||
--- Python-3.11.14.orig/Lib/posixpath.py 2025-11-15 19:14:27.465471369 +0100
|
||||
+++ Python-3.11.14/Lib/posixpath.py 2025-11-15 19:14:41.389334199 +0100
|
||||
@@ -287,42 +287,41 @@
|
||||
# This expands the forms $variable and ${variable} only.
|
||||
# Non-existent variables are left unchanged.
|
||||
|
||||
-_varprog = None
|
||||
-_varprogb = None
|
||||
+_varpattern = r'\$(\w+|\{[^}]*\}?)'
|
||||
+_varsub = None
|
||||
+_varsubb = None
|
||||
|
||||
def expandvars(path):
|
||||
"""Expand shell variables of form $var and ${var}. Unknown variables
|
||||
are left unchanged."""
|
||||
path = os.fspath(path)
|
||||
- global _varprog, _varprogb
|
||||
+ global _varsub, _varsubb
|
||||
if isinstance(path, bytes):
|
||||
if b'$' not in path:
|
||||
return path
|
||||
- if not _varprogb:
|
||||
+ if not _varsubb:
|
||||
import re
|
||||
- _varprogb = re.compile(br'\$(\w+|\{[^}]*\})', re.ASCII)
|
||||
- search = _varprogb.search
|
||||
+ _varsubb = re.compile(_varpattern.encode(), re.ASCII).sub
|
||||
+ sub = _varsubb
|
||||
start = b'{'
|
||||
end = b'}'
|
||||
environ = getattr(os, 'environb', None)
|
||||
else:
|
||||
if '$' not in path:
|
||||
return path
|
||||
- if not _varprog:
|
||||
+ if not _varsub:
|
||||
import re
|
||||
- _varprog = re.compile(r'\$(\w+|\{[^}]*\})', re.ASCII)
|
||||
- search = _varprog.search
|
||||
+ _varsub = re.compile(_varpattern, re.ASCII).sub
|
||||
+ sub = _varsub
|
||||
start = '{'
|
||||
end = '}'
|
||||
environ = os.environ
|
||||
- i = 0
|
||||
- while True:
|
||||
- m = search(path, i)
|
||||
- if not m:
|
||||
- break
|
||||
- i, j = m.span(0)
|
||||
- name = m.group(1)
|
||||
- if name.startswith(start) and name.endswith(end):
|
||||
+
|
||||
+ def repl(m):
|
||||
+ name = m[1]
|
||||
+ if name.startswith(start):
|
||||
+ if not name.endswith(end):
|
||||
+ return m[0]
|
||||
name = name[1:-1]
|
||||
try:
|
||||
if environ is None:
|
||||
@@ -330,13 +329,11 @@
|
||||
else:
|
||||
value = environ[name]
|
||||
except KeyError:
|
||||
- i = j
|
||||
+ return m[0]
|
||||
else:
|
||||
- tail = path[j:]
|
||||
- path = path[:i] + value
|
||||
- i = len(path)
|
||||
- path += tail
|
||||
- return path
|
||||
+ return value
|
||||
+
|
||||
+ return sub(repl, path)
|
||||
|
||||
|
||||
# Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A/B.
|
||||
Index: Python-3.11.14/Lib/test/test_genericpath.py
|
||||
===================================================================
|
||||
--- Python-3.11.14.orig/Lib/test/test_genericpath.py 2025-11-15 19:14:28.470950071 +0100
|
||||
+++ Python-3.11.14/Lib/test/test_genericpath.py 2025-11-15 19:14:41.389533528 +0100
|
||||
@@ -7,6 +7,7 @@
|
||||
import sys
|
||||
import unittest
|
||||
import warnings
|
||||
+from test import support
|
||||
from test.support import is_emscripten
|
||||
from test.support import os_helper
|
||||
from test.support import warnings_helper
|
||||
@@ -434,6 +435,19 @@
|
||||
os.fsencode('$bar%s bar' % nonascii))
|
||||
check(b'$spam}bar', os.fsencode('%s}bar' % nonascii))
|
||||
|
||||
+ @support.requires_resource('cpu')
|
||||
+ def test_expandvars_large(self):
|
||||
+ expandvars = self.pathmodule.expandvars
|
||||
+ with os_helper.EnvironmentVarGuard() as env:
|
||||
+ env.clear()
|
||||
+ env["A"] = "B"
|
||||
+ n = 100_000
|
||||
+ self.assertEqual(expandvars('$A'*n), 'B'*n)
|
||||
+ self.assertEqual(expandvars('${A}'*n), 'B'*n)
|
||||
+ self.assertEqual(expandvars('$A!'*n), 'B!'*n)
|
||||
+ self.assertEqual(expandvars('${A}A'*n), 'BA'*n)
|
||||
+ self.assertEqual(expandvars('${'*10*n), '${'*10*n)
|
||||
+
|
||||
def test_abspath(self):
|
||||
self.assertIn("foo", self.pathmodule.abspath("foo"))
|
||||
with warnings.catch_warnings():
|
||||
Index: Python-3.11.14/Lib/test/test_ntpath.py
|
||||
===================================================================
|
||||
--- Python-3.11.14.orig/Lib/test/test_ntpath.py 2025-11-15 19:14:29.042372971 +0100
|
||||
+++ Python-3.11.14/Lib/test/test_ntpath.py 2025-11-15 19:14:41.389799697 +0100
|
||||
@@ -6,8 +6,8 @@
|
||||
import unittest
|
||||
import warnings
|
||||
from ntpath import ALLOW_MISSING
|
||||
-from test.support import os_helper
|
||||
-from test.support import TestFailed, is_emscripten
|
||||
+from test import support
|
||||
+from test.support import os_helper, is_emscripten
|
||||
from test.support.os_helper import FakePath
|
||||
from test import test_genericpath
|
||||
from tempfile import TemporaryFile
|
||||
@@ -57,7 +57,7 @@
|
||||
fn = fn.replace("\\", "\\\\")
|
||||
gotResult = eval(fn)
|
||||
if wantResult != gotResult and _norm(wantResult) != _norm(gotResult):
|
||||
- raise TestFailed("%s should return: %s but returned: %s" \
|
||||
+ raise support.TestFailed("%s should return: %s but returned: %s" \
|
||||
%(str(fn), str(wantResult), str(gotResult)))
|
||||
|
||||
# then with bytes
|
||||
@@ -73,7 +73,7 @@
|
||||
warnings.simplefilter("ignore", DeprecationWarning)
|
||||
gotResult = eval(fn)
|
||||
if _norm(wantResult) != _norm(gotResult):
|
||||
- raise TestFailed("%s should return: %s but returned: %s" \
|
||||
+ raise support.TestFailed("%s should return: %s but returned: %s" \
|
||||
%(str(fn), str(wantResult), repr(gotResult)))
|
||||
|
||||
|
||||
@@ -820,6 +820,19 @@
|
||||
check('%spam%bar', '%sbar' % nonascii)
|
||||
check('%{}%bar'.format(nonascii), 'ham%sbar' % nonascii)
|
||||
|
||||
+ @support.requires_resource('cpu')
|
||||
+ def test_expandvars_large(self):
|
||||
+ expandvars = ntpath.expandvars
|
||||
+ with os_helper.EnvironmentVarGuard() as env:
|
||||
+ env.clear()
|
||||
+ env["A"] = "B"
|
||||
+ n = 100_000
|
||||
+ self.assertEqual(expandvars('%A%'*n), 'B'*n)
|
||||
+ self.assertEqual(expandvars('%A%A'*n), 'BA'*n)
|
||||
+ self.assertEqual(expandvars("''"*n + '%%'), "''"*n + '%')
|
||||
+ self.assertEqual(expandvars("%%"*n), "%"*n)
|
||||
+ self.assertEqual(expandvars("$$"*n), "$"*n)
|
||||
+
|
||||
def test_expanduser(self):
|
||||
tester('ntpath.expanduser("test")', 'test')
|
||||
|
||||
@@ -1090,6 +1103,7 @@
|
||||
self.assertIsInstance(b_final_path, bytes)
|
||||
self.assertGreater(len(b_final_path), 0)
|
||||
|
||||
+
|
||||
class NtCommonTest(test_genericpath.CommonTest, unittest.TestCase):
|
||||
pathmodule = ntpath
|
||||
attributes = ['relpath']
|
||||
Index: Python-3.11.14/Misc/NEWS.d/next/Security/2025-05-30-22-33-27.gh-issue-136065.bu337o.rst
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ Python-3.11.14/Misc/NEWS.d/next/Security/2025-05-30-22-33-27.gh-issue-136065.bu337o.rst 2025-11-15 19:14:41.390091148 +0100
|
||||
@@ -0,0 +1 @@
|
||||
+Fix quadratic complexity in :func:`os.path.expandvars`.
|
||||
BIN
Python-3.11.14.tar.xz
LFS
Normal file
BIN
Python-3.11.14.tar.xz
LFS
Normal file
Binary file not shown.
1
Python-3.11.14.tar.xz.sigstore
Normal file
1
Python-3.11.14.tar.xz.sigstore
Normal file
File diff suppressed because one or more lines are too long
BIN
Python-3.11.15.tar.xz
LFS
BIN
Python-3.11.15.tar.xz
LFS
Binary file not shown.
File diff suppressed because one or more lines are too long
@@ -12,11 +12,9 @@ for the definition of this variable.
|
||||
Doc/library/functions.rst | 2 +-
|
||||
2 files changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
Index: Python-3.11.15/Doc/conf.py
|
||||
===================================================================
|
||||
--- Python-3.11.15.orig/Doc/conf.py 2026-03-03 01:52:57.000000000 +0100
|
||||
+++ Python-3.11.15/Doc/conf.py 2026-03-06 18:23:39.828089970 +0100
|
||||
@@ -316,7 +316,8 @@
|
||||
--- a/Doc/conf.py
|
||||
+++ b/Doc/conf.py
|
||||
@@ -316,7 +316,8 @@ html_context = {
|
||||
}
|
||||
|
||||
# This 'Last updated on:' timestamp is inserted at the bottom of every page.
|
||||
@@ -26,11 +24,9 @@ Index: Python-3.11.15/Doc/conf.py
|
||||
|
||||
# Path to find HTML templates.
|
||||
templates_path = ['tools/templates']
|
||||
Index: Python-3.11.15/Doc/library/functions.rst
|
||||
===================================================================
|
||||
--- Python-3.11.15.orig/Doc/library/functions.rst 2026-03-03 01:52:57.000000000 +0100
|
||||
+++ Python-3.11.15/Doc/library/functions.rst 2026-03-06 18:23:39.829089979 +0100
|
||||
@@ -1356,7 +1356,7 @@
|
||||
--- a/Doc/library/functions.rst
|
||||
+++ b/Doc/library/functions.rst
|
||||
@@ -1356,7 +1356,7 @@ are always available. They are listed h
|
||||
(where :func:`open` is declared), :mod:`os`, :mod:`os.path`, :mod:`tempfile`,
|
||||
and :mod:`shutil`.
|
||||
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
Misc/NEWS | 2 +-
|
||||
2 files changed, 1 insertion(+), 4 deletions(-)
|
||||
|
||||
Index: Python-3.11.15/Doc/using/configure.rst
|
||||
Index: Python-3.11.14/Doc/using/configure.rst
|
||||
===================================================================
|
||||
--- Python-3.11.15.orig/Doc/using/configure.rst 2026-03-06 16:06:43.304945441 +0100
|
||||
+++ Python-3.11.15/Doc/using/configure.rst 2026-03-06 16:06:55.576758292 +0100
|
||||
--- Python-3.11.14.orig/Doc/using/configure.rst 2025-11-15 19:14:54.096952433 +0100
|
||||
+++ Python-3.11.14/Doc/using/configure.rst 2025-11-15 19:15:04.439920979 +0100
|
||||
@@ -43,7 +43,6 @@
|
||||
|
||||
See :data:`sys.int_info.bits_per_digit <sys.int_info>`.
|
||||
@@ -29,11 +29,11 @@ Index: Python-3.11.15/Doc/using/configure.rst
|
||||
.. option:: --enable-framework=INSTALLDIR
|
||||
|
||||
Create a Python.framework rather than a traditional Unix install. Optional
|
||||
Index: Python-3.11.15/Misc/NEWS
|
||||
Index: Python-3.11.14/Misc/NEWS
|
||||
===================================================================
|
||||
--- Python-3.11.15.orig/Misc/NEWS 2026-03-06 16:06:43.304945441 +0100
|
||||
+++ Python-3.11.15/Misc/NEWS 2026-03-06 16:06:55.580059032 +0100
|
||||
@@ -10081,7 +10081,7 @@
|
||||
--- Python-3.11.14.orig/Misc/NEWS 2025-11-15 19:14:54.096952433 +0100
|
||||
+++ Python-3.11.14/Misc/NEWS 2025-11-15 19:15:04.445942414 +0100
|
||||
@@ -9987,7 +9987,7 @@
|
||||
- bpo-40939: Removed documentation for the removed ``PyParser_*`` C API.
|
||||
|
||||
- bpo-43795: The list in :ref:`limited-api-list` now shows the public name
|
||||
|
||||
@@ -1,133 +1,3 @@
|
||||
-------------------------------------------------------------------
|
||||
Fri Mar 6 18:54:51 UTC 2026 - Matej Cepl <mcepl@cepl.eu>
|
||||
|
||||
- Update to 3.11.15:
|
||||
- Security
|
||||
- gh-144125: BytesGenerator will now refuse to serialize
|
||||
(write) headers that are unsafely folded or delimited; see
|
||||
verify_generated_headers. (Contributed by Bas Bloemsaat and
|
||||
Petr Viktorin in gh-121650).
|
||||
- gh-143935: Fixed a bug in the folding of comments when
|
||||
flattening an email message using a modern email policy.
|
||||
Comments consisting of a very long sequence of non-foldable
|
||||
characters could trigger a forced line wrap that omitted
|
||||
the required leading space on the continuation line,
|
||||
causing the remainder of the comment to be interpreted as
|
||||
a new header field. This enabled header injection with
|
||||
carefully crafted inputs (bsc#1257029 CVE-2025-11468).
|
||||
- gh-143925: Reject control characters in data: URL media
|
||||
types (bsc#1257046, CVE-2025-15282).
|
||||
- gh-143919: Reject control characters in http.cookies.Morsel
|
||||
fields and values (bsc#1257031, CVE-2026-0672).
|
||||
- gh-143916: Reject C0 control characters within
|
||||
wsgiref.headers.Headers fields, values, and parameters
|
||||
(bsc#1257042, CVE-2026-0865).
|
||||
- gh-142145: Remove quadratic behavior in xml.minidom node ID
|
||||
cache clearing. In order to do this without breaking
|
||||
existing users, we also add the ownerDocument attribute to
|
||||
xml.dom.minidom elements and attributes created by directly
|
||||
instantiating the Element or Attr class. Note that this way
|
||||
of creating nodes is not supported; creator functions like
|
||||
xml.dom.Document.documentElement() should be used instead
|
||||
(bsc#1254997, CVE-2025-12084).
|
||||
- gh-137836: Add support of the “plaintext” element, RAWTEXT
|
||||
elements “xmp”, “iframe”, “noembed” and “noframes”, and
|
||||
optionally RAWTEXT element “noscript” in
|
||||
html.parser.HTMLParser.
|
||||
- gh-136063: email.message: ensure linear complexity for
|
||||
legacy HTTP parameters parsing. Patch by Bénédikt Tran.
|
||||
- gh-136065: Fix quadratic complexity in
|
||||
os.path.expandvars() (bsc#1252974, CVE-2025-6075).
|
||||
- gh-119451: Fix a potential memory denial of service in the
|
||||
http.client module. When connecting to a malicious server,
|
||||
it could cause an arbitrary amount of memory to be
|
||||
allocated. This could have led to symptoms including
|
||||
a MemoryError, swapping, out of memory (OOM) killed
|
||||
processes or containers, or even system crashes
|
||||
(CVE-2025-13836, bsc#1254400).
|
||||
- gh-119452: Fix a potential memory denial of service in the
|
||||
http.server module. When a malicious user is connected to
|
||||
the CGI server on Windows, it could cause an arbitrary
|
||||
amount of memory to be allocated. This could have led to
|
||||
symptoms including a MemoryError, swapping, out of memory
|
||||
(OOM) killed processes or containers, or even system
|
||||
crashes.
|
||||
- gh-119342: Fix a potential memory denial of service in the
|
||||
plistlib module. When reading a Plist file received from
|
||||
untrusted source, it could cause an arbitrary amount of
|
||||
memory to be allocated. This could have led to symptoms
|
||||
including a MemoryError, swapping, out of memory (OOM)
|
||||
killed processes or containers, or even system crashes
|
||||
(bsc#1254401, CVE-2025-13837).
|
||||
- Library
|
||||
- gh-144833: Fixed a use-after-free in ssl when SSL_new()
|
||||
returns NULL in newPySSLSocket(). The error was reported
|
||||
via a dangling pointer after the object had already been
|
||||
freed.
|
||||
- gh-144363: Update bundled libexpat to 2.7.4
|
||||
- gh-90949: Add SetAllocTrackerActivationThreshold() and
|
||||
SetAllocTrackerMaximumAmplification() to xmlparser objects
|
||||
to prevent use of disproportional amounts of dynamic memory
|
||||
from within an Expat parser. Patch by Bénédikt Tran.
|
||||
- Core and Builtins
|
||||
- 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.
|
||||
- gh-120298: Fix use-after free in list_richcompare_impl
|
||||
which can be invoked via some specificly tailored evil
|
||||
input.
|
||||
Remove upstreamed patches:
|
||||
- CVE-2025-11468-email-hdr-fold-comment.patch
|
||||
- CVE-2025-12084-minidom-quad-search.patch
|
||||
- CVE-2025-13836-http-resp-cont-len.patch
|
||||
- CVE-2025-13837-plistlib-mailicious-length.patch
|
||||
- CVE-2025-6075-expandvars-perf-degrad.patch
|
||||
- CVE-2026-0672-http-hdr-inject-cookie-Morsel.patch
|
||||
- CVE-2026-0865-wsgiref-ctrl-chars.patch
|
||||
- CVE-2025-15282-urllib-ctrl-chars.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Feb 11 19:09:06 CET 2026 - Matej Cepl <mcepl@suse.com>
|
||||
|
||||
- CVE-2025-11468: preserving parens when folding comments in
|
||||
email headers (bsc#1257029, gh#python/cpython#143935).
|
||||
CVE-2025-11468-email-hdr-fold-comment.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-12781: fix decoding with non-standard Base64 alphabet
|
||||
(bsc#1257108, gh#python/cpython#125346)
|
||||
CVE-2025-12781-b64decode-alt-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
|
||||
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).
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Nov 13 17:13:03 UTC 2025 - Matej Cepl <mcepl@cepl.eu>
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
# _md5.cpython-38m-x86_64-linux-gnu.so
|
||||
%define dynlib() %{sitedir}/lib-dynload/%{1}.cpython-%{abi_tag}-%{archname}-%{_os}%{?_gnu}%{?armsuffix}.so
|
||||
Name: %{python_pkg_name}%{psuffix}
|
||||
Version: 3.11.15
|
||||
Version: 3.11.14
|
||||
Release: 0
|
||||
Summary: Python 3 Interpreter
|
||||
License: Python-2.0
|
||||
@@ -188,16 +188,9 @@ Patch22: gh120226-fix-sendfile-test-kernel-610.patch
|
||||
Patch24: add-loongarch64-support.patch
|
||||
# PATCH-FIX-OPENSUSE gh139257-Support-docutils-0.22.patch gh#python/cpython#139257 daniel.garcia@suse.com
|
||||
Patch25: gh139257-Support-docutils-0.22.patch
|
||||
# PATCH-FIX-UPSTREAM CVE-2025-15366-imap-ctrl-chars.patch bsc#1257044 mcepl@suse.com
|
||||
# Reject control characters in wsgiref.headers.Headers
|
||||
Patch33: CVE-2025-15366-imap-ctrl-chars.patch
|
||||
# PATCH-FIX-UPSTREAM CVE-2025-15367-poplib-ctrl-chars.patch bsc#1257041 mcepl@suse.com
|
||||
# Reject control characters in poplib
|
||||
Patch35: CVE-2025-15367-poplib-ctrl-chars.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
|
||||
Patch36: CVE-2025-12781-b64decode-alt-chars.patch
|
||||
### END OF PATCHES
|
||||
# PATCH-FIX-UPSTREAM CVE-2025-6075-expandvars-perf-degrad.patch bsc#1252974 mcepl@suse.com
|
||||
# Avoid potential quadratic complexity vulnerabilities in path modules
|
||||
Patch26: CVE-2025-6075-expandvars-perf-degrad.patch
|
||||
BuildRequires: autoconf-archive
|
||||
BuildRequires: automake
|
||||
BuildRequires: crypto-policies-scripts
|
||||
@@ -553,9 +546,6 @@ LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH \
|
||||
%check
|
||||
export SUSE_VERSION="0%{?suse_version}"
|
||||
export SLE_VERSION="0%{?sle_version}"
|
||||
echo "Show the openssl version"
|
||||
openssl version -a
|
||||
echo ""
|
||||
%if %{with general}
|
||||
# exclude test_gdb -- it doesn't run in buildservice anyway, and fails on missing debuginfos
|
||||
# when you install gdb into your test env
|
||||
|
||||
Reference in New Issue
Block a user