diff --git a/CVE-2025-11468-email-hdr-fold-comment.patch b/CVE-2025-11468-email-hdr-fold-comment.patch deleted file mode 100644 index 5dbcb4f..0000000 --- a/CVE-2025-11468-email-hdr-fold-comment.patch +++ /dev/null @@ -1,108 +0,0 @@ -From 3900a2cb7d8321629717b8483179263a968bf552 Mon Sep 17 00:00:00 2001 -From: Seth Michael Larson -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 -Co-authored-by: Denis Ledoux ---- - 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)', -+ '(loremipsumdolorsitametconsecteturadipi)\n'), -+ ('(loremipsumdolorsitametconsecteturadipi)', -+ '(loremipsumdolorsitametconsecteturadipi)\n'), -+ ('(loremipsum dolorsitametconsecteturadipi)', -+ '(loremipsum dolorsitametconsecteturadipi)\n'), -+ ('(loremipsum dolorsitametconsecteturadipi)', -+ '(loremipsum\n dolorsitametconsecteturadipi)\n'), -+ ('(Escaped \\( \\) chars \\\\ in comments stay escaped)', -+ '(Escaped \\( \\) chars \\\\ in comments stay\n escaped)\n'), -+ ('((loremipsum)(loremipsum)(loremipsum)(loremipsum))', -+ '((loremipsum)(loremipsum)(loremipsum)(loremipsum))\n'), -+ ('((loremipsum)(loremipsum)(loremipsum) (loremipsum))', -+ '((loremipsum)(loremipsum)(loremipsum)\n (loremipsum))\n'), -+ ] -+ for (to, folded) in cases: -+ with self.subTest(to=to): -+ self._test(parser.get_address_list(to)[0], folded, policy=policy) -+ - # XXX Need tests with comments on various sides of a unicode token, - # and with unicode tokens in the comments. Spaces inside the quotes - # currently don't do the right thing. -Index: Python-3.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. diff --git a/CVE-2025-12084-minidom-quad-search.patch b/CVE-2025-12084-minidom-quad-search.patch deleted file mode 100644 index b4c8dd7..0000000 --- a/CVE-2025-12084-minidom-quad-search.patch +++ /dev/null @@ -1,94 +0,0 @@ -From df996ce4b9860f8d0c391d876ffe6d0143132a81 Mon Sep 17 00:00:00 2001 -From: Seth Michael Larson -Date: Wed, 3 Dec 2025 01:16:37 -0600 -Subject: [PATCH] gh-142145: Remove quadratic behavior in node ID cache - clearing (GH-142146) - -* Remove quadratic behavior in node ID cache clearing - -Co-authored-by: Jacob Walls <38668450+jacobtylerwalls@users.noreply.github.com> - -* Add news fragment - ---------- -(cherry picked from commit 08d8e18ad81cd45bc4a27d6da478b51ea49486e4) - -Co-authored-by: Seth Michael Larson -Co-authored-by: Jacob Walls <38668450+jacobtylerwalls@users.noreply.github.com> ---- - Lib/test/test_minidom.py | 18 ++++++++++++++++++ - Lib/xml/dom/minidom.py | 9 +-------- - ...5-12-01-09-36-45.gh-issue-142145.tcAUhg.rst | 1 + - 3 files changed, 20 insertions(+), 8 deletions(-) - create mode 100644 Misc/NEWS.d/next/Security/2025-12-01-09-36-45.gh-issue-142145.tcAUhg.rst - -diff --git a/Lib/test/test_minidom.py b/Lib/test/test_minidom.py -index 699265ccadc7f9..a83cb88ef9be79 100644 ---- a/Lib/test/test_minidom.py -+++ b/Lib/test/test_minidom.py -@@ -2,6 +2,7 @@ - - import copy - import pickle -+import time - import io - from test import support - import unittest -@@ -176,6 +177,23 @@ def testAppendChild(self): - self.confirm(dom.documentElement.childNodes[-1].data == "Hello") - dom.unlink() - -+ def testAppendChildNoQuadraticComplexity(self): -+ impl = getDOMImplementation() -+ -+ newdoc = impl.createDocument(None, "some_tag", None) -+ top_element = newdoc.documentElement -+ children = [newdoc.createElement(f"child-{i}") for i in range(1, 2 ** 15 + 1)] -+ element = top_element -+ -+ start = time.time() -+ for child in children: -+ element.appendChild(child) -+ element = child -+ end = time.time() -+ -+ # This example used to take at least 30 seconds. -+ self.assertLess(end - start, 1) -+ - def testAppendChildFragment(self): - dom, orig, c1, c2, c3, frag = self._create_fragment_test_nodes() - dom.documentElement.appendChild(frag) -diff --git a/Lib/xml/dom/minidom.py b/Lib/xml/dom/minidom.py -index ef8a159833bbc0..83f717eeb5d043 100644 ---- a/Lib/xml/dom/minidom.py -+++ b/Lib/xml/dom/minidom.py -@@ -292,13 +292,6 @@ def _append_child(self, node): - childNodes.append(node) - node.parentNode = self - --def _in_document(node): -- # return True iff node is part of a document tree -- while node is not None: -- if node.nodeType == Node.DOCUMENT_NODE: -- return True -- node = node.parentNode -- return False - - def _write_data(writer, data): - "Writes datachars to writer." -@@ -1539,7 +1532,7 @@ def _clear_id_cache(node): - if node.nodeType == Node.DOCUMENT_NODE: - node._id_cache.clear() - node._id_search_stack = None -- elif _in_document(node): -+ elif node.ownerDocument: - node.ownerDocument._id_cache.clear() - node.ownerDocument._id_search_stack= None - -diff --git a/Misc/NEWS.d/next/Security/2025-12-01-09-36-45.gh-issue-142145.tcAUhg.rst b/Misc/NEWS.d/next/Security/2025-12-01-09-36-45.gh-issue-142145.tcAUhg.rst -new file mode 100644 -index 00000000000000..440bc7794c69ef ---- /dev/null -+++ b/Misc/NEWS.d/next/Security/2025-12-01-09-36-45.gh-issue-142145.tcAUhg.rst -@@ -0,0 +1 @@ -+Remove quadratic behavior in ``xml.minidom`` node ID cache clearing. diff --git a/CVE-2025-12781-b64decode-alt-chars.patch b/CVE-2025-12781-b64decode-alt-chars.patch index bbe241f..fde573f 100644 --- a/CVE-2025-12781-b64decode-alt-chars.patch +++ b/CVE-2025-12781-b64decode-alt-chars.patch @@ -12,10 +12,10 @@ argument of b32decode(). 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 +Index: Python-3.12.13/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 +--- Python-3.12.13.orig/Doc/library/base64.rst 2026-03-03 13:39:30.000000000 +0100 ++++ Python-3.12.13/Doc/library/base64.rst 2026-03-06 20:24:47.155493487 +0100 @@ -74,15 +74,20 @@ A :exc:`binascii.Error` exception is raised if *s* is incorrectly padded. @@ -52,10 +52,10 @@ Index: Python-3.12.12/Doc/library/base64.rst .. function:: b32encode(s) -Index: Python-3.12.12/Lib/base64.py +Index: Python-3.12.13/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 +--- Python-3.12.13.orig/Lib/base64.py 2026-03-06 20:21:12.189779055 +0100 ++++ Python-3.12.13/Lib/base64.py 2026-03-06 20:24:47.156270051 +0100 @@ -71,20 +71,39 @@ The result is returned as a bytes object. A binascii.Error is raised if s is incorrectly padded. @@ -121,10 +121,10 @@ Index: Python-3.12.12/Lib/base64.py -Index: Python-3.12.12/Lib/test/test_base64.py +Index: Python-3.12.13/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 +--- Python-3.12.13.orig/Lib/test/test_base64.py 2026-03-06 20:21:14.072714339 +0100 ++++ Python-3.12.13/Lib/test/test_base64.py 2026-03-06 20:24:47.156769814 +0100 @@ -232,6 +232,25 @@ b'\xd3V\xbeo\xf7\x1d') self.check_decode_type_errors(base64.urlsafe_b64decode) @@ -181,10 +181,10 @@ Index: Python-3.12.12/Lib/test/test_base64.py 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 +Index: Python-3.12.13/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 ++++ Python-3.12.13/Misc/NEWS.d/next/Library/2025-11-06-12-03-29.gh-issue-125346.7Gfpgw.rst 2026-03-06 20:24:47.157181851 +0100 @@ -0,0 +1,5 @@ +Accepting ``+`` and ``/`` characters with an alternative alphabet in +:func:`base64.b64decode` and :func:`base64.urlsafe_b64decode` is now diff --git a/CVE-2025-13836-http-resp-cont-len.patch b/CVE-2025-13836-http-resp-cont-len.patch deleted file mode 100644 index d0f96ac..0000000 --- a/CVE-2025-13836-http-resp-cont-len.patch +++ /dev/null @@ -1,154 +0,0 @@ -From b3a7998115e195c40e00cfa662bcaa899d937c05 Mon Sep 17 00:00:00 2001 -From: Serhiy Storchaka -Date: Mon, 1 Dec 2025 17:26:07 +0200 -Subject: [PATCH] gh-119451: Fix a potential denial of service in http.client - (GH-119454) - -Reading the whole body of the HTTP response could cause OOM if -the Content-Length value is too large even if the server does not send -a large amount of data. Now the HTTP client reads large data by chunks, -therefore the amount of consumed memory is proportional to the amount -of sent data. -(cherry picked from commit 5a4c4a033a4a54481be6870aa1896fad732555b5) - -Co-authored-by: Serhiy Storchaka ---- - Lib/http/client.py | 28 +++- - Lib/test/test_httplib.py | 66 ++++++++++ - Misc/NEWS.d/next/Security/2024-05-23-11-47-48.gh-issue-119451.qkJe9-.rst | 5 - 3 files changed, 95 insertions(+), 4 deletions(-) - create mode 100644 Misc/NEWS.d/next/Security/2024-05-23-11-47-48.gh-issue-119451.qkJe9-.rst - -Index: Python-3.12.12/Lib/http/client.py -=================================================================== ---- Python-3.12.12.orig/Lib/http/client.py 2025-12-18 19:10:59.442847463 +0100 -+++ Python-3.12.12/Lib/http/client.py 2025-12-18 19:11:10.279358227 +0100 -@@ -111,6 +111,11 @@ - _MAXLINE = 65536 - _MAXHEADERS = 100 - -+# Data larger than this will be read in chunks, to prevent extreme -+# overallocation. -+_MIN_READ_BUF_SIZE = 1 << 20 -+ -+ - # Header name/value ABNF (http://tools.ietf.org/html/rfc7230#section-3.2) - # - # VCHAR = %x21-7E -@@ -639,10 +644,25 @@ - reading. If the bytes are truly not available (due to EOF), then the - IncompleteRead exception can be used to detect the problem. - """ -- data = self.fp.read(amt) -- if len(data) < amt: -- raise IncompleteRead(data, amt-len(data)) -- return data -+ cursize = min(amt, _MIN_READ_BUF_SIZE) -+ data = self.fp.read(cursize) -+ if len(data) >= amt: -+ return data -+ if len(data) < cursize: -+ raise IncompleteRead(data, amt - len(data)) -+ -+ data = io.BytesIO(data) -+ data.seek(0, 2) -+ while True: -+ # This is a geometric increase in read size (never more than -+ # doubling out the current length of data per loop iteration). -+ delta = min(cursize, amt - cursize) -+ data.write(self.fp.read(delta)) -+ if data.tell() >= amt: -+ return data.getvalue() -+ cursize += delta -+ if data.tell() < cursize: -+ raise IncompleteRead(data.getvalue(), amt - data.tell()) - - def _safe_readinto(self, b): - """Same as _safe_read, but for reading into a buffer.""" -Index: Python-3.12.12/Lib/test/test_httplib.py -=================================================================== ---- Python-3.12.12.orig/Lib/test/test_httplib.py 2025-12-18 19:11:00.972941560 +0100 -+++ Python-3.12.12/Lib/test/test_httplib.py 2025-12-18 19:11:10.279958169 +0100 -@@ -1452,6 +1452,72 @@ - thread.join() - self.assertEqual(result, b"proxied data\n") - -+ def test_large_content_length(self): -+ serv = socket.create_server((HOST, 0)) -+ self.addCleanup(serv.close) -+ -+ def run_server(): -+ [conn, address] = serv.accept() -+ with conn: -+ while conn.recv(1024): -+ conn.sendall( -+ b"HTTP/1.1 200 Ok\r\n" -+ b"Content-Length: %d\r\n" -+ b"\r\n" % size) -+ conn.sendall(b'A' * (size//3)) -+ conn.sendall(b'B' * (size - size//3)) -+ -+ thread = threading.Thread(target=run_server) -+ thread.start() -+ self.addCleanup(thread.join, 1.0) -+ -+ conn = client.HTTPConnection(*serv.getsockname()) -+ try: -+ for w in range(15, 27): -+ size = 1 << w -+ conn.request("GET", "/") -+ with conn.getresponse() as response: -+ self.assertEqual(len(response.read()), size) -+ finally: -+ conn.close() -+ thread.join(1.0) -+ -+ def test_large_content_length_truncated(self): -+ serv = socket.create_server((HOST, 0)) -+ self.addCleanup(serv.close) -+ -+ def run_server(): -+ while True: -+ [conn, address] = serv.accept() -+ with conn: -+ conn.recv(1024) -+ if not size: -+ break -+ conn.sendall( -+ b"HTTP/1.1 200 Ok\r\n" -+ b"Content-Length: %d\r\n" -+ b"\r\n" -+ b"Text" % size) -+ -+ thread = threading.Thread(target=run_server) -+ thread.start() -+ self.addCleanup(thread.join, 1.0) -+ -+ conn = client.HTTPConnection(*serv.getsockname()) -+ try: -+ for w in range(18, 65): -+ size = 1 << w -+ conn.request("GET", "/") -+ with conn.getresponse() as response: -+ self.assertRaises(client.IncompleteRead, response.read) -+ conn.close() -+ finally: -+ conn.close() -+ size = 0 -+ conn.request("GET", "/") -+ conn.close() -+ thread.join(1.0) -+ - def test_putrequest_override_domain_validation(self): - """ - It should be possible to override the default validation -Index: Python-3.12.12/Misc/NEWS.d/next/Security/2024-05-23-11-47-48.gh-issue-119451.qkJe9-.rst -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ Python-3.12.12/Misc/NEWS.d/next/Security/2024-05-23-11-47-48.gh-issue-119451.qkJe9-.rst 2025-12-18 19:11:10.280437075 +0100 -@@ -0,0 +1,5 @@ -+Fix a potential memory denial of service in the :mod:`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 :exc:`MemoryError`, swapping, out -+of memory (OOM) killed processes or containers, or even system crashes. diff --git a/CVE-2025-13837-plistlib-mailicious-length.patch b/CVE-2025-13837-plistlib-mailicious-length.patch deleted file mode 100644 index 41b3ab2..0000000 --- a/CVE-2025-13837-plistlib-mailicious-length.patch +++ /dev/null @@ -1,159 +0,0 @@ -From fa6d8d0f5d00fd629c5df6aabadc82d5f2a76099 Mon Sep 17 00:00:00 2001 -From: Serhiy Storchaka -Date: Mon, 1 Dec 2025 17:28:15 +0200 -Subject: [PATCH] [3.12] gh-119342: Fix a potential denial of service in - plistlib (GH-119343) - -Reading a specially prepared small Plist file could cause OOM because file's -read(n) preallocates a bytes object for reading the specified amount of -data. Now plistlib reads large data by chunks, therefore the upper limit of -consumed memory is proportional to the size of the input file. -(cherry picked from commit 694922cf40aa3a28f898b5f5ee08b71b4922df70) - -Co-authored-by: Serhiy Storchaka ---- - Lib/plistlib.py | 31 +++++--- - Lib/test/test_plistlib.py | 37 +++++++++- - Misc/NEWS.d/next/Security/2024-05-21-22-11-31.gh-issue-119342.BTFj4Z.rst | 5 + - 3 files changed, 59 insertions(+), 14 deletions(-) - create mode 100644 Misc/NEWS.d/next/Security/2024-05-21-22-11-31.gh-issue-119342.BTFj4Z.rst - -Index: Python-3.12.12/Lib/plistlib.py -=================================================================== ---- Python-3.12.12.orig/Lib/plistlib.py 2025-10-09 13:07:00.000000000 +0200 -+++ Python-3.12.12/Lib/plistlib.py 2025-12-19 20:12:03.018693606 +0100 -@@ -73,6 +73,9 @@ - PlistFormat = enum.Enum('PlistFormat', 'FMT_XML FMT_BINARY', module=__name__) - globals().update(PlistFormat.__members__) - -+# Data larger than this will be read in chunks, to prevent extreme -+# overallocation. -+_MIN_READ_BUF_SIZE = 1 << 20 - - class UID: - def __init__(self, data): -@@ -499,12 +502,24 @@ - - return tokenL - -+ def _read(self, size): -+ cursize = min(size, _MIN_READ_BUF_SIZE) -+ data = self._fp.read(cursize) -+ while True: -+ if len(data) != cursize: -+ raise InvalidFileException -+ if cursize == size: -+ return data -+ delta = min(cursize, size - cursize) -+ data += self._fp.read(delta) -+ cursize += delta -+ - def _read_ints(self, n, size): -- data = self._fp.read(size * n) -+ data = self._read(size * n) - if size in _BINARY_FORMAT: - return struct.unpack(f'>{n}{_BINARY_FORMAT[size]}', data) - else: -- if not size or len(data) != size * n: -+ if not size: - raise InvalidFileException() - return tuple(int.from_bytes(data[i: i + size], 'big') - for i in range(0, size * n, size)) -@@ -561,22 +576,16 @@ - - elif tokenH == 0x40: # data - s = self._get_size(tokenL) -- result = self._fp.read(s) -- if len(result) != s: -- raise InvalidFileException() -+ result = self._read(s) - - elif tokenH == 0x50: # ascii string - s = self._get_size(tokenL) -- data = self._fp.read(s) -- if len(data) != s: -- raise InvalidFileException() -+ data = self._read(s) - result = data.decode('ascii') - - elif tokenH == 0x60: # unicode string - s = self._get_size(tokenL) * 2 -- data = self._fp.read(s) -- if len(data) != s: -- raise InvalidFileException() -+ data = self._read(s) - result = data.decode('utf-16be') - - elif tokenH == 0x80: # UID -Index: Python-3.12.12/Lib/test/test_plistlib.py -=================================================================== ---- Python-3.12.12.orig/Lib/test/test_plistlib.py 2025-10-09 13:07:00.000000000 +0200 -+++ Python-3.12.12/Lib/test/test_plistlib.py 2025-12-19 20:12:03.018920871 +0100 -@@ -841,8 +841,7 @@ - - class TestBinaryPlistlib(unittest.TestCase): - -- @staticmethod -- def decode(*objects, offset_size=1, ref_size=1): -+ def build(self, *objects, offset_size=1, ref_size=1): - data = [b'bplist00'] - offset = 8 - offsets = [] -@@ -854,7 +853,11 @@ - len(objects), 0, offset) - data.extend(offsets) - data.append(tail) -- return plistlib.loads(b''.join(data), fmt=plistlib.FMT_BINARY) -+ return b''.join(data) -+ -+ def decode(self, *objects, offset_size=1, ref_size=1): -+ data = self.build(*objects, offset_size=offset_size, ref_size=ref_size) -+ return plistlib.loads(data, fmt=plistlib.FMT_BINARY) - - def test_nonstandard_refs_size(self): - # Issue #21538: Refs and offsets are 24-bit integers -@@ -963,6 +966,34 @@ - with self.assertRaises(plistlib.InvalidFileException): - plistlib.loads(b'bplist00' + data, fmt=plistlib.FMT_BINARY) - -+ def test_truncated_large_data(self): -+ self.addCleanup(os_helper.unlink, os_helper.TESTFN) -+ def check(data): -+ with open(os_helper.TESTFN, 'wb') as f: -+ f.write(data) -+ # buffered file -+ with open(os_helper.TESTFN, 'rb') as f: -+ with self.assertRaises(plistlib.InvalidFileException): -+ plistlib.load(f, fmt=plistlib.FMT_BINARY) -+ # unbuffered file -+ with open(os_helper.TESTFN, 'rb', buffering=0) as f: -+ with self.assertRaises(plistlib.InvalidFileException): -+ plistlib.load(f, fmt=plistlib.FMT_BINARY) -+ for w in range(20, 64): -+ s = 1 << w -+ # data -+ check(self.build(b'\x4f\x13' + s.to_bytes(8, 'big'))) -+ # ascii string -+ check(self.build(b'\x5f\x13' + s.to_bytes(8, 'big'))) -+ # unicode string -+ check(self.build(b'\x6f\x13' + s.to_bytes(8, 'big'))) -+ # array -+ check(self.build(b'\xaf\x13' + s.to_bytes(8, 'big'))) -+ # dict -+ check(self.build(b'\xdf\x13' + s.to_bytes(8, 'big'))) -+ # number of objects -+ check(b'bplist00' + struct.pack('>6xBBQQQ', 1, 1, s, 0, 8)) -+ - - class TestKeyedArchive(unittest.TestCase): - def test_keyed_archive_data(self): -Index: Python-3.12.12/Misc/NEWS.d/next/Security/2024-05-21-22-11-31.gh-issue-119342.BTFj4Z.rst -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ Python-3.12.12/Misc/NEWS.d/next/Security/2024-05-21-22-11-31.gh-issue-119342.BTFj4Z.rst 2025-12-19 20:12:03.019148207 +0100 -@@ -0,0 +1,5 @@ -+Fix a potential memory denial of service in the :mod:`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 :exc:`MemoryError`, swapping, out -+of memory (OOM) killed processes or containers, or even system crashes. diff --git a/CVE-2025-15282-urllib-ctrl-chars.patch b/CVE-2025-15282-urllib-ctrl-chars.patch deleted file mode 100644 index 3e78e8f..0000000 --- a/CVE-2025-15282-urllib-ctrl-chars.patch +++ /dev/null @@ -1,64 +0,0 @@ -From f336af1c4b103297de1322bbe00f920f3e58b899 Mon Sep 17 00:00:00 2001 -From: Seth Michael Larson -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 ---- - 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. diff --git a/CVE-2025-15366-imap-ctrl-chars.patch b/CVE-2025-15366-imap-ctrl-chars.patch index e42abab..6f091da 100644 --- a/CVE-2025-15366-imap-ctrl-chars.patch +++ b/CVE-2025-15366-imap-ctrl-chars.patch @@ -8,10 +8,10 @@ Subject: [PATCH 1/2] Add 'test.support' fixture for C0 control characters 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 +Index: Python-3.12.13/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 +--- Python-3.12.13.orig/Lib/imaplib.py 2026-03-06 20:21:13.076797807 +0100 ++++ Python-3.12.13/Lib/imaplib.py 2026-03-06 20:25:14.549622415 +0100 @@ -132,7 +132,7 @@ # We compile these in _mode_xxx. _Literal = br'.*{(?P\d+)}$' @@ -30,9 +30,9 @@ Index: Python-3.12.12/Lib/imaplib.py 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 +Index: Python-3.12.13/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 ++++ Python-3.12.13/Misc/NEWS.d/next/Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst 2026-03-06 20:25:14.550097371 +0100 @@ -0,0 +1 @@ +Reject control characters in IMAP commands. diff --git a/CVE-2025-15367-poplib-ctrl-chars.patch b/CVE-2025-15367-poplib-ctrl-chars.patch index 4366206..dd77b13 100644 --- a/CVE-2025-15367-poplib-ctrl-chars.patch +++ b/CVE-2025-15367-poplib-ctrl-chars.patch @@ -9,10 +9,10 @@ Subject: [PATCH 1/2] Add 'test.support' fixture for C0 control characters Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst | 1 + 3 files changed, 11 insertions(+) -Index: Python-3.12.12/Lib/poplib.py +Index: Python-3.12.13/Lib/poplib.py =================================================================== ---- Python-3.12.12.orig/Lib/poplib.py 2026-02-11 23:46:29.442215955 +0100 -+++ Python-3.12.12/Lib/poplib.py 2026-02-11 23:46:46.713251058 +0100 +--- Python-3.12.13.orig/Lib/poplib.py 2026-03-06 20:21:13.491889752 +0100 ++++ Python-3.12.13/Lib/poplib.py 2026-03-06 20:25:33.388287765 +0100 @@ -122,6 +122,8 @@ def _putcmd(self, line): if self._debugging: print('*cmd*', repr(line)) @@ -22,10 +22,10 @@ Index: Python-3.12.12/Lib/poplib.py self._putline(line) -Index: Python-3.12.12/Lib/test/test_poplib.py +Index: Python-3.12.13/Lib/test/test_poplib.py =================================================================== ---- Python-3.12.12.orig/Lib/test/test_poplib.py 2026-02-11 23:46:31.636412813 +0100 -+++ Python-3.12.12/Lib/test/test_poplib.py 2026-02-11 23:46:46.713442229 +0100 +--- Python-3.12.13.orig/Lib/test/test_poplib.py 2026-03-06 20:21:15.497803691 +0100 ++++ Python-3.12.13/Lib/test/test_poplib.py 2026-03-06 20:25:33.389775036 +0100 @@ -17,6 +17,7 @@ from test.support import threading_helper from test.support import asynchat @@ -48,9 +48,9 @@ Index: Python-3.12.12/Lib/test/test_poplib.py @requires_ssl def test_stls_capa(self): capa = self.client.capa() -Index: Python-3.12.12/Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst +Index: Python-3.12.13/Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ Python-3.12.12/Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst 2026-02-11 23:46:46.713620996 +0100 ++++ Python-3.12.13/Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst 2026-03-06 20:25:33.390103395 +0100 @@ -0,0 +1 @@ +Reject control characters in POP3 commands. diff --git a/CVE-2025-6075-expandvars-perf-degrad.patch b/CVE-2025-6075-expandvars-perf-degrad.patch deleted file mode 100644 index f867760..0000000 --- a/CVE-2025-6075-expandvars-perf-degrad.patch +++ /dev/null @@ -1,382 +0,0 @@ -From 122a417f8000eb904a3cac9aacf4de8d288d7148 Mon Sep 17 00:00:00 2001 -From: Serhiy Storchaka -Date: Fri, 31 Oct 2025 15:49:51 +0200 -Subject: [PATCH 1/2] [3.12] 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 -Co-authored-by: Łukasz Langa ---- - Lib/ntpath.py | 126 ++++++------------ - Lib/posixpath.py | 43 +++--- - Lib/test/test_genericpath.py | 14 ++ - Lib/test/test_ntpath.py | 22 ++- - ...-05-30-22-33-27.gh-issue-136065.bu337o.rst | 1 + - 5 files changed, 93 insertions(+), 113 deletions(-) - create mode 100644 Misc/NEWS.d/next/Security/2025-05-30-22-33-27.gh-issue-136065.bu337o.rst - -diff --git a/Lib/ntpath.py b/Lib/ntpath.py -index 1bef630bd9c0ff..393d358b0afb8c 100644 ---- a/Lib/ntpath.py -+++ b/Lib/ntpath.py -@@ -409,17 +409,23 @@ def expanduser(path): - # 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'}' -@@ -428,94 +434,44 @@ def expandvars(path): - 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. -diff --git a/Lib/posixpath.py b/Lib/posixpath.py -index 90a6f545f90529..6306f14f53491b 100644 ---- a/Lib/posixpath.py -+++ b/Lib/posixpath.py -@@ -314,42 +314,41 @@ def expanduser(path): - # 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: -@@ -357,13 +356,11 @@ def expandvars(path): - 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. -diff --git a/Lib/test/test_genericpath.py b/Lib/test/test_genericpath.py -index 3eefb722b81e55..1cec587e875888 100644 ---- a/Lib/test/test_genericpath.py -+++ b/Lib/test/test_genericpath.py -@@ -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 -@@ -443,6 +444,19 @@ def check(value, expected): - 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(): -diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py -index ced9dc4fffb41e..72f89ebb21c478 100644 ---- a/Lib/test/test_ntpath.py -+++ b/Lib/test/test_ntpath.py -@@ -7,8 +7,7 @@ - import unittest - import warnings - from ntpath import ALLOW_MISSING --from test.support import cpython_only, os_helper --from test.support import TestFailed, is_emscripten -+from test.support import os_helper, is_emscripten - from test.support.os_helper import FakePath - from test import test_genericpath - from tempfile import TemporaryFile -@@ -58,7 +57,7 @@ def tester(fn, wantResult): - 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 -@@ -74,7 +73,7 @@ def tester(fn, wantResult): - 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))) - - -@@ -882,6 +881,19 @@ def check(value, expected): - 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') - -@@ -1207,7 +1219,7 @@ def test_con_device(self): - self.assertTrue(os.path.exists(r"\\.\CON")) - - @unittest.skipIf(sys.platform != 'win32', "Fast paths are only for win32") -- @cpython_only -+ @support.cpython_only - def test_fast_paths_in_use(self): - # There are fast paths of these functions implemented in posixmodule.c. - # Confirm that they are being used, and not the Python fallbacks in -diff --git a/Misc/NEWS.d/next/Security/2025-05-30-22-33-27.gh-issue-136065.bu337o.rst b/Misc/NEWS.d/next/Security/2025-05-30-22-33-27.gh-issue-136065.bu337o.rst -new file mode 100644 -index 00000000000000..1d152bb5318380 ---- /dev/null -+++ b/Misc/NEWS.d/next/Security/2025-05-30-22-33-27.gh-issue-136065.bu337o.rst -@@ -0,0 +1 @@ -+Fix quadratic complexity in :func:`os.path.expandvars`. - -From 27eb90f676ced2a2a6f2a3ea9d0555d045a0d976 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?=C5=81ukasz=20Langa?= -Date: Fri, 31 Oct 2025 17:32:52 +0100 -Subject: [PATCH 2/2] Oops - ---- - Lib/test/test_ntpath.py | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py -index 72f89ebb21c478..7c42d4f5894788 100644 ---- a/Lib/test/test_ntpath.py -+++ b/Lib/test/test_ntpath.py -@@ -7,6 +7,7 @@ - import unittest - import warnings - from ntpath import ALLOW_MISSING -+from test import support - from test.support import os_helper, is_emscripten - from test.support.os_helper import FakePath - from test import test_genericpath diff --git a/CVE-2026-0672-http-hdr-inject-cookie-Morsel.patch b/CVE-2026-0672-http-hdr-inject-cookie-Morsel.patch deleted file mode 100644 index 1ce4e2f..0000000 --- a/CVE-2026-0672-http-hdr-inject-cookie-Morsel.patch +++ /dev/null @@ -1,183 +0,0 @@ -From 9729bdf210967c806f3364c76663fc2ade58e389 Mon Sep 17 00:00:00 2001 -From: Seth Michael Larson -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 -Co-authored-by: Bartosz Sławecki -Co-authored-by: sobolevn ---- - 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': "", - 'output': 'Set-Cookie: chips=ahoy\nSet-Cookie: vienna=finger'}, - -- {'data': 'keebler="E=mc2; L=\\"Loves\\"; fudge=\\012;"', -- 'dict': {'keebler' : 'E=mc2; L="Loves"; fudge=\012;'}, -- 'repr': '''''', -- 'output': 'Set-Cookie: keebler="E=mc2; L=\\"Loves\\"; fudge=\\012;"'}, -+ {'data': 'keebler="E=mc2; L=\\"Loves\\"; fudge=;"', -+ 'dict': {'keebler' : 'E=mc2; L="Loves"; fudge=;'}, -+ 'repr': '''''', -+ 'output': 'Set-Cookie: keebler="E=mc2; L=\\"Loves\\"; fudge=;"'}, - - # Check illegal cookies that have an '=' char in an unquoted value - {'data': 'keebler=E=mc2', -@@ -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. diff --git a/CVE-2026-0865-wsgiref-ctrl-chars.patch b/CVE-2026-0865-wsgiref-ctrl-chars.patch deleted file mode 100644 index d189998..0000000 --- a/CVE-2026-0865-wsgiref-ctrl-chars.patch +++ /dev/null @@ -1,96 +0,0 @@ -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 ---- - 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. diff --git a/Python-3.12.12.tar.xz b/Python-3.12.12.tar.xz deleted file mode 100644 index a5676e8..0000000 --- a/Python-3.12.12.tar.xz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fb85a13414b028c49ba18bbd523c2d055a30b56b18b92ce454ea2c51edc656c4 -size 20798712 diff --git a/Python-3.12.12.tar.xz.asc b/Python-3.12.12.tar.xz.asc deleted file mode 100644 index 9e6c514..0000000 --- a/Python-3.12.12.tar.xz.asc +++ /dev/null @@ -1,18 +0,0 @@ ------BEGIN PGP SIGNATURE----- - -iQKTBAABCgB9FiEEcWlgX2LHUTVtBUomqCHmgOX6YwUFAmjnnr1fFIAAAAAALgAo -aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldDcx -Njk2MDVGNjJDNzUxMzU2RDA1NEEyNkE4MjFFNjgwRTVGQTYzMDUACgkQqCHmgOX6 -YwXF3Q//VrreGa+P8lvp9UMjoj/YquKPwLqjzzAWf5vzHipkebdiESsB1HfGu04k -Jw+ctTnXHf/12u0W7ijv+56JtcJFqEzh8yGokWqOzc99rpCeCY9qtuwaVYtZrTNx -wepRaDAHdhP4Z2kLPDiE6pCXu2NIR5wHqHjQ8JGmprhASc07uxEhNN/gucVR2Sbr -cCfC9rHfHkdhoPpZRRbcraAaxPGL3VyBXf7HuYbHhf4GuF9EVDlFg5I0BzHCKJDd -ebPXYHvsoDgrMMqPXiX/YkGNByf3Ze6KZTNSGICy8SDzIzZgpmtOe5rzvlOXJBZZ -SVfX8SqP4Ufml+MfJrGEx30S9reYYvnyTSmttpbDznonROKPEZOuDt08+CG3yR+T -o5RdIneWmGXRf1mBrFKH9Br5tfOd+YeldfxdoQgla2fFHFVRnab1lsZFOC/HZ5z2 -Q3rPfVMDYKO8yoIKqv0BUzlkn9wYphCWoPHq0Y+SGjcP+Zh5qRTMqZYIaGekhWmx -86egHHVqedMI0Q9hvgIEirupVJ1q34FZn2+3sEka9hdOie9aNHXWTmgWCGDm46qj -qC9tT/jkMzWIY2Y4RdVDMdSCb7HkBEl1eAANq511gJ+eSWAXbP1sVrQoiAQY+EkC -Yu2ceZYsl9i6zm7i/QaU/mOGB7xMZhMQLZBnZTHSzAZo/pBN7y8= -=RuLK ------END PGP SIGNATURE----- diff --git a/Python-3.12.12.tar.xz.sigstore b/Python-3.12.12.tar.xz.sigstore deleted file mode 100644 index bcab32a..0000000 --- a/Python-3.12.12.tar.xz.sigstore +++ /dev/null @@ -1 +0,0 @@ -{"mediaType": "application/vnd.dev.sigstore.bundle.v0.3+json", "verificationMaterial": {"certificate": {"rawBytes": "MIICyjCCAlCgAwIBAgIUa7XmzWlmoxbdaf7Bd0cb7k2SJX0wCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjUxMDA5MTEzOTEwWhcNMjUxMDA5MTE0OTEwWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEnnBupfHW0kIyKIch4g4bg/VMzmQSN3W+fDXSBXPHKVV01duW4mnJBNAx8dOjaDQJbbGLCL3nHReR6AHY5EzzWKOCAW8wggFrMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUxS1GFV6/403CJB2LIriD0Yxys+kwHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0RAQH/BBUwE4ERdGhvbWFzQHB5dGhvbi5vcmcwKQYKKwYBBAGDvzABAQQbaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tMCsGCisGAQQBg78wAQgEHQwbaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tMIGKBgorBgEEAdZ5AgQCBHwEegB4AHYA3T0wasbHETJjGR4cmWc3AqJKXrjePK3/h4pygC8p7o4AAAGZyMSWqQAABAMARzBFAiEAgP3Zja0sZ42WlEujGWIbBp+3AemF4BPwFlVMLG/criwCIDSK9BOHosQgvpZnN+hpQrqZdHZ7j1QXaxWfcERObDGrMAoGCCqGSM49BAMDA2gAMGUCMC/Fx5Bbae7C7w5CjzPgAIRB8sAV5THF7EynHjFxBqjwYhiMblyn5lzwpTsSpcGyiQIxAMtPBAMZXbJeY8LL/rTmrqaS+gvUCFZe430pf/7njbi+vMTsnX6lbyDW6+MBPf2w0Q=="}, "tlogEntries": [{"logIndex": "597445409", "logId": {"keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="}, "kindVersion": {"kind": "hashedrekord", "version": "0.0.1"}, "integratedTime": "1760009951", "inclusionPromise": {"signedEntryTimestamp": "MEQCICmAn/SSLFYafnAtkPRYmvBAv34ZqQsxnCKxA6lvOwtIAiADgWJmj7xnSimwJjyYMND/62BSa6VAn+yiurqa+3sFbg=="}, "inclusionProof": {"logIndex": "475541147", "rootHash": "NtKq0OO26YDo37dp00CxEkih9ardFvhT06bm+f1SQDE=", "treeSize": "475541154", "hashes": ["NslcefFuKuND6JRNbUSPjLrHeL0W18bCD4VhxfCcQKk=", "A0S2uABqcbgE1HPfloLBAk0TlXFJVl7yLEBondSsQ0c=", "6sWxX6Qc03LZeNbyN5W9cj7IZtqLYjkxFKvRS3ynzso=", "sdBvJFo0UwZVcXbz5NwqW/k4wRKwjiBjYIlN9G6hzXc=", "HSc04gOheRI34V7k9W+RDSDZFEf2I9JjEEOdGOMAUCA=", "C0KrXbTnn0FjHCn6Pk8TOEPndNLUliSsS1kLpaoeFho=", "/lb6eJIa9/379KwZZThJl+TJzpB0p9sLsW59J4AkleA=", "60XcwfvS6KRVEutb85dCHmflKO/pCJu3wP/wi71Hjjw=", "T5+n1/blJViw8vobIXjJuar7GB5qkWPWxuPI4TLuIus=", "N/HdEEbPrOhis60vsOpblzzFJ5Gn0VF1X5o/a5zj5ho=", "5iV4XGoB9mnKM5YryHN+GB7tIaTkjbMhbGbF01zhzKU=", "qXhJobQjWl6SO/pue3trUW2uL4jXx24Ip7lpd4hc5bU=", "56ObhlROm9L8Q4JyN+mxEQ5pZD5QdobB1xZFIeL0lVg=", "EGaD/cNavzxGYLx1Gl0uNNWBZvyXlSHSdlIeH7m+63A=", "2Wv4GiithwNukRKV06clevnQQYCzXmSS/+/OJtXgsXQ=", "1mfy94KpcItqshH9+gwqV6jccupcaMpVsF28New8zDY=", "vS7O4ozHIQZJWBiov+mkpI27GE8zAmVCEkRcP3NDyNE="], "checkpoint": {"envelope": "rekor.sigstore.dev - 1193050959916656506\n475541154\nNtKq0OO26YDo37dp00CxEkih9ardFvhT06bm+f1SQDE=\n\n\u2014 rekor.sigstore.dev wNI9ajBFAiBAXkd6xMHjC/fa3mQGVYRGINSGMy5E39T2cwLfMJUCdAIhAJ8pLs5eiFWKL+RH/M/yyicyskpEIjumbkignFyjP+fn\n"}}, "canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiJmYjg1YTEzNDE0YjAyOGM0OWJhMThiYmQ1MjNjMmQwNTVhMzBiNTZiMThiOTJjZTQ1NGVhMmM1MWVkYzY1NmM0In19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FVUNJUUNzSysxcVRmNGZHd2I1eTBuaHpiQXdKa1hucGUydDYzZU96a3VrQ2Q5bFNRSWdDTzNRb3huTFc2b0FyMk0yMFMvL3k4aURVS0VHZTNwaXBMd0MvK3ptTG5BPSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVTjVha05EUVd4RFowRjNTVUpCWjBsVllUZFliWHBYYkcxdmVHSmtZV1kzUW1Rd1kySTNhekpUU2xnd2QwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcFZlRTFFUVRWTlZFVjZUMVJGZDFkb1kwNU5hbFY0VFVSQk5VMVVSVEJQVkVWM1YycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVZ1YmtKMWNHWklWekJyU1hsTFNXTm9OR2MwWW1jdlZrMTZiVkZUVGpOWEsyWkVXRk1LUWxoUVNFdFdWakF4WkhWWE5HMXVTa0pPUVhnNFpFOXFZVVJSU21KaVIweERURE51U0ZKbFVqWkJTRmsxUlhwNlYwdFBRMEZYT0hkblowWnlUVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXUkNaMDVXU0ZFMFJVWm5VVlY0VXpGSENrWldOaTgwTURORFNrSXlURWx5YVVRd1dYaDVjeXRyZDBoM1dVUldVakJxUWtKbmQwWnZRVlV6T1ZCd2VqRlphMFZhWWpWeFRtcHdTMFpYYVhocE5Ga0tXa1E0ZDBoM1dVUldVakJTUVZGSUwwSkNWWGRGTkVWU1pFZG9kbUpYUm5wUlNFSTFaRWRvZG1KcE5YWmpiV04zUzFGWlMwdDNXVUpDUVVkRWRucEJRZ3BCVVZGaVlVaFNNR05JVFRaTWVUbG9XVEpPZG1SWE5UQmplVFZ1WWpJNWJtSkhWWFZaTWpsMFRVTnpSME5wYzBkQlVWRkNaemM0ZDBGUlowVklVWGRpQ21GSVVqQmpTRTAyVEhrNWFGa3lUblprVnpVd1kzazFibUl5T1c1aVIxVjFXVEk1ZEUxSlIwdENaMjl5UW1kRlJVRmtXalZCWjFGRFFraDNSV1ZuUWpRS1FVaFpRVE5VTUhkaGMySklSVlJLYWtkU05HTnRWMk16UVhGS1MxaHlhbVZRU3pNdmFEUndlV2RET0hBM2J6UkJRVUZIV25sTlUxZHhVVUZCUWtGTlFRcFNla0pHUVdsRlFXZFFNMXBxWVRCeldqUXlWMnhGZFdwSFYwbGlRbkFyTTBGbGJVWTBRbEIzUm14V1RVeEhMMk55YVhkRFNVUlRTemxDVDBodmMxRm5Dblp3V201T0syaHdVWEp4V21SSVdqZHFNVkZZWVhoWFptTkZVazlpUkVkeVRVRnZSME5EY1VkVFRUUTVRa0ZOUkVFeVowRk5SMVZEVFVNdlJuZzFRbUlLWVdVM1F6ZDNOVU5xZWxCblFVbFNRamh6UVZZMVZFaEdOMFY1YmtocVJuaENjV3AzV1docFRXSnNlVzQxYkhwM2NGUnpVM0JqUjNscFVVbDRRVTEwVUFwQ1FVMWFXR0pLWlZrNFRFd3ZjbFJ0Y25GaFV5dG5kbFZEUmxwbE5ETXdjR1l2TjI1cVlta3JkazFVYzI1WU5teGllVVJYTml0TlFsQm1NbmN3VVQwOUNpMHRMUzB0UlU1RUlFTkZVbFJKUmtsRFFWUkZMUzB0TFMwSyJ9fX19"}], "timestampVerificationData": {}}, "messageSignature": {"messageDigest": {"algorithm": "SHA2_256", "digest": "+4WhNBSwKMSboYu9UjwtBVowtWsYuSzkVOosUe3GVsQ="}, "signature": "MEUCIQCsK+1qTf4fGwb5y0nhzbAwJkXnpe2t63eOzkukCd9lSQIgCO3QoxnLW6oAr2M20S//y8iDUKEGe3pipLwC/+zmLnA="}} diff --git a/Python-3.12.13.tar.xz b/Python-3.12.13.tar.xz new file mode 100644 index 0000000..e53cbfa --- /dev/null +++ b/Python-3.12.13.tar.xz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c08bc65a81971c1dd5783182826503369466c7e67374d1646519adf05207b684 +size 20801708 diff --git a/Python-3.12.13.tar.xz.asc b/Python-3.12.13.tar.xz.asc new file mode 100644 index 0000000..9888566 --- /dev/null +++ b/Python-3.12.13.tar.xz.asc @@ -0,0 +1,18 @@ +-----BEGIN PGP SIGNATURE----- + +iQKTBAABCgB9FiEEcWlgX2LHUTVtBUomqCHmgOX6YwUFAmmm3hlfFIAAAAAALgAo +aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldDcx +Njk2MDVGNjJDNzUxMzU2RDA1NEEyNkE4MjFFNjgwRTVGQTYzMDUACgkQqCHmgOX6 +YwW/NA/+MsD99kuy8nBgrK65H3nVj104QcYaau9qhQ62x5+d7P04sVs8bf0mo/AM +zec7eCTHnwoLVborEiqyd5NPRUFNJRfsIn0g4z0PIWRBaXsPztMT4suQdNw+VOTd +3+up8Um0cA2tnesiXZvT5mXY/2kjffcosP/D4OjdADEGYcUawgNeY4LQi9sTOzs6 +ubI+mrtSqlAzgKM5NeVj2LdXPeLhpFz4TPk5GTlp0N9p5I1/7ZjK6eLw9p1gPZNN +xzN84JL191a9DybGJXIEJ6AcN5TxuBwXHV/KlnEK57AGj1WS5VOhKbHGoSwpRU5m +BAtCfJj0zBVqME9W/rROR5mxhta/kG71594STPhXKppyQaH+f41lseNf32So0O+w +PdCVebFJgNnCM8Sl+NMrfqiVKW17bAwk4POtbSVqALq3Y2mseDUr0ggU/ZNgeKHy +bDxPBSWAAI3kE75yZlXrAJYYiEWgc5GMZJQgFqOJfw1nDmfZL626ckyDdsJotiJO +6pZKmFqLlTPkXzw1t45z8/ZI8p/oWrMnTS/IGMcTobXcWHEBvbn9Ljt6nBLrZgO6 +67vTGss5KhjvfyKwNyQGkG+KIoUJLoewFJ6l5okZB5JIALYn1f/P3bl/kJPUDNp4 +eP2ao9kSYBBOwutUe1lH8tQYrNGA0C80hPykvbWDHcvF13J5k2E= +=KNz3 +-----END PGP SIGNATURE----- diff --git a/Python-3.12.13.tar.xz.sigstore b/Python-3.12.13.tar.xz.sigstore new file mode 100644 index 0000000..a51cafb --- /dev/null +++ b/Python-3.12.13.tar.xz.sigstore @@ -0,0 +1 @@ +{"mediaType": "application/vnd.dev.sigstore.bundle.v0.3+json", "verificationMaterial": {"certificate": {"rawBytes": "MIICyjCCAlGgAwIBAgIUO7TJR+RHchxVU5kgvbim2H9+cbcwCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjYwMzAzMTMxMjIwWhcNMjYwMzAzMTMyMjIwWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAELwC+xgTfcROEXl4pozmTWsTNPZLTeacmkg6Hg0WATZMDJ+lr38EW6hvCs6TDkHrSaW6cdK1cwiJkn1Fll29q/KOCAXAwggFsMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUmvaaERiEcY/i892YYr9Mxt7u1pAwHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0RAQH/BBUwE4ERdGhvbWFzQHB5dGhvbi5vcmcwKQYKKwYBBAGDvzABAQQbaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tMCsGCisGAQQBg78wAQgEHQwbaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tMIGLBgorBgEEAdZ5AgQCBH0EewB5AHcA3T0wasbHETJjGR4cmWc3AqJKXrjePK3/h4pygC8p7o4AAAGcs9P79QAABAMASDBGAiEAtjJfOYWsz9g9ZW3xOzvooREK151hFSCpuGGQfA0CoEECIQChliLi08aP9JK7exWp1EUkEsLQ8xS3k6dKzK08r1FK3jAKBggqhkjOPQQDAwNnADBkAjA5RnsbbOv8594Rg66k8ehuGKRy9tuwnGeh+Ms/7QH9azMryf4lq2MWW6gs3oJFeYcCMC/oCuy0KqaSKLjL+Bjkw206Xydj9Wcxzi6n/HeqnxiZrBz790kpkwjsxOJnaUIQyg=="}, "tlogEntries": [{"logIndex": "1017907816", "logId": {"keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="}, "kindVersion": {"kind": "hashedrekord", "version": "0.0.1"}, "integratedTime": "1772543540", "inclusionPromise": {"signedEntryTimestamp": "MEYCIQDT7wtacuqV+7MUnwBq5Rqq3l63sLEGHZI1XuWp0421qgIhAP1/dl8he7N/t5VMUhca4SFy/Wd1VCYHhB8pvaVeTnG6"}, "inclusionProof": {"logIndex": "896003554", "rootHash": "dduWJQVh9hToIh7KBktgBf1ZmjzxXKBtY6RlC8Qvck8=", "treeSize": "896003562", "hashes": ["c24gaFO/5zpzzLClPoHIHcfL0tXHo4KM0fe1kRP1mXA=", "2TTK3bhgXfKMKbX6Sykzb4FK7KWTGFwZt3cL6RDnrhQ=", "UDmpPuP1lUhqv/P+G1TT3lwHHar8e66rgtFoftcCyFA=", "1cimjEHaKfeVzMwQ2g5aNI2AY+mKuyefuKu4bl3dYYY=", "ov3364KQKY67aOFB2yraPDt2tN2J3ubsoFc0Qz4Uyqc=", "QDY5M9oZY+lj4k8u1dw8TLSPZMx2RaFU6azxmtI/DYk=", "wjOmQYl/uPBoLszh0aCCIaStXoKgMBx2hr8/yd8mrxw=", "SWlkQuEKVKLExEBBYik+E2ntQcWU8FXaStLk5OR58Hw=", "TT/C2pqjIfvIL3alv8+8t803UUA+J7F3G3RJBGX47qo=", "QIvLvG9kOJaMYUH84Qv3nYMwHBgvO09NBWZgAQxV/XQ=", "Xu3Ph++KXQYw4sr2FXO+m6ejdFnRdvIq0sNIXZ3JPeI=", "X/ABFC6+4cGeNLxsbeuvEES5P1gqWZNVz354NrulKvs=", "JRrqNWh/H7qLgers5uYHsZhlBeUG0Iq15/rzmx5nOnM=", "zqeC5oCJfF7U0j+xFOZMczDTNKLpXtPqv1Bm2CRa+q8=", "3MUmJMn+WmTO/xZck3ZnB+/1ODBh1XagFTFyOYA8fGg=", "9kv572LTRu9iSxQwHZ/9IjIVAil7jC0UKQGvJ1+OSIc=", "Qiu5gIc/ZjU7HM63IWVs3PCkgNTV4cY0dnn0aOI66WY=", "TowAI7Ml+oo4i97aYU8IPGwFN1B4qy+pdx75ciLu3E8=", "Xo5tam8gxbsWohATkFEqn5hvHpPFwBJ0SDjNE5DiI2A=", "ZleKYeRKwUF3HP3HO0kxHMVeJgY3N/euGinVhlVWaq0=", "fLAvE46NqCVV86EpB2pKkwJlFjjFk7ntX3lC+PiZuIo=", "T4DqWD42hAtN+vX8jKCWqoC4meE4JekI9LxYGCcPy1M="], "checkpoint": {"envelope": "rekor.sigstore.dev - 1193050959916656506\n896003562\ndduWJQVh9hToIh7KBktgBf1ZmjzxXKBtY6RlC8Qvck8=\n\n\u2014 rekor.sigstore.dev wNI9ajBEAiBkoWZ7HDLN0R8PyB2wRfwbnaOwvM8cdqelTzCaeOAFzQIgREZTN2XN/tZDjqkuie8cGAVFpOtF05VIsGCgvUZX9+s=\n"}}, "canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiJjMDhiYzY1YTgxOTcxYzFkZDU3ODMxODI4MjY1MDMzNjk0NjZjN2U2NzM3NGQxNjQ2NTE5YWRmMDUyMDdiNjg0In19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FVUNJUURpN3FEa0c3UGQvaEpiYnVCK0MwZlF1bDlUaDlwY253Y2I0QVpnSFY0L09RSWdhVDdqZkg0cWdQbWJOSE5jbzFpMVdWdTUzS3ZBanI1bVBIRGVBcVY5RThvPSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVTjVha05EUVd4SFowRjNTVUpCWjBsVlR6ZFVTbElyVWtoamFIaFdWVFZyWjNaaWFXMHlTRGtyWTJKamQwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcFpkMDE2UVhwTlZFMTRUV3BKZDFkb1kwNU5hbGwzVFhwQmVrMVVUWGxOYWtsM1YycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVZNZDBNcmVHZFVabU5TVDBWWWJEUndiM3B0VkZkelZFNVFXa3hVWldGamJXdG5Oa2dLWnpCWFFWUmFUVVJLSzJ4eU16aEZWelpvZGtOek5sUkVhMGh5VTJGWE5tTmtTekZqZDJsS2EyNHhSbXhzTWpseEwwdFBRMEZZUVhkblowWnpUVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXUkNaMDVXU0ZFMFJVWm5VVlZ0ZG1GaENrVlNhVVZqV1M5cE9Ea3lXVmx5T1UxNGREZDFNWEJCZDBoM1dVUldVakJxUWtKbmQwWnZRVlV6T1ZCd2VqRlphMFZhWWpWeFRtcHdTMFpYYVhocE5Ga0tXa1E0ZDBoM1dVUldVakJTUVZGSUwwSkNWWGRGTkVWU1pFZG9kbUpYUm5wUlNFSTFaRWRvZG1KcE5YWmpiV04zUzFGWlMwdDNXVUpDUVVkRWRucEJRZ3BCVVZGaVlVaFNNR05JVFRaTWVUbG9XVEpPZG1SWE5UQmplVFZ1WWpJNWJtSkhWWFZaTWpsMFRVTnpSME5wYzBkQlVWRkNaemM0ZDBGUlowVklVWGRpQ21GSVVqQmpTRTAyVEhrNWFGa3lUblprVnpVd1kzazFibUl5T1c1aVIxVjFXVEk1ZEUxSlIweENaMjl5UW1kRlJVRmtXalZCWjFGRFFrZ3dSV1YzUWpVS1FVaGpRVE5VTUhkaGMySklSVlJLYWtkU05HTnRWMk16UVhGS1MxaHlhbVZRU3pNdmFEUndlV2RET0hBM2J6UkJRVUZIWTNNNVVEYzVVVUZCUWtGTlFRcFRSRUpIUVdsRlFYUnFTbVpQV1ZkemVqbG5PVnBYTTNoUGVuWnZiMUpGU3pFMU1XaEdVME53ZFVkSFVXWkJNRU52UlVWRFNWRkRhR3hwVEdrd09HRlFDamxLU3pkbGVGZHdNVVZWYTBWelRGRTRlRk16YXpaa1MzcExNRGh5TVVaTE0ycEJTMEpuWjNGb2EycFBVRkZSUkVGM1RtNUJSRUpyUVdwQk5WSnVjMklLWWs5Mk9EVTVORkpuTmpack9HVm9kVWRMVW5rNWRIVjNia2RsYUN0TmN5ODNVVWc1WVhwTmNubG1OR3h4TWsxWFZ6Wm5jek52U2tabFdXTkRUVU12YndwRGRYa3dTM0ZoVTB0TWFrd3JRbXByZHpJd05saDVaR281VjJONGVtazJiaTlJWlhGdWVHbGFja0o2Tnprd2EzQnJkMnB6ZUU5S2JtRlZTVkY1WnowOUNpMHRMUzB0UlU1RUlFTkZVbFJKUmtsRFFWUkZMUzB0TFMwSyJ9fX19"}], "timestampVerificationData": {}}, "messageSignature": {"messageDigest": {"algorithm": "SHA2_256", "digest": "wIvGWoGXHB3VeDGCgmUDNpRmx+ZzdNFkZRmt8FIHtoQ="}, "signature": "MEUCIQDi7qDkG7Pd/hJbbuB+C0fQul9Th9pcnwcb4AZgHV4/OQIgaT7jfH4qgPmbNHNco1i1WVu53KvAjr5mPHDeAqV9E8o="}} diff --git a/fix_configure_rst.patch b/fix_configure_rst.patch index 2528ab1..312be1f 100644 --- a/fix_configure_rst.patch +++ b/fix_configure_rst.patch @@ -3,10 +3,10 @@ Misc/NEWS | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) -Index: Python-3.12.12/Doc/using/configure.rst +Index: Python-3.12.13/Doc/using/configure.rst =================================================================== ---- Python-3.12.12.orig/Doc/using/configure.rst 2025-10-09 13:07:00.000000000 +0200 -+++ Python-3.12.12/Doc/using/configure.rst 2025-11-15 16:08:56.030736737 +0100 +--- Python-3.12.13.orig/Doc/using/configure.rst 2026-03-06 20:22:08.230317302 +0100 ++++ Python-3.12.13/Doc/using/configure.rst 2026-03-06 20:22:22.242697945 +0100 @@ -640,13 +640,11 @@ See ``Mac/README.rst``. @@ -21,11 +21,11 @@ Index: Python-3.12.12/Doc/using/configure.rst .. option:: --enable-framework=INSTALLDIR Create a Python.framework rather than a traditional Unix install. Optional -Index: Python-3.12.12/Misc/NEWS +Index: Python-3.12.13/Misc/NEWS =================================================================== ---- Python-3.12.12.orig/Misc/NEWS 2025-10-09 13:07:00.000000000 +0200 -+++ Python-3.12.12/Misc/NEWS 2025-11-15 16:08:56.040736728 +0100 -@@ -15234,7 +15234,7 @@ +--- Python-3.12.13.orig/Misc/NEWS 2026-03-06 20:22:08.230317302 +0100 ++++ Python-3.12.13/Misc/NEWS 2026-03-06 20:22:22.248451941 +0100 +@@ -15317,7 +15317,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 diff --git a/pass-test_write_read_limited_history.patch b/pass-test_write_read_limited_history.patch index 7eadf12..a407c45 100644 --- a/pass-test_write_read_limited_history.patch +++ b/pass-test_write_read_limited_history.patch @@ -1,7 +1,11 @@ -Index: Python-3.12.12/Modules/readline.c +--- + Modules/readline.c | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +Index: Python-3.12.13/Modules/readline.c =================================================================== ---- Python-3.12.12.orig/Modules/readline.c 2025-11-19 20:17:29.982940492 +0100 -+++ Python-3.12.12/Modules/readline.c 2025-11-19 20:36:46.627307300 +0100 +--- Python-3.12.13.orig/Modules/readline.c 2026-03-03 13:39:30.000000000 +0100 ++++ Python-3.12.13/Modules/readline.c 2026-03-06 20:22:54.135627806 +0100 @@ -145,6 +145,8 @@ #define readlinestate_global ((readlinestate *)PyModule_GetState(PyState_FindModule(&readlinemodule))) diff --git a/python312.changes b/python312.changes index b67b7a6..ff40af9 100644 --- a/python312.changes +++ b/python312.changes @@ -1,3 +1,86 @@ +------------------------------------------------------------------- +Fri Mar 6 19:20:34 UTC 2026 - Matej Cepl + +- Update to 3.12.13: + - Python 3.12.13 final + - Release date: 2026-03-03 + - 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. +- 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 + ------------------------------------------------------------------- Fri Feb 6 00:07:20 CET 2026 - Matej Cepl diff --git a/python312.spec b/python312.spec index 17eeef8..9ea95ad 100644 --- a/python312.spec +++ b/python312.spec @@ -118,7 +118,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.12.12 +Version: 3.12.13 Release: 0 Summary: Python 3 Interpreter License: Python-2.0 @@ -189,39 +189,15 @@ Patch44: doc-py38-to-py36.patch Patch45: bsc1243155-sphinx-non-determinism.patch # PATCH-FIX-OPENSUSE gh139257-Support-docutils-0.22.patch gh#python/cpython#139257 daniel.garcia@suse.com Patch46: gh139257-Support-docutils-0.22.patch -# PATCH-FIX-UPSTREAM CVE-2025-6075-expandvars-perf-degrad.patch bsc#1252974 mcepl@suse.com -# Avoid potential quadratic complexity vulnerabilities in path modules -Patch47: CVE-2025-6075-expandvars-perf-degrad.patch # PATCH-FIX-UPSTREAM pass-test_write_read_limited_history.patch bsc#[0-9]+ mcepl@suse.com # Fix readline history truncation when length is reduced Patch48: pass-test_write_read_limited_history.patch -# PATCH-FIX-UPSTREAM CVE-2025-13836-http-resp-cont-len.patch bsc#1254400 mcepl@suse.com -# Avoid loading possibly compromised length of HTTP response -Patch49: CVE-2025-13836-http-resp-cont-len.patch -# PATCH-FIX-UPSTREAM CVE-2025-12084-minidom-quad-search.patch bsc#1254997 mcepl@suse.com -# prevent quadratic behavior in node ID cache clearing -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 # PATCH-FIX-UPSTREAM CVE-2025-15367-poplib-ctrl-chars.patch bsc#1257041 mcepl@suse.com # Reject control characters in poplib Patch58: CVE-2025-15367-poplib-ctrl-chars.patch