[Buildroot] [PATCH 1/1] package/python3: security bump version to 3.14.7

Bernd Kuhls <[email protected]>
Newsgroups net.busybox.buildroot
Message-ID <[email protected]>
https://www.python.org/downloads/release/python-3147/
https://docs.python.org/release/3.14.7/whatsnew/changelog.html

Rebased patch 0010 due to upstream commit:
https://github.com/python/cpython/commit/04735deeb2dbdc6404eb38544541abf387d71069#diff-b9d5f29e160364d4616b4bcc3b04538fca8d1d1cca809af4196bcaf16c7c5d40

Removed patches 0011-0015 which are included in this release.

Fixes CVE-2026-12003 and others.

Signed-off-by: Bernd Kuhls <[email protected]>
---
Gitlab pipeline including almost all external python modules built
python3 successfully but crashed due to lack of free disk space:
https://gitlab.com/bkuhls/buildroot/-/commits/f6a31521d51315228f57e5c2f9384bd7abf85585

Gitlab pipeline building only python3 passed:
https://gitlab.com/bkuhls/buildroot/-/commits/e01ff38bf1f65e4f7881debbbd455e525c25b478

 ...mpilation-of-Modules-_remote_debuggi.patch |  15 +-
 ...ix-symlink-escape-via-tarfile-hardli.patch |  83 ----------
 ...ormalize-all-line-endings-CR-CRLF-an.patch |  71 --------
 ...ake-tarfile._Stream.seek-break-at-EO.patch |  76 ---------
 ...ass-filter_function-to-TarFile._extr.patch | 151 ------------------
 ...ix-quadratic-complexity-in-increment.patch | 123 --------------
 package/python3/python3.hash                  |   4 +-
 package/python3/python3.mk                    |  17 +-
 8 files changed, 10 insertions(+), 530 deletions(-)
 delete mode 100644 package/python3/0011-3.14-gh-151558-Fix-symlink-escape-via-tarfile-hardli.patch
 delete mode 100644 package/python3/0012-3.14-gh-143927-Normalize-all-line-endings-CR-CRLF-an.patch
 delete mode 100644 package/python3/0013-3.14-gh-151981-Make-tarfile._Stream.seek-break-at-EO.patch
 delete mode 100644 package/python3/0014-3.14-gh-151987-Pass-filter_function-to-TarFile._extr.patch
 delete mode 100644 package/python3/0015-3.14-gh-153030-Fix-quadratic-complexity-in-increment.patch

diff --git a/package/python3/0010-gh-139275-Fix-compilation-of-Modules-_remote_debuggi.patch b/package/python3/0010-gh-139275-Fix-compilation-of-Modules-_remote_debuggi.patch
index b000a68e9b..833bcc9cc8 100644
--- a/package/python3/0010-gh-139275-Fix-compilation-of-Modules-_remote_debuggi.patch
+++ b/package/python3/0010-gh-139275-Fix-compilation-of-Modules-_remote_debuggi.patch
@@ -7,8 +7,7 @@ Subject: [PATCH] gh-139275: Fix compilation of
 
 Upstream: https://github.com/python/cpython/commit/1963e701001839389cfb1b11d803b0743f4705d7
 
-[ Bernd Kuhls: ported to Python 3.14.4]
-[ Vincent Fazio: update to apply cleanly to 3.14.3 ]
+[ Bernd Kuhls: ported to Python 3.14.7]
 Signed-off-by: Bernd Kuhls <[email protected]>
 ---
  .../2025-09-24-17-32-52.gh-issue-139275.novrqf.rst              | 2 ++
@@ -29,9 +28,9 @@ diff --git a/Modules/_remote_debugging_module.c b/Modules/_remote_debugging_modu
 index b46538b76df..e86a27d5812 100644
 --- a/Modules/_remote_debugging_module.c
 +++ b/Modules/_remote_debugging_module.c
-@@ -834,7 +834,7 @@ _Py_RemoteDebug_GetAsyncioDebugAddress(proc_handle_t* handle)
-         PyErr_SetString(PyExc_RuntimeError, "Failed to find the AsyncioDebug section in the process.");
-         _PyErr_ChainExceptions1(exc);
+@@ -1329,7 +1329,7 @@ _Py_RemoteDebug_GetAsyncioDebugAddress(proc_handle_t* handle)
+             _PyErr_ChainExceptions1(exc);
+         }
      }
 -#elif defined(__linux__)
 +#elif defined(__linux__) && HAVE_PROCESS_VM_READV
