Date: Fri, 12 Jun 2026 05:58:53 +0000 From: Charlie Li <vishwin@FreeBSD.org> To: ports-committers@FreeBSD.org, dev-commits-ports-all@FreeBSD.org, dev-commits-ports-branches@FreeBSD.org Cc: Matthias Andree <mandree@FreeBSD.org> Subject: git: 7bec71c4243b - 2026Q2 - lang/python314: Update to 3.14.5 Message-ID: <6a2ba01d.436f2.101e95ee@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch 2026Q2 has been updated by vishwin: URL: https://cgit.FreeBSD.org/ports/commit/?id=7bec71c4243bdec53bb63a38d561ad41b89e09de commit 7bec71c4243bdec53bb63a38d561ad41b89e09de Author: Matthias Andree <mandree@FreeBSD.org> AuthorDate: 2026-05-11 16:00:29 +0000 Commit: Charlie Li <vishwin@FreeBSD.org> CommitDate: 2026-06-12 05:53:18 +0000 lang/python314: Update to 3.14.5 This release swaps out the incremental garbage collector for the generational one used in 3.13 due to reports of memory pressure. Backport the post-release upstream fix for: Heap Buffer Overflow in pyexpat Character Data Buffering #148441 which is believed to be only triggered in rare circumstances. Changelog: https://www.python.org/downloads/release/python-3145/ PR: 295200 MFH: 2026Q2 (cherry picked from commit ecdfdb02e3cdae8b5d61d074175ee0424f90bd85) --- lang/python314/Makefile | 2 +- lang/python314/Makefile.version | 2 +- lang/python314/distinfo | 6 +- ...211-reject-CR_LF-in-HTTP-tunnel-request-headers | 108 --------------------- ...ix-quadratic-regex-backtracking-in-configparser | 83 ---------------- ...action_substitution-bypass-of-dash-prefix-check | 66 ------------- ...tch-gh-148395-fix-possible-uaf-in-decompressors | 65 ------------- ...integer-overflow-in-Expats-CharacterDataHandler | 70 +++++++++++++ lang/python314/pkg-plist | 7 +- 9 files changed, 77 insertions(+), 332 deletions(-) diff --git a/lang/python314/Makefile b/lang/python314/Makefile index d3513d47ad73..55ea7849a9cf 100644 --- a/lang/python314/Makefile +++ b/lang/python314/Makefile @@ -1,6 +1,6 @@ PORTNAME= python DISTVERSION= ${PYTHON_DISTVERSION} # see Makefile.version -PORTREVISION= 3 +PORTREVISION= 0 CATEGORIES= lang python MASTER_SITES= PYTHON/ftp/python/${DISTVERSION:C/[a-z].*//} PKGNAMESUFFIX= ${PYTHON_SUFFIX} diff --git a/lang/python314/Makefile.version b/lang/python314/Makefile.version index c8ccfa3963b0..01917fa79e66 100644 --- a/lang/python314/Makefile.version +++ b/lang/python314/Makefile.version @@ -4,4 +4,4 @@ # 1. Update python documentation (lang/python-doc-*) # Run "make -C lang/python-doc-html makesum" # 2. Remove PORTREVISION in Makefile -PYTHON_DISTVERSION= 3.14.4 +PYTHON_DISTVERSION= 3.14.5 diff --git a/lang/python314/distinfo b/lang/python314/distinfo index 7c5dead58955..762b3cb841c8 100644 --- a/lang/python314/distinfo +++ b/lang/python314/distinfo @@ -1,3 +1,3 @@ -TIMESTAMP = 1775640582 -SHA256 (python/Python-3.14.4.tar.xz) = d923c51303e38e249136fc1bdf3568d56ecb03214efdef48516176d3d7faaef8 -SIZE (python/Python-3.14.4.tar.xz) = 23855332 +TIMESTAMP = 1778513616 +SHA256 (python/Python-3.14.5.tar.xz) = 7e32597b99e5d9a39abed35de4693fa169df3e5850d4c334337ffd6a19a36db6 +SIZE (python/Python-3.14.5.tar.xz) = 23903332 diff --git a/lang/python314/files/patch-gh-146211-reject-CR_LF-in-HTTP-tunnel-request-headers b/lang/python314/files/patch-gh-146211-reject-CR_LF-in-HTTP-tunnel-request-headers deleted file mode 100644 index 989f22a0529b..000000000000 --- a/lang/python314/files/patch-gh-146211-reject-CR_LF-in-HTTP-tunnel-request-headers +++ /dev/null @@ -1,108 +0,0 @@ -From afdd351544e8112d4070a31f2218f99256697472 Mon Sep 17 00:00:00 2001 -From: Seth Larson <seth@python.org> -Date: Fri, 10 Apr 2026 10:21:42 -0500 -Subject: [PATCH] gh-146211: Reject CR/LF in HTTP tunnel request headers - (GH-146212) (cherry picked from commit - 05ed7ce7ae9e17c23a04085b2539fe6d6d3cef69) - -Co-authored-by: Seth Larson <seth@python.org> -Co-authored-by: Illia Volochii <illia.volochii@gmail.com> ---- - Lib/http/client.py | 11 ++++- - Lib/test/test_httplib.py | 45 +++++++++++++++++++ - ...-03-20-09-29-42.gh-issue-146211.PQVbs7.rst | 2 + - 3 files changed, 57 insertions(+), 1 deletion(-) - create mode 100644 Misc/NEWS.d/next/Security/2026-03-20-09-29-42.gh-issue-146211.PQVbs7.rst - -diff --git a/Lib/http/client.py b/Lib/http/client.py -index 77f8d26291dfc2..6fb7d254ea9c27 100644 ---- ./Lib/http/client.py -+++ b/Lib/http/client.py -@@ -972,13 +972,22 @@ def _wrap_ipv6(self, ip): - return ip - - def _tunnel(self): -+ if _contains_disallowed_url_pchar_re.search(self._tunnel_host): -+ raise ValueError('Tunnel host can\'t contain control characters %r' -+ % (self._tunnel_host,)) - connect = b"CONNECT %s:%d %s\r\n" % ( - self._wrap_ipv6(self._tunnel_host.encode("idna")), - self._tunnel_port, - self._http_vsn_str.encode("ascii")) - headers = [connect] - for header, value in self._tunnel_headers.items(): -- headers.append(f"{header}: {value}\r\n".encode("latin-1")) -+ header_bytes = header.encode("latin-1") -+ value_bytes = value.encode("latin-1") -+ if not _is_legal_header_name(header_bytes): -+ raise ValueError('Invalid header name %r' % (header_bytes,)) -+ if _is_illegal_header_value(value_bytes): -+ raise ValueError('Invalid header value %r' % (value_bytes,)) -+ headers.append(b"%s: %s\r\n" % (header_bytes, value_bytes)) - headers.append(b"\r\n") - # Making a single send() call instead of one per line encourages - # the host OS to use a more optimal packet size instead of -diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py -index bcb828edec7c39..6f3eac6b98a4de 100644 ---- ./Lib/test/test_httplib.py -+++ b/Lib/test/test_httplib.py -@@ -369,6 +369,51 @@ def test_invalid_headers(self): - with self.assertRaisesRegex(ValueError, 'Invalid header'): - conn.putheader(name, value) - -+ def test_invalid_tunnel_headers(self): -+ cases = ( -+ ('Invalid\r\nName', 'ValidValue'), -+ ('Invalid\rName', 'ValidValue'), -+ ('Invalid\nName', 'ValidValue'), -+ ('\r\nInvalidName', 'ValidValue'), -+ ('\rInvalidName', 'ValidValue'), -+ ('\nInvalidName', 'ValidValue'), -+ (' InvalidName', 'ValidValue'), -+ ('\tInvalidName', 'ValidValue'), -+ ('Invalid:Name', 'ValidValue'), -+ (':InvalidName', 'ValidValue'), -+ ('ValidName', 'Invalid\r\nValue'), -+ ('ValidName', 'Invalid\rValue'), -+ ('ValidName', 'Invalid\nValue'), -+ ('ValidName', 'InvalidValue\r\n'), -+ ('ValidName', 'InvalidValue\r'), -+ ('ValidName', 'InvalidValue\n'), -+ ) -+ for name, value in cases: -+ with self.subTest((name, value)): -+ conn = client.HTTPConnection('example.com') -+ conn.set_tunnel('tunnel', headers={ -+ name: value -+ }) -+ conn.sock = FakeSocket('') -+ with self.assertRaisesRegex(ValueError, 'Invalid header'): -+ conn._tunnel() # Called in .connect() -+ -+ def test_invalid_tunnel_host(self): -+ cases = ( -+ 'invalid\r.host', -+ '\ninvalid.host', -+ 'invalid.host\r\n', -+ 'invalid.host\x00', -+ 'invalid host', -+ ) -+ for tunnel_host in cases: -+ with self.subTest(tunnel_host): -+ conn = client.HTTPConnection('example.com') -+ conn.set_tunnel(tunnel_host) -+ conn.sock = FakeSocket('') -+ with self.assertRaisesRegex(ValueError, 'Tunnel host can\'t contain control characters'): -+ conn._tunnel() # Called in .connect() -+ - def test_headers_debuglevel(self): - body = ( - b'HTTP/1.1 200 OK\r\n' -diff --git a/Misc/NEWS.d/next/Security/2026-03-20-09-29-42.gh-issue-146211.PQVbs7.rst b/Misc/NEWS.d/next/Security/2026-03-20-09-29-42.gh-issue-146211.PQVbs7.rst -new file mode 100644 -index 00000000000000..4993633b8ebebb ---- /dev/null -+++ ./Misc/NEWS.d/next/Security/2026-03-20-09-29-42.gh-issue-146211.PQVbs7.rst -@@ -0,0 +1,2 @@ -+Reject CR/LF characters in tunnel request headers for the -+HTTPConnection.set_tunnel() method. diff --git a/lang/python314/files/patch-gh-146333-Fix-quadratic-regex-backtracking-in-configparser b/lang/python314/files/patch-gh-146333-Fix-quadratic-regex-backtracking-in-configparser deleted file mode 100644 index 7dffa8ff1cfe..000000000000 --- a/lang/python314/files/patch-gh-146333-Fix-quadratic-regex-backtracking-in-configparser +++ /dev/null @@ -1,83 +0,0 @@ -From ab8704a8e05e2f926c10f994e4085e8726048fa4 Mon Sep 17 00:00:00 2001 -From: Joshua Swanson <22283299+joshuaswanson@users.noreply.github.com> -Date: Tue, 7 Apr 2026 16:10:34 +0200 -Subject: [PATCH] gh-146333: Fix quadratic regex backtracking in configparser - option parsing (GH-146399) - -Use negative lookahead in option regex to prevent backtracking, and to avoid changing logic outside the regexes (since people could use the regex directly). -(cherry picked from commit 7e0a0be4097f9d29d66fe23f5af86f18a34ed7dd) - -Co-authored-by: Joshua Swanson <22283299+joshuaswanson@users.noreply.github.com> ---- - Lib/configparser.py | 8 ++++++-- - Lib/test/test_configparser.py | 20 +++++++++++++++++++ - ...3-25-00-51-03.gh-issue-146333.LqdL__bn.rst | 3 +++ - 3 files changed, 29 insertions(+), 2 deletions(-) - create mode 100644 Misc/NEWS.d/next/Security/2026-03-25-00-51-03.gh-issue-146333.LqdL__bn.rst - -diff --git a/Lib/configparser.py b/Lib/configparser.py -index d435a5c2fe0da2..e76647d339e913 100644 ---- ./Lib/configparser.py -+++ b/Lib/configparser.py -@@ -613,7 +613,9 @@ class RawConfigParser(MutableMapping): - \] # ] - """ - _OPT_TMPL = r""" -- (?P<option>.*?) # very permissive! -+ (?P<option> # very permissive! -+ (?:(?!{delim})\S)* # non-delimiter non-whitespace -+ (?:\s+(?:(?!{delim})\S)+)*) # optionally more words - \s*(?P<vi>{delim})\s* # any number of space/tab, - # followed by any of the - # allowed delimiters, -@@ -621,7 +623,9 @@ class RawConfigParser(MutableMapping): - (?P<value>.*)$ # everything up to eol - """ - _OPT_NV_TMPL = r""" -- (?P<option>.*?) # very permissive! -+ (?P<option> # very permissive! -+ (?:(?!{delim})\S)* # non-delimiter non-whitespace -+ (?:\s+(?:(?!{delim})\S)+)*) # optionally more words - \s*(?: # any number of space/tab, - (?P<vi>{delim})\s* # optionally followed by - # any of the allowed -diff --git a/Lib/test/test_configparser.py b/Lib/test/test_configparser.py -index 1bfb53ccbb1398..d7c4f19c1a5ef0 100644 ---- ./Lib/test/test_configparser.py -+++ b/Lib/test/test_configparser.py -@@ -2270,6 +2270,26 @@ def test_section_bracket_in_key(self): - output.close() - - -+class ReDoSTestCase(unittest.TestCase): -+ """Regression tests for quadratic regex backtracking (gh-146333).""" -+ -+ def test_option_regex_does_not_backtrack(self): -+ # A line with many spaces between non-delimiter characters -+ # should be parsed in linear time, not quadratic. -+ parser = configparser.RawConfigParser() -+ content = "[section]\n" + "x" + " " * 40000 + "y" + "\n" -+ # This should complete almost instantly. Before the fix, -+ # it would take over a minute due to catastrophic backtracking. -+ with self.assertRaises(configparser.ParsingError): -+ parser.read_string(content) -+ -+ def test_option_regex_no_value_does_not_backtrack(self): -+ parser = configparser.RawConfigParser(allow_no_value=True) -+ content = "[section]\n" + "x" + " " * 40000 + "y" + "\n" -+ parser.read_string(content) -+ self.assertTrue(parser.has_option("section", "x" + " " * 40000 + "y")) -+ -+ - class MiscTestCase(unittest.TestCase): - def test__all__(self): - support.check__all__(self, configparser, not_exported={"Error"}) -diff --git a/Misc/NEWS.d/next/Security/2026-03-25-00-51-03.gh-issue-146333.LqdL__bn.rst b/Misc/NEWS.d/next/Security/2026-03-25-00-51-03.gh-issue-146333.LqdL__bn.rst -new file mode 100644 -index 00000000000000..96d86ecc0a0fb3 ---- /dev/null -+++ ./Misc/NEWS.d/next/Security/2026-03-25-00-51-03.gh-issue-146333.LqdL__bn.rst -@@ -0,0 +1,3 @@ -+Fix quadratic backtracking in :class:`configparser.RawConfigParser` option -+parsing regexes (``OPTCRE`` and ``OPTCRE_NV``). A crafted configuration line -+with many whitespace characters could cause excessive CPU usage. diff --git a/lang/python314/files/patch-gh-148169-fix-webbrowser-_action_substitution-bypass-of-dash-prefix-check b/lang/python314/files/patch-gh-148169-fix-webbrowser-_action_substitution-bypass-of-dash-prefix-check deleted file mode 100644 index 5407326b750a..000000000000 --- a/lang/python314/files/patch-gh-148169-fix-webbrowser-_action_substitution-bypass-of-dash-prefix-check +++ /dev/null @@ -1,66 +0,0 @@ -From f529b9470752c28ab69c96f31b0dbc10db69b404 Mon Sep 17 00:00:00 2001 -From: Stan Ulbrych <stan@python.org> -Date: Mon, 13 Apr 2026 20:02:52 +0100 -Subject: [PATCH] gh-148169: Fix webbrowser `%action` substitution bypass of - dash-prefix check (GH-148170) (cherry picked from commit - d22922c8a7958353689dc4763dd72da2dea03fff) - -Co-authored-by: Stan Ulbrych <stan@python.org> ---- - Lib/test/test_webbrowser.py | 9 +++++++++ - Lib/webbrowser.py | 5 +++-- - .../2026-03-31-09-15-51.gh-issue-148169.EZJzz2.rst | 2 ++ - 3 files changed, 14 insertions(+), 2 deletions(-) - create mode 100644 Misc/NEWS.d/next/Security/2026-03-31-09-15-51.gh-issue-148169.EZJzz2.rst - -diff --git a/Lib/test/test_webbrowser.py b/Lib/test/test_webbrowser.py -index 404b3a31a5d2c9..bfbcf112b0b085 100644 ---- ./Lib/test/test_webbrowser.py -+++ b/Lib/test/test_webbrowser.py -@@ -119,6 +119,15 @@ def test_open_bad_new_parameter(self): - arguments=[URL], - kw=dict(new=999)) - -+ def test_reject_action_dash_prefixes(self): -+ browser = self.browser_class(name=CMD_NAME) -+ with self.assertRaises(ValueError): -+ browser.open('%action--incognito') -+ # new=1: action is "--new-window", so "%action" itself expands to -+ # a dash-prefixed flag even with no dash in the original URL. -+ with self.assertRaises(ValueError): -+ browser.open('%action', new=1) -+ - - class EdgeCommandTest(CommandTestMixin, unittest.TestCase): - -diff --git a/Lib/webbrowser.py b/Lib/webbrowser.py -index 0e0b5034e5f53d..97aad6eea509eb 100644 ---- ./Lib/webbrowser.py -+++ b/Lib/webbrowser.py -@@ -274,7 +274,6 @@ def _invoke(self, args, remote, autoraise, url=None): - - def open(self, url, new=0, autoraise=True): - sys.audit("webbrowser.open", url) -- self._check_url(url) - if new == 0: - action = self.remote_action - elif new == 1: -@@ -288,7 +287,9 @@ def open(self, url, new=0, autoraise=True): - raise Error("Bad 'new' parameter to open(); " - f"expected 0, 1, or 2, got {new}") - -- args = [arg.replace("%s", url).replace("%action", action) -+ self._check_url(url.replace("%action", action)) -+ -+ args = [arg.replace("%action", action).replace("%s", url) - for arg in self.remote_args] - args = [arg for arg in args if arg] - success = self._invoke(args, True, autoraise, url) -diff --git a/Misc/NEWS.d/next/Security/2026-03-31-09-15-51.gh-issue-148169.EZJzz2.rst b/Misc/NEWS.d/next/Security/2026-03-31-09-15-51.gh-issue-148169.EZJzz2.rst -new file mode 100644 -index 00000000000000..45cdeebe1b6d64 ---- /dev/null -+++ ./Misc/NEWS.d/next/Security/2026-03-31-09-15-51.gh-issue-148169.EZJzz2.rst -@@ -0,0 +1,2 @@ -+A bypass in :mod:`webbrowser` allowed URLs prefixed with ``%action`` to pass -+the dash-prefix safety check. diff --git a/lang/python314/files/patch-gh-148395-fix-possible-uaf-in-decompressors b/lang/python314/files/patch-gh-148395-fix-possible-uaf-in-decompressors deleted file mode 100644 index d5532033752e..000000000000 --- a/lang/python314/files/patch-gh-148395-fix-possible-uaf-in-decompressors +++ /dev/null @@ -1,65 +0,0 @@ -From c8d8173c4b06d06902c99ec010ad785a30952880 Mon Sep 17 00:00:00 2001 -From: Stan Ulbrych <stan@python.org> -Date: Mon, 13 Apr 2026 02:14:54 +0100 -Subject: [PATCH] gh-148395: Fix a possible UAF in - `{LZMA,BZ2,_Zlib}Decompressor` (GH-148396) - -Fix dangling input pointer after `MemoryError` in _lzma/_bz2/_ZlibDecompressor.decompress -(cherry picked from commit 8fc66aef6d7b3ae58f43f5c66f9366cc8cbbfcd2) - -Co-authored-by: Stan Ulbrych <stan@python.org> ---- - .../Security/2026-04-10-16-28-21.gh-issue-148395.kfzm0G.rst | 5 +++++ - Modules/_bz2module.c | 1 + - Modules/_lzmamodule.c | 1 + - Modules/zlibmodule.c | 1 + - 4 files changed, 8 insertions(+) - create mode 100644 Misc/NEWS.d/next/Security/2026-04-10-16-28-21.gh-issue-148395.kfzm0G.rst - -diff --git a/Misc/NEWS.d/next/Security/2026-04-10-16-28-21.gh-issue-148395.kfzm0G.rst b/Misc/NEWS.d/next/Security/2026-04-10-16-28-21.gh-issue-148395.kfzm0G.rst -new file mode 100644 -index 00000000000000..9502189ab199c1 ---- /dev/null -+++ ./Misc/NEWS.d/next/Security/2026-04-10-16-28-21.gh-issue-148395.kfzm0G.rst -@@ -0,0 +1,5 @@ -+Fix a dangling input pointer in :class:`lzma.LZMADecompressor`, -+:class:`bz2.BZ2Decompressor`, and internal :class:`!zlib._ZlibDecompressor` -+when memory allocation fails with :exc:`MemoryError`, which could let a -+subsequent :meth:`!decompress` call read or write through a stale pointer to -+the already-released caller buffer. -diff --git a/Modules/_bz2module.c b/Modules/_bz2module.c -index 9e85e0de42cd8d..055ce82e7d2863 100644 ---- ./Modules/_bz2module.c -+++ b/Modules/_bz2module.c -@@ -593,6 +593,7 @@ decompress(BZ2Decompressor *d, char *data, size_t len, Py_ssize_t max_length) - return result; - - error: -+ bzs->next_in = NULL; - Py_XDECREF(result); - return NULL; - } -diff --git a/Modules/_lzmamodule.c b/Modules/_lzmamodule.c -index 462c2181fa6036..6785dc56730c5c 100644 ---- ./Modules/_lzmamodule.c -+++ b/Modules/_lzmamodule.c -@@ -1120,6 +1120,7 @@ decompress(Decompressor *d, uint8_t *data, size_t len, Py_ssize_t max_length) - return result; - - error: -+ lzs->next_in = NULL; - Py_XDECREF(result); - return NULL; - } -diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c -index 5b6b0c5cac864a..a86aa5fdbb576c 100644 ---- ./Modules/zlibmodule.c -+++ b/Modules/zlibmodule.c -@@ -1675,6 +1675,7 @@ decompress(ZlibDecompressor *self, uint8_t *data, - return result; - - error: -+ self->zst.next_in = NULL; - Py_XDECREF(result); - return NULL; - } diff --git a/lang/python314/files/patch-gh-148441-Avoid-integer-overflow-in-Expats-CharacterDataHandler b/lang/python314/files/patch-gh-148441-Avoid-integer-overflow-in-Expats-CharacterDataHandler new file mode 100644 index 000000000000..1625b93d088f --- /dev/null +++ b/lang/python314/files/patch-gh-148441-Avoid-integer-overflow-in-Expats-CharacterDataHandler @@ -0,0 +1,70 @@ +From 6588ca5b642a0f878197fc31afb6bfa424fd7219 Mon Sep 17 00:00:00 2001 +From: "Miss Islington (bot)" + <31488909+miss-islington@users.noreply.github.com> +Date: Sun, 10 May 2026 16:08:59 +0200 +Subject: [PATCH] [3.14] gh-148441: Avoid integer overflow in Expat's + CharacterDataHandler (GH-148904) (#149638) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +gh-148441: Avoid integer overflow in Expat's CharacterDataHandler (GH-148904) +(cherry picked from commit bc1be4f6174086b4a46e3fe656552f5bb4e6e7b2) + +Co-authored-by: ByteFlow <fakeshadow1337@gmail.com> +Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> +--- + Lib/test/test_pyexpat.py | 14 ++++++++++++++ + .../2026-04-23-12-50-15.gh-issue-148441.zvpCkR.rst | 4 ++++ + Modules/pyexpat.c | 2 +- + 3 files changed, 19 insertions(+), 1 deletion(-) + create mode 100644 Misc/NEWS.d/next/Library/2026-04-23-12-50-15.gh-issue-148441.zvpCkR.rst + +diff --git ./Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py +index 465f65a03b9e15..6eda89ad2cdf2a 100644 +--- ./Lib/test/test_pyexpat.py ++++ b/Lib/test/test_pyexpat.py +@@ -672,6 +672,20 @@ def test_change_size_2(self): + parser.Parse(xml2, True) + self.assertEqual(self.n, 4) + ++ @support.requires_resource('cpu') ++ @support.requires_resource('walltime') ++ @support.bigmemtest(size=2**31, memuse=4, dry_run=False) ++ def test_large_character_data_does_not_crash(self): ++ # See https://github.com/python/cpython/issues/148441 ++ parser = expat.ParserCreate() ++ parser.buffer_text = True ++ parser.buffer_size = 2**31 - 1 # INT_MAX ++ N = 2049 * (1 << 20) - 3 # Character data greater than INT_MAX ++ self.assertGreater(N, parser.buffer_size) ++ parser.CharacterDataHandler = lambda text: None ++ xml_data = b"<r>" + b"A" * N + b"</r>" ++ self.assertEqual(parser.Parse(xml_data, True), 1) ++ + class ElementDeclHandlerTest(unittest.TestCase): + def test_trigger_leak(self): + # Unfixed, this test would leak the memory of the so-called +diff --git a/Misc/NEWS.d/next/Library/2026-04-23-12-50-15.gh-issue-148441.zvpCkR.rst b/Misc/NEWS.d/next/Library/2026-04-23-12-50-15.gh-issue-148441.zvpCkR.rst +new file mode 100644 +index 00000000000000..762815270e4d40 +--- /dev/null ++++ ./Misc/NEWS.d/next/Library/2026-04-23-12-50-15.gh-issue-148441.zvpCkR.rst +@@ -0,0 +1,4 @@ ++:mod:`xml.parsers.expat`: prevent a crash in ++:meth:`~xml.parsers.expat.xmlparser.CharacterDataHandler` ++when the character data size exceeds the parser's ++:attr:`buffer size <xml.parsers.expat.xmlparser.buffer_size>`. +diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c +index f82f8456e489eb..c9dc5e2211ecd5 100644 +--- ./Modules/pyexpat.c ++++ b/Modules/pyexpat.c +@@ -389,7 +389,7 @@ my_CharacterDataHandler(void *userData, const XML_Char *data, int len) + if (self->buffer == NULL) + call_character_handler(self, data, len); + else { +- if ((self->buffer_used + len) > self->buffer_size) { ++ if (len > (self->buffer_size - self->buffer_used)) { + if (flush_character_buffer(self) < 0) + return; + /* handler might have changed; drop the rest on the floor diff --git a/lang/python314/pkg-plist b/lang/python314/pkg-plist index b5fe9727f492..3090f13e1c5d 100644 --- a/lang/python314/pkg-plist +++ b/lang/python314/pkg-plist @@ -1847,7 +1847,7 @@ lib/python%%XYDOT%%/ensurepip/__pycache__/__main__.cpython-%%XY%%.pyc lib/python%%XYDOT%%/ensurepip/__pycache__/_uninstall.cpython-%%XY%%.opt-1.pyc lib/python%%XYDOT%%/ensurepip/__pycache__/_uninstall.cpython-%%XY%%.opt-2.pyc lib/python%%XYDOT%%/ensurepip/__pycache__/_uninstall.cpython-%%XY%%.pyc -lib/python%%XYDOT%%/ensurepip/_bundled/pip-26.0.1-py3-none-any.whl +lib/python%%XYDOT%%/ensurepip/_bundled/pip-26.1.1-py3-none-any.whl lib/python%%XYDOT%%/ensurepip/_uninstall.py lib/python%%XYDOT%%/enum.py lib/python%%XYDOT%%/filecmp.py @@ -2908,9 +2908,6 @@ lib/python%%XYDOT%%/test/__pycache__/_test_eintr.cpython-%%XY%%.pyc lib/python%%XYDOT%%/test/__pycache__/_test_embed_structseq.cpython-%%XY%%.opt-1.pyc lib/python%%XYDOT%%/test/__pycache__/_test_embed_structseq.cpython-%%XY%%.opt-2.pyc lib/python%%XYDOT%%/test/__pycache__/_test_embed_structseq.cpython-%%XY%%.pyc -lib/python%%XYDOT%%/test/__pycache__/_test_gc_fast_cycles.cpython-%%XY%%.opt-1.pyc -lib/python%%XYDOT%%/test/__pycache__/_test_gc_fast_cycles.cpython-%%XY%%.opt-2.pyc -lib/python%%XYDOT%%/test/__pycache__/_test_gc_fast_cycles.cpython-%%XY%%.pyc lib/python%%XYDOT%%/test/__pycache__/_test_monitoring_shutdown.cpython-%%XY%%.opt-1.pyc lib/python%%XYDOT%%/test/__pycache__/_test_monitoring_shutdown.cpython-%%XY%%.opt-2.pyc lib/python%%XYDOT%%/test/__pycache__/_test_monitoring_shutdown.cpython-%%XY%%.pyc @@ -4233,7 +4230,6 @@ lib/python%%XYDOT%%/test/_crossinterp_definitions.py lib/python%%XYDOT%%/test/_test_atexit.py lib/python%%XYDOT%%/test/_test_eintr.py lib/python%%XYDOT%%/test/_test_embed_structseq.py -lib/python%%XYDOT%%/test/_test_gc_fast_cycles.py lib/python%%XYDOT%%/test/_test_monitoring_shutdown.py lib/python%%XYDOT%%/test/_test_multiprocessing.py lib/python%%XYDOT%%/test/_test_venv_multiprocessing.py @@ -6679,6 +6675,7 @@ lib/python%%XYDOT%%/test/test_json/__pycache__/test_tool.cpython-%%XY%%.pyc lib/python%%XYDOT%%/test/test_json/__pycache__/test_unicode.cpython-%%XY%%.opt-1.pyc lib/python%%XYDOT%%/test/test_json/__pycache__/test_unicode.cpython-%%XY%%.opt-2.pyc lib/python%%XYDOT%%/test/test_json/__pycache__/test_unicode.cpython-%%XY%%.pyc +lib/python%%XYDOT%%/test/test_json/json_lines.jsonl lib/python%%XYDOT%%/test/test_json/test_decode.py lib/python%%XYDOT%%/test/test_json/test_default.py lib/python%%XYDOT%%/test/test_json/test_dump.pyhome | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a2ba01d.436f2.101e95ee>