@@ -42,9 +41,9 @@ diff --git a/Python/remote_debug.h b/Python/remote_debug.h
 index 8f9b6cd4c49..b7d17a0f345 100644
 --- a/Python/remote_debug.h
 +++ b/Python/remote_debug.h
-@@ -923,7 +923,7 @@
-             handle->pid);
-         _PyErr_ChainExceptions1(exc);
+@@ -1174,7 +1174,7 @@
+             _PyErr_ChainExceptions1(exc);
+         }
      }
 -#elif defined(__linux__)
 +#elif defined(__linux__) && HAVE_PROCESS_VM_READV
diff --git a/package/python3/0011-3.14-gh-151558-Fix-symlink-escape-via-tarfile-hardli.patch b/package/python3/0011-3.14-gh-151558-Fix-symlink-escape-via-tarfile-hardli.patch
deleted file mode 100644
index d3454a7a6b..0000000000
--- a/package/python3/0011-3.14-gh-151558-Fix-symlink-escape-via-tarfile-hardli.patch
+++ /dev/null
@@ -1,83 +0,0 @@
-From 79c06bd5c6afa3c440d50faf7ee1b147c8832b4c Mon Sep 17 00:00:00 2001
-From: "Miss Islington (bot)"
- <[email protected]>
-Date: Tue, 23 Jun 2026 15:58:47 +0200
-Subject: [PATCH] [3.14] gh-151558: Fix symlink escape via `tarfile`
- hardlink-extraction fallback (GH-151559)
-
-(cherry picked from commit 27dd970bf6b17ebca7c8ed486a40ab043ed7af8f)
-
-Co-authored-by: Stan Ulbrych <[email protected]>
-
-Upstream: https://github.com/python/cpython/commit/79c06bd5c6afa3c440d50faf7ee1b147c8832b4c
-CVE: CVE-2026-11940
-
-Signed-off-by: Bernd Kuhls <[email protected]>
----
- Lib/tarfile.py                                |  3 +++
- Lib/test/test_tarfile.py                      | 24 +++++++++++++++++++
- ...-06-10-13-08-19.gh-issue-151558.mL74i2.rst |  3 +++
- 3 files changed, 30 insertions(+)
- create mode 100644 Misc/NEWS.d/next/Security/2026-06-10-13-08-19.gh-issue-151558.mL74i2.rst
-
-diff --git a/Lib/tarfile.py b/Lib/tarfile.py
-index 39b1cd6514c..399f906efdf 100644
---- a/Lib/tarfile.py
-+++ b/Lib/tarfile.py
-@@ -2784,6 +2784,9 @@ def makelink_with_filter(self, tarinfo, targetpath,
-                     "makelink_with_filter: if filter_function is not None, "
-                     + "extraction_root must also not be None")
-             try:
-+                filter_function(
-+                    unfiltered.replace(name=tarinfo.name, deep=False),
-+                    extraction_root)
-                 filtered = filter_function(unfiltered, extraction_root)
-             except _FILTER_ERRORS as cause:
-                 raise LinkFallbackError(tarinfo, unfiltered.name) from cause
-diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py
-index 8503024a690..045377d620c 100644
---- a/Lib/test/test_tarfile.py
-+++ b/Lib/test/test_tarfile.py
-@@ -4344,6 +4344,30 @@ def test_sneaky_hardlink_fallback(self):
-                     self.expect_file("boom", symlink_to='../../link_here')
-                     self.expect_file("c", symlink_to='b')
- 
-+    @symlink_test
-+    def test_sneaky_hardlink_fallback_deep(self):
-+        # (CVE-2026-11940)
-+        with ArchiveMaker() as arc:
-+            arc.add("a/b/s", symlink_to=os.path.join("..", "escape"))
-+            arc.add("s", hardlink_to=os.path.join("a", "b", "s"))
-+
-+        with self.check_context(arc.open(), 'data'):
-+            e = self.expect_exception(
-+                tarfile.LinkFallbackError,
-+                "link 's' would be extracted as a copy of "
-+                + "'a/b/s', which was rejected")
-+            self.assertIsInstance(e.__cause__,
-+                                  tarfile.LinkOutsideDestinationError)
-+
-+        for filter in 'tar', 'fully_trusted':
-+            with self.subTest(filter), self.check_context(arc.open(), filter):
-+                if not os_helper.can_symlink():
-+                    self.expect_file("a/")
-+                    self.expect_file("a/b/")
-+                else:
-+                    self.expect_file("a/b/s", symlink_to=os.path.join('..', 'escape'))
-+                    self.expect_file("s", symlink_to=os.path.join('..', 'escape'))
-+
-     @symlink_test
-     def test_exfiltration_via_symlink(self):
-         # (CVE-2025-4138)
-diff --git a/Misc/NEWS.d/next/Security/2026-06-10-13-08-19.gh-issue-151558.mL74i2.rst b/Misc/NEWS.d/next/Security/2026-06-10-13-08-19.gh-issue-151558.mL74i2.rst
-new file mode 100644
-index 00000000000..74459d5680e
---- /dev/null
-+++ b/Misc/NEWS.d/next/Security/2026-06-10-13-08-19.gh-issue-151558.mL74i2.rst
-@@ -0,0 +1,3 @@
-+Fixed an vulnerability in the :mod:`tarfile` ``data`` and ``tar`` extraction
-+filters where crafted archives could create a symlink pointing outside the
-+destination directory. This was a bypass of :cve:`2025-4330`.
--- 
-2.47.3
-
diff --git a/package/python3/0012-3.14-gh-143927-Normalize-all-line-endings-CR-CRLF-an.patch b/package/python3/0012-3.14-gh-143927-Normalize-all-line-endings-CR-CRLF-an.patch
deleted file mode 100644
index 8c9b35a8d2..0000000000
--- a/package/python3/0012-3.14-gh-143927-Normalize-all-line-endings-CR-CRLF-an.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From 71f2e02a52d47417a6fd69f456346cd8aa7aca98 Mon Sep 17 00:00:00 2001
-From: "Miss Islington (bot)"
- <[email protected]>
-Date: Wed, 24 Jun 2026 11:46:33 +0200
-Subject: [PATCH] [3.14] gh-143927: Normalize all line endings (CR, CRLF, and
- LF) in configparser (GH-143929) (GH-152003)
-
-gh-143927: Normalize all line endings (CR, CRLF, and LF) in configparser (GH-143929)
-(cherry picked from commit 5858e42c539dac8394636a6e9b30472b8994851f)
-
-Co-authored-by: Seth Larson <[email protected]>
-
-Upstream: https://github.com/python/cpython/commit/71f2e02a52d47417a6fd69f456346cd8aa7aca98
-CVE: CVE-2026-0864
-
-Signed-off-by: Bernd Kuhls <[email protected]>
----
- Lib/configparser.py                                   |  4 +++-
- Lib/test/test_configparser.py                         | 11 +++++++++++
- .../2026-01-16-11-58-19.gh-issue-143927.aviFeG.rst    |  2 ++
- 3 files changed, 16 insertions(+), 1 deletion(-)
- create mode 100644 Misc/NEWS.d/next/Security/2026-01-16-11-58-19.gh-issue-143927.aviFeG.rst
-
-diff --git a/Lib/configparser.py b/Lib/configparser.py
-index a53ac872764..3c452afe8ad 100644
---- a/Lib/configparser.py
-+++ b/Lib/configparser.py
-@@ -992,7 +992,9 @@ def _write_section(self, fp, section_name, section_items, delimiter, unnamed=Fal
-             value = self._interpolation.before_write(self, section_name, key,
-                                                      value)
-             if value is not None or not self._allow_no_value:
--                value = delimiter + str(value).replace('\n', '\n\t')
-+                # Convert all possible line-endings into '\n\t'
-+                value = (delimiter + str(value).replace('\r\n', '\n')
-+                         .replace('\r', '\n').replace('\n', '\n\t'))
-             else:
-                 value = ""
-             fp.write("{}{}\n".format(key, value))
-diff --git a/Lib/test/test_configparser.py b/Lib/test/test_configparser.py
-index 8d8dd2a2bf2..4783943f71a 100644
---- a/Lib/test/test_configparser.py
-+++ b/Lib/test/test_configparser.py
-@@ -526,6 +526,17 @@ def test_default_case_sensitivity(self):
-             cf.get(self.default_section, "Foo"), "Bar",
-             "could not locate option, expecting case-insensitive defaults")
- 
-+    def test_crlf_normalization(self):
-+        cf = self.newconfig({"key1": "a\nb","key2": "a\rb", "key3": "a\r\nb", "key4": "a\r\nb"})
-+        buf = io.StringIO()
-+        cf.write(buf)
-+        cf_str = buf.getvalue()
-+        self.assertNotIn("\r", cf_str)
-+        self.assertNotIn("\r\n", cf_str)
-+        self.assertEqual(cf_str.count("\n"), 10)
-+        self.assertEqual(cf_str.count("\n\t"), 4)
-+        self.assertTrue(cf_str.endswith("\n\n"))
-+
-     def test_parse_errors(self):
-         cf = self.newconfig()
-         self.parse_error(cf, configparser.ParsingError,
-diff --git a/Misc/NEWS.d/next/Security/2026-01-16-11-58-19.gh-issue-143927.aviFeG.rst b/Misc/NEWS.d/next/Security/2026-01-16-11-58-19.gh-issue-143927.aviFeG.rst
-new file mode 100644
-index 00000000000..ca554997e5c
---- /dev/null
-+++ b/Misc/NEWS.d/next/Security/2026-01-16-11-58-19.gh-issue-143927.aviFeG.rst
-@@ -0,0 +1,2 @@
-+Normalize all line endings (CR, CRLF, and LF) to LF+TAB when writing
-+multi-line configparser values.
--- 
-2.47.3
-
diff --git a/package/python3/0013-3.14-gh-151981-Make-tarfile._Stream.seek-break-at-EO.patch b/package/python3/0013-3.14-gh-151981-Make-tarfile._Stream.seek-break-at-EO.patch
deleted file mode 100644
index 7db9439639..0000000000
--- a/package/python3/0013-3.14-gh-151981-Make-tarfile._Stream.seek-break-at-EO.patch
+++ /dev/null
@@ -1,76 +0,0 @@
-From e86666c9dd256d52d0fbef6feb1ea4a51768fdec Mon Sep 17 00:00:00 2001
-From: "Miss Islington (bot)"
- <[email protected]>
-Date: Tue, 23 Jun 2026 15:46:18 +0200
-Subject: [PATCH] [3.14] gh-151981: Make tarfile._Stream.seek break at EOF
- (GH-151982) (#151992)
-
-(cherry picked from commit f50bf13566189c8d0ce5a814f33eff3d89951896)
-
-Co-authored-by: Petr Viktorin <[email protected]>
-Co-authored-by: Stan Ulbrych <[email protected]>
-
-Upstream: https://github.com/python/cpython/commit/e86666c9dd256d52d0fbef6feb1ea4a51768fdec
-CVE: CVE-2026-11972
-
-Signed-off-by: Bernd Kuhls <[email protected]>
----
- Lib/tarfile.py                                   |  4 +++-
- Lib/test/test_tarfile.py                         | 16 ++++++++++++++++
- ...026-06-23-13-28-16.gh-issue-151981.xBHEcU.rst |  2 ++
- 3 files changed, 21 insertions(+), 1 deletion(-)
- create mode 100644 Misc/NEWS.d/next/Security/2026-06-23-13-28-16.gh-issue-151981.xBHEcU.rst
-
-diff --git a/Lib/tarfile.py b/Lib/tarfile.py
-index e6734db24f6..39b1cd6514c 100644
---- a/Lib/tarfile.py
-+++ b/Lib/tarfile.py
-@@ -524,7 +524,9 @@ def seek(self, pos=0):
-         if pos - self.pos >= 0:
-             blocks, remainder = divmod(pos - self.pos, self.bufsize)
-             for i in range(blocks):
--                self.read(self.bufsize)
-+                data = self.read(self.bufsize)
-+                if not data:
-+                    break
-             self.read(remainder)
-         else:
-             raise StreamError("seeking backwards is not allowed")
-diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py
-index d974c7d46ec..8503024a690 100644
---- a/Lib/test/test_tarfile.py
-+++ b/Lib/test/test_tarfile.py
-@@ -4762,6 +4762,22 @@ def valueerror_filter(tarinfo, path):
-         with self.check_context(arc.open(errorlevel='boo!'), filtererror_filter):
-             self.expect_exception(TypeError)  # errorlevel is not int
- 
-+    @support.subTests('format', [tarfile.GNU_FORMAT, tarfile.PAX_FORMAT])
-+    def test_getmembers_big_size(self, format):
-+        # gh-151981: A loop in seek() for streaming files tried to read the
-+        # declared number of blocks even at EOF
-+        tinfo = tarfile.TarInfo("huge-file")
-+        tinfo.size = 1 << 64
-+        bio = io.BytesIO()
-+        # Write header without data
-+        bio.write(tinfo.tobuf(format))
-+
-+        # Reset & try to get contents
-+        bio.seek(0)
-+        with tarfile.open(fileobj=bio, mode="r|") as tar:
-+            with self.assertRaises(tarfile.ReadError):
-+                tar.getmembers()
-+
- 
- class OverwriteTests(archiver_tests.OverwriteTests, unittest.TestCase):
-     testdir = os.path.join(TEMPDIR, "testoverwrite")
-diff --git a/Misc/NEWS.d/next/Security/2026-06-23-13-28-16.gh-issue-151981.xBHEcU.rst b/Misc/NEWS.d/next/Security/2026-06-23-13-28-16.gh-issue-151981.xBHEcU.rst
-new file mode 100644
-index 00000000000..2123ab8e081
---- /dev/null
-+++ b/Misc/NEWS.d/next/Security/2026-06-23-13-28-16.gh-issue-151981.xBHEcU.rst
-@@ -0,0 +1,2 @@
-+In :mod:`tarfile`, seeking a stream now stops when end of the stream is
-+reached.
--- 
-2.47.3
-
diff --git a/package/python3/0014-3.14-gh-151987-Pass-filter_function-to-TarFile._extr.patch b/package/python3/0014-3.14-gh-151987-Pass-filter_function-to-TarFile._extr.patch
deleted file mode 100644
index 3b38594c75..0000000000
--- a/package/python3/0014-3.14-gh-151987-Pass-filter_function-to-TarFile._extr.patch
+++ /dev/null
@@ -1,151 +0,0 @@
-From 5e0ef3f1afe892e4f64eb83368db57ac4c40cba0 Mon Sep 17 00:00:00 2001
-From: "Miss Islington (bot)"
- <[email protected]>
-Date: Mon, 29 Jun 2026 21:11:22 +0200
-Subject: [PATCH] [3.14] gh-151987: Pass filter_function to
- `TarFile._extract_one()` during `.extract()` (GH-151988) (#152609)
-
-(cherry picked from commit 7ccdbaba2c54250a70d7f25632152df7655a5e0a)
-
-Co-authored-by: Petr Viktorin <[email protected]>
-Co-authored-by: Seth Michael Larson <[email protected]>
-
-Upstream: https://github.com/python/cpython/commit/5e0ef3f1afe892e4f64eb83368db57ac4c40cba0
-CVE: CVE-2026-4360
-
-Signed-off-by: Bernd Kuhls <[email protected]>
----
- Lib/tarfile.py                                |  3 +-
- Lib/test/test_tarfile.py                      | 92 +++++++++++++++++++
- ...-06-23-14-19-30.gh-issue-151987.8mNIMf.rst |  2 +
- 3 files changed, 96 insertions(+), 1 deletion(-)
- create mode 100644 Misc/NEWS.d/next/Security/2026-06-23-14-19-30.gh-issue-151987.8mNIMf.rst
-
-diff --git a/Lib/tarfile.py b/Lib/tarfile.py
-index cb09e307c46..d3c48999700 100644
---- a/Lib/tarfile.py
-+++ b/Lib/tarfile.py
-@@ -2538,7 +2538,8 @@ def extract(self, member, path="", set_attrs=True, *, numeric_owner=False,
-         tarinfo, unfiltered = self._get_extract_tarinfo(
-             member, filter_function, path)
-         if tarinfo is not None:
--            self._extract_one(tarinfo, path, set_attrs, numeric_owner)
-+            self._extract_one(tarinfo, path, set_attrs, numeric_owner,
-+                              filter_function=filter_function)
- 
-     def _get_extract_tarinfo(self, member, filter_function, path):
-         """Get (filtered, unfiltered) TarInfos from *member*
-diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py
-index 804c3e6d809..f3b61d9fbad 100644
---- a/Lib/test/test_tarfile.py
-+++ b/Lib/test/test_tarfile.py
-@@ -4470,6 +4470,98 @@ def test_chmod_outside_dir(self):
-                     st_mode = cc.outerdir.stat().st_mode
-                     self.assertNotEqual(st_mode & 0o777, 0o777)
- 
-+    @symlink_test
-+    @unittest.skipUnless(hasattr(os, 'chown'), "missing os.chown")
-+    @unittest.skipUnless(hasattr(os, 'lchown'), "missing os.lchown")
-+    @unittest.skipUnless(hasattr(os, 'geteuid'), "missing os.geteuid")
-+    @support.subTests('link_type', (tarfile.SYMTYPE, tarfile.LNKTYPE))
-+    def test_chown_links_on_extract(self, link_type):
-+        with ArchiveMaker() as arc:
-+            arc.add("test.txt",
-+                    uid=1337, gid=1337, uname="", gname="", mode='-rwxr-xr-x')
-+            arc.add("link",
-+                    type=link_type,
-+                    linkname='test.txt',
-+                    uid=1337, gid=1337, uname="", gname="", mode='-rwxr-xr-x')
-+
-+        with (
-+            os_helper.temp_dir() as tmpdir,
-+            arc.open() as tar,
-+            unittest.mock.patch("os.chown") as mock_chown,
-+            unittest.mock.patch("os.lchown") as mock_lchown,
-+            unittest.mock.patch("os.geteuid") as mock_geteuid,
-+        ):
-+            # Set UID to 0 so chown() is attempted.
-+            mock_geteuid.return_value = 0
-+            tar.extract("link", path=tmpdir, filter='data')
-+            extract_path = os.path.join(tmpdir, "link")
-+
-+            if link_type == tarfile.SYMTYPE:
-+                mock_chown.assert_not_called()
-+                mock_lchown.assert_called_once_with(extract_path, -1, -1)
-+            else:
-+                mock_chown.assert_has_calls([
-+                    unittest.mock.call(extract_path, -1, -1),
-+                    unittest.mock.call(extract_path, -1, -1)
-+                ])
-+                mock_lchown.assert_not_called()
-+
-+    @symlink_test
-+    @unittest.skipUnless(hasattr(os, 'chown'), "missing os.chown")
-+    @unittest.skipUnless(hasattr(os, 'lchown'), "missing os.lchown")
-+    @unittest.skipUnless(hasattr(os, 'geteuid'), "missing os.geteuid")
-+    @support.subTests('link_type', (tarfile.SYMTYPE, tarfile.LNKTYPE))
-+    def test_chown_links_on_extractall(self, link_type):
-+        with ArchiveMaker() as arc:
-+            arc.add("test.txt",
-+                    uid=1337, gid=1337, uname="", gname="", mode='-rwxr-xr-x')
-+            arc.add("link",
-+                    type=link_type,
-+                    linkname='test.txt',
-+                    uid=1337, gid=1337, uname="", gname="", mode='-rwxr-xr-x')
-+
-+        with (
-+            os_helper.temp_dir() as tmpdir,
-+            arc.open() as tar,
-+            unittest.mock.patch("os.chown") as mock_chown,
-+            unittest.mock.patch("os.lchown") as mock_lchown,
-+            unittest.mock.patch("os.geteuid") as mock_geteuid,
-+        ):
-+            # Set UID to 0 so chown() is attempted.
-+            mock_geteuid.return_value = 0
-+            tar.extractall(path=tmpdir, filter='data')
-+            extract_link_path = os.path.join(tmpdir, "link")
-+            extract_file_path = os.path.join(tmpdir, "test.txt")
-+
-+            if link_type == tarfile.SYMTYPE:
-+                mock_chown.assert_called_once_with(extract_file_path, -1, -1)
-+                mock_lchown.assert_called_once_with(extract_link_path, -1, -1)
-+            else:
-+                mock_chown.assert_has_calls([
-+                    unittest.mock.call(extract_file_path, -1, -1),
-+                    unittest.mock.call(extract_link_path, -1, -1)
-+                ])
-+                mock_lchown.assert_not_called()
-+
-+    def test_extract_filters_target(self):
-+        # Test that when extract() falls back to extracting (rather than
-+        # linking) a hardlink target, it filters the target.
-+        with ArchiveMaker() as arc:
-+            arc.add("target")
-+            arc.add("link", hardlink_to="target")
-+        def testing_filter(member, path):
-+            if member.name == 'target':
-+                # target: set read-only
-+                return member.replace(mode=stat.S_IRUSR)
-+            # link: don't overwrite the mode
-+            return member.replace(mode=None)
-+        tempdir = pathlib.Path(TEMPDIR) / 'extract'
-+        with os_helper.temp_dir(tempdir), arc.open() as tar:
-+            tar.extract("link", path=tempdir, filter=testing_filter)
-+            path = tempdir / 'link'
-+            if os_helper.can_chmod():
-+                self.assertFalse(path.stat().st_mode & stat.S_IWUSR)
-+
-     def test_link_fallback_normalizes(self):
-         # Make sure hardlink fallbacks work for non-normalized paths for all
-         # filters
-diff --git a/Misc/NEWS.d/next/Security/2026-06-23-14-19-30.gh-issue-151987.8mNIMf.rst b/Misc/NEWS.d/next/Security/2026-06-23-14-19-30.gh-issue-151987.8mNIMf.rst
-new file mode 100644
-index 00000000000..9eea7b32c4d
---- /dev/null
-+++ b/Misc/NEWS.d/next/Security/2026-06-23-14-19-30.gh-issue-151987.8mNIMf.rst
-@@ -0,0 +1,2 @@
-+The :meth:`tarfile.TarFile.extract` method now applies the given filter when
-+it extracts a link target from the archive as a fallback.
--- 
-2.47.3
-
diff --git a/package/python3/0015-3.14-gh-153030-Fix-quadratic-complexity-in-increment.patch b/package/python3/0015-3.14-gh-153030-Fix-quadratic-complexity-in-increment.patch
deleted file mode 100644
index e9c3f40cc0..0000000000
--- a/package/python3/0015-3.14-gh-153030-Fix-quadratic-complexity-in-increment.patch
+++ /dev/null
@@ -1,123 +0,0 @@
-From 07efb08123ba9367a7107325adb9d5626dca1ca9 Mon Sep 17 00:00:00 2001
-From: "Miss Islington (bot)"
- <[email protected]>
-Date: Sat, 4 Jul 2026 20:08:05 +0200
-Subject: [PATCH] [3.14] gh-153030: Fix quadratic complexity in incremental
- parsing in HTMLParser (GH-153031) (GH-153039)
-
-When an unterminated construct (e.g. a tag or comment) spanned many
-feed() calls, rescanning the growing buffer and concatenating new data
-onto it were both quadratic.  New data is now accumulated in a list and
-only joined and parsed once enough has piled up.
-(cherry picked from commit bcf98ddbc40ec9b3ee87da0124a5660b19b7e606)
-
-Co-authored-by: Serhiy Storchaka <[email protected]>
-Co-authored-by: Claude Opus 4.8 <[email protected]>
-
-Upstream: https://github.com/python/cpython/commit/07efb08123ba9367a7107325adb9d5626dca1ca9
-CVE: CVE-2026-15308
-
-Signed-off-by: Bernd Kuhls <[email protected]>
----
- Lib/html/parser.py                            | 32 +++++++++++++++++--
- Lib/test/test_htmlparser.py                   | 20 ++++++++++++
- ...-07-04-17-00-00.gh-issue-153030.RovkP6.rst |  3 ++
- 3 files changed, 53 insertions(+), 2 deletions(-)
- create mode 100644 Misc/NEWS.d/next/Security/2026-07-04-17-00-00.gh-issue-153030.RovkP6.rst
-
-diff --git a/Lib/html/parser.py b/Lib/html/parser.py
-index 38ddf9ef442..fbe0d3665e0 100644
---- a/Lib/html/parser.py
-+++ b/Lib/html/parser.py
-@@ -157,6 +157,9 @@ def reset(self):
-         self.cdata_elem = None
-         self._support_cdata = True
-         self._escapable = True
-+        self._pending = []
-+        self._pending_len = 0
-+        self._parse_threshold = 1
-         super().reset()
- 
-     def feed(self, data):
-@@ -165,11 +168,36 @@ def feed(self, data):
-         Call this as often as you want, with as little or as much text
-         as you want (may include '\n').
-         """
--        self.rawdata = self.rawdata + data
--        self.goahead(0)
-+        # Accumulate new data in a list and only join and parse it once
-+        # enough has piled up.  Rescanning an unparsed buffer (e.g. an
-+        # unterminated tag) and concatenating onto it on every call would
-+        # both be quadratic in the input size.
-+        self._pending_len += len(data)
-+        if self._pending_len < self._parse_threshold:
-+            self._pending.append(data)
-+        else:
-+            if not self._pending:
-+                self.rawdata += data
-+            else:
-+                self._pending.append(data)
-+                self.rawdata += ''.join(self._pending)
-+                self._pending.clear()
-+            self._pending_len = 0
-+            n = len(self.rawdata)
-+            self.goahead(0)
-+            if len(self.rawdata) < n:
-+                # Some data was parsed; resume on the next call.
-+                self._parse_threshold = 1
-+            else:
-+                # Nothing was parsed; wait until the buffer doubles.
-+                self._parse_threshold = len(self.rawdata)
- 
-     def close(self):
-         """Handle any buffered data."""
-+        if self._pending:
-+            self.rawdata += ''.join(self._pending)
-+            self._pending.clear()
-+            self._pending_len = 0
-         self.goahead(1)
- 
-     __starttag_text = None
-diff --git a/Lib/test/test_htmlparser.py b/Lib/test/test_htmlparser.py
-index 6b7624f1150..3fdaed4ff46 100644
---- a/Lib/test/test_htmlparser.py
-+++ b/Lib/test/test_htmlparser.py
-@@ -1041,6 +1041,26 @@ def check(source):
-         check("<![CDATA[" * 9 * n)
-         check("<!doctype" * 35 * n)
- 
-+    @support.requires_resource('cpu')
-+    def test_incremental_no_quadratic_complexity(self):
-+        # An unterminated construct fed in many small chunks used to take
-+        # quadratic time, both to rescan and to concatenate the buffer.
-+        # Now it takes a fraction of a second.
-+        def check(prefix, chunk, suffix):
-+            parser = html.parser.HTMLParser()
-+            parser.feed(prefix)
-+            for _ in range(200_000):
-+                parser.feed(chunk)
-+            parser.feed(suffix)
-+            parser.close()
-+        chunk = "a" * 64
-+        check("<!--", chunk, "-->")       # comment
-+        check("<?", chunk, ">")           # processing instruction
-+        check("<!doctype ", chunk, ">")   # doctype
-+        check("<![CDATA[", chunk, "]]>")  # CDATA section
-+        check("<a href='", chunk, "'>")   # start tag
-+        check("<script>", chunk, "</script>")  # RAWTEXT element
-+
- 
- class AttributesTestCase(TestCaseBase):
- 
-diff --git a/Misc/NEWS.d/next/Security/2026-07-04-17-00-00.gh-issue-153030.RovkP6.rst b/Misc/NEWS.d/next/Security/2026-07-04-17-00-00.gh-issue-153030.RovkP6.rst
-new file mode 100644
-index 00000000000..d1d60593f4b
---- /dev/null
-+++ b/Misc/NEWS.d/next/Security/2026-07-04-17-00-00.gh-issue-153030.RovkP6.rst
-@@ -0,0 +1,3 @@
-+Fixed quadratic complexity in incremental parsing of long unterminated
-+constructs (such as tags or comments) in :class:`html.parser.HTMLParser`,
-+which could be exploited for a denial of service.
--- 
-2.47.3
-
diff --git a/package/python3/python3.hash b/package/python3/python3.hash
index 0f2436fb23..97302bc750 100644
--- a/package/python3/python3.hash
+++ b/package/python3/python3.hash
@@ -1,4 +1,4 @@
-# From https://www.python.org/downloads/release/python-3146/
-sha256  143b1dddefaec3bd2e21e3b839b34a2b7fb9842272883c576420d605e9f30c63  Python-3.14.6.tar.xz
+# From https://www.python.org/downloads/release/python-3147/
+sha256  3b48dac8fb59f62eaa67ac83c1eb12bda1b7a08406dd286e252c11a66be27f81  Python-3.14.7.tar.xz
 # Locally computed
 sha256  b0e25a78cffb43f4d92de8b61ccfa1f1f98ecbc22330b54b5251e7b6ba010231  LICENSE
diff --git a/package/python3/python3.mk b/package/python3/python3.mk
index 9a47a1f306..cb5e1a4b85 100644
--- a/package/python3/python3.mk
+++ b/package/python3/python3.mk
@@ -5,7 +5,7 @@
 ################################################################################
 
 PYTHON3_VERSION_MAJOR = 3.14
-PYTHON3_VERSION = $(PYTHON3_VERSION_MAJOR).6
+PYTHON3_VERSION = $(PYTHON3_VERSION_MAJOR).7
 PYTHON3_SOURCE = Python-$(PYTHON3_VERSION).tar.xz
 PYTHON3_SITE = https://python.org/ftp/python/$(PYTHON3_VERSION)
 PYTHON3_LICENSE = Python-2.0, others
@@ -13,21 +13,6 @@ PYTHON3_LICENSE_FILES = LICENSE
 PYTHON3_CPE_ID_VENDOR = python
 PYTHON3_CPE_ID_PRODUCT = python
 
-# 0011-3.14-gh-151558-Fix-symlink-escape-via-tarfile-hardli.patch
-PYTHON3_IGNORE_CVES += CVE-2026-11940
-
-# 0012-3.14-gh-143927-Normalize-all-line-endings-CR-CRLF-an.patch
-PYTHON3_IGNORE_CVES += CVE-2026-0864
-
-# 0013-3.14-gh-151981-Make-tarfile._Stream.seek-break-at-EO.patch
-PYTHON3_IGNORE_CVES += CVE-2026-11972
-
-# 0014-3.14-gh-151987-Pass-filter_function-to-TarFile._extr.patch
-PYTHON3_IGNORE_CVES += CVE-2026-4360
-
-# 0015-3.14-gh-153030-Fix-quadratic-complexity-in-increment.patch
-PYTHON3_IGNORE_CVES += CVE-2026-15308
-
 # This host Python is installed in $(HOST_DIR), as it is needed when
 # cross-compiling third-party Python modules.
 
-- 
2.47.3

_______________________________________________
buildroot mailing list
[email protected]
https://lists.buildroot.org/mailman/listinfo/buildroot
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.