Compare commits

2 Commits

Author SHA256 Message Date
3c05b2426b Add CVE-2025-6075-expandvars-perf-degrad.patch avoid simple
quadratic complexity vulnerabilities of os.path.expandvars()
  (CVE-2025-6075, bsc#1252974).
Reapply patches:
  - bsc1243155-sphinx-non-determinism.patch
  - doc-py38-to-py36.patch
  - fix_configure_rst.patch
2025-11-16 00:10:53 +01:00
a6fa7f608e Mark the upgrade to 3.12.12 as fixing CVE-2025-8291, bsc#1251305. 2025-11-12 00:53:10 +01:00
6 changed files with 451 additions and 54 deletions

View File

@@ -0,0 +1,382 @@
From 122a417f8000eb904a3cac9aacf4de8d288d7148 Mon Sep 17 00:00:00 2001
From: Serhiy Storchaka <storchaka@gmail.com>
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 <storchaka@gmail.com>
Co-authored-by: Łukasz Langa <lukasz@langa.pl>
---
Lib/ntpath.py | 126 ++++++------------
Lib/posixpath.py | 43 +++---
Lib/test/test_genericpath.py | 14 ++
Lib/test/test_ntpath.py | 22 ++-
...-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?= <lukasz@langa.pl>
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

View File

@@ -14,10 +14,10 @@ https://github.com/python/cpython/issues/130979
Doc/tools/extensions/audit_events.py | 11 ++++++++--- Doc/tools/extensions/audit_events.py | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-) 1 file changed, 8 insertions(+), 3 deletions(-)
Index: Python-3.12.11/Doc/tools/extensions/audit_events.py Index: Python-3.12.12/Doc/tools/extensions/audit_events.py
=================================================================== ===================================================================
--- Python-3.12.11.orig/Doc/tools/extensions/audit_events.py 2025-07-02 16:10:55.447792590 +0200 --- Python-3.12.12.orig/Doc/tools/extensions/audit_events.py 2025-11-15 16:09:06.279580426 +0100
+++ Python-3.12.11/Doc/tools/extensions/audit_events.py 2025-07-02 16:12:00.124596479 +0200 +++ Python-3.12.12/Doc/tools/extensions/audit_events.py 2025-11-15 18:14:28.878403685 +0100
@@ -64,8 +64,13 @@ @@ -64,8 +64,13 @@
logger.warning(msg) logger.warning(msg)
return return

View File

@@ -14,16 +14,16 @@
Doc/tools/extensions/pydoc_topics.py | 22 +++++----- Doc/tools/extensions/pydoc_topics.py | 22 +++++-----
13 files changed, 126 insertions(+), 118 deletions(-) 13 files changed, 126 insertions(+), 118 deletions(-)
Index: Python-3.12.10/Doc/Makefile Index: Python-3.12.12/Doc/Makefile
=================================================================== ===================================================================
--- Python-3.12.10.orig/Doc/Makefile 2025-04-29 22:11:50.013198738 +0200 --- Python-3.12.12.orig/Doc/Makefile 2025-10-09 13:07:00.000000000 +0200
+++ Python-3.12.10/Doc/Makefile 2025-04-29 22:11:52.047098026 +0200 +++ Python-3.12.12/Doc/Makefile 2025-11-16 00:10:17.204996992 +0100
@@ -14,15 +14,15 @@ @@ -14,15 +14,15 @@
SOURCES = SOURCES =
DISTVERSION = $(shell $(PYTHON) tools/extensions/patchlevel.py) DISTVERSION = $(shell $(PYTHON) tools/extensions/patchlevel.py)
REQUIREMENTS = requirements.txt REQUIREMENTS = requirements.txt
-SPHINXERRORHANDLING = --fail-on-warning -SPHINXERRORHANDLING = --fail-on-warning
+SPHINXERRORHANDLING = -W +SPHINXERRORHANDLING =
# Internal variables. # Internal variables.
PAPEROPT_a4 = --define latex_elements.papersize=a4paper PAPEROPT_a4 = --define latex_elements.papersize=a4paper
@@ -38,10 +38,10 @@ Index: Python-3.12.10/Doc/Makefile
$(PAPEROPT_$(PAPER)) \ $(PAPEROPT_$(PAPER)) \
$(SPHINXOPTS) $(SPHINXERRORHANDLING) \ $(SPHINXOPTS) $(SPHINXERRORHANDLING) \
. build/$(BUILDER) $(SOURCES) . build/$(BUILDER) $(SOURCES)
Index: Python-3.12.10/Doc/conf.py Index: Python-3.12.12/Doc/conf.py
=================================================================== ===================================================================
--- Python-3.12.10.orig/Doc/conf.py 2025-04-29 22:11:46.161835452 +0200 --- Python-3.12.12.orig/Doc/conf.py 2025-11-16 00:09:22.481046078 +0100
+++ Python-3.12.10/Doc/conf.py 2025-04-29 22:11:52.047459667 +0200 +++ Python-3.12.12/Doc/conf.py 2025-11-16 00:09:33.435219937 +0100
@@ -11,6 +11,8 @@ @@ -11,6 +11,8 @@
from importlib import import_module from importlib import import_module
from importlib.util import find_spec from importlib.util import find_spec
@@ -86,10 +86,10 @@ Index: Python-3.12.10/Doc/conf.py
# Options for c_annotations extension # Options for c_annotations extension
# ----------------------------------- # -----------------------------------
Index: Python-3.12.10/Doc/tools/check-warnings.py Index: Python-3.12.12/Doc/tools/check-warnings.py
=================================================================== ===================================================================
--- Python-3.12.10.orig/Doc/tools/check-warnings.py 2025-04-08 13:35:47.000000000 +0200 --- Python-3.12.12.orig/Doc/tools/check-warnings.py 2025-10-09 13:07:00.000000000 +0200
+++ Python-3.12.10/Doc/tools/check-warnings.py 2025-04-29 22:11:52.047704324 +0200 +++ Python-3.12.12/Doc/tools/check-warnings.py 2025-11-16 00:09:33.435482474 +0100
@@ -228,7 +228,8 @@ @@ -228,7 +228,8 @@
print(filename) print(filename)
for warning in warnings: for warning in warnings:
@@ -109,10 +109,10 @@ Index: Python-3.12.10/Doc/tools/check-warnings.py
for warning in warnings for warning in warnings
if "Doc/" in warning if "Doc/" in warning
} }
Index: Python-3.12.10/Doc/tools/extensions/audit_events.py Index: Python-3.12.12/Doc/tools/extensions/audit_events.py
=================================================================== ===================================================================
--- Python-3.12.10.orig/Doc/tools/extensions/audit_events.py 2025-04-08 13:35:47.000000000 +0200 --- Python-3.12.12.orig/Doc/tools/extensions/audit_events.py 2025-10-09 13:07:00.000000000 +0200
+++ Python-3.12.10/Doc/tools/extensions/audit_events.py 2025-04-29 22:11:52.047967558 +0200 +++ Python-3.12.12/Doc/tools/extensions/audit_events.py 2025-11-16 00:09:38.867031380 +0100
@@ -1,9 +1,6 @@ @@ -1,9 +1,6 @@
"""Support for documenting audit events.""" """Support for documenting audit events."""
@@ -253,10 +253,10 @@ Index: Python-3.12.10/Doc/tools/extensions/audit_events.py
) -> nodes.row: ) -> nodes.row:
row = nodes.row() row = nodes.row()
name_node = nodes.paragraph("", nodes.Text(name)) name_node = nodes.paragraph("", nodes.Text(name))
Index: Python-3.12.10/Doc/tools/extensions/availability.py Index: Python-3.12.12/Doc/tools/extensions/availability.py
=================================================================== ===================================================================
--- Python-3.12.10.orig/Doc/tools/extensions/availability.py 2025-04-08 13:35:47.000000000 +0200 --- Python-3.12.12.orig/Doc/tools/extensions/availability.py 2025-10-09 13:07:00.000000000 +0200
+++ Python-3.12.10/Doc/tools/extensions/availability.py 2025-04-29 22:11:52.048206976 +0200 +++ Python-3.12.12/Doc/tools/extensions/availability.py 2025-11-16 00:09:33.436104069 +0100
@@ -1,8 +1,6 @@ @@ -1,8 +1,6 @@
"""Support for documenting platform availability""" """Support for documenting platform availability"""
@@ -310,10 +310,10 @@ Index: Python-3.12.10/Doc/tools/extensions/availability.py
app.add_directive("availability", Availability) app.add_directive("availability", Availability)
return { return {
Index: Python-3.12.10/Doc/tools/extensions/c_annotations.py Index: Python-3.12.12/Doc/tools/extensions/c_annotations.py
=================================================================== ===================================================================
--- Python-3.12.10.orig/Doc/tools/extensions/c_annotations.py 2025-04-29 22:11:52.033400629 +0200 --- Python-3.12.12.orig/Doc/tools/extensions/c_annotations.py 2025-11-16 00:09:33.421429756 +0100
+++ Python-3.12.10/Doc/tools/extensions/c_annotations.py 2025-04-29 22:11:52.048411194 +0200 +++ Python-3.12.12/Doc/tools/extensions/c_annotations.py 2025-11-16 00:09:33.436337970 +0100
@@ -9,22 +9,18 @@ @@ -9,22 +9,18 @@
* Set ``stable_abi_file`` to the path to stable ABI list. * Set ``stable_abi_file`` to the path to stable ABI list.
""" """
@@ -443,10 +443,10 @@ Index: Python-3.12.10/Doc/tools/extensions/c_annotations.py
return { return {
"version": "1.0", "version": "1.0",
"parallel_read_safe": True, "parallel_read_safe": True,
Index: Python-3.12.10/Doc/tools/extensions/changes.py Index: Python-3.12.12/Doc/tools/extensions/changes.py
=================================================================== ===================================================================
--- Python-3.12.10.orig/Doc/tools/extensions/changes.py 2025-04-08 13:35:47.000000000 +0200 --- Python-3.12.12.orig/Doc/tools/extensions/changes.py 2025-10-09 13:07:00.000000000 +0200
+++ Python-3.12.10/Doc/tools/extensions/changes.py 2025-04-29 22:11:52.048619113 +0200 +++ Python-3.12.12/Doc/tools/extensions/changes.py 2025-11-16 00:09:33.436590030 +0100
@@ -1,7 +1,5 @@ @@ -1,7 +1,5 @@
"""Support for documenting version of changes, additions, deprecations.""" """Support for documenting version of changes, additions, deprecations."""
@@ -482,10 +482,10 @@ Index: Python-3.12.10/Doc/tools/extensions/changes.py
# Override Sphinx's directives with support for 'next' # Override Sphinx's directives with support for 'next'
app.add_directive("versionadded", PyVersionChange, override=True) app.add_directive("versionadded", PyVersionChange, override=True)
app.add_directive("versionchanged", PyVersionChange, override=True) app.add_directive("versionchanged", PyVersionChange, override=True)
Index: Python-3.12.10/Doc/tools/extensions/glossary_search.py Index: Python-3.12.12/Doc/tools/extensions/glossary_search.py
=================================================================== ===================================================================
--- Python-3.12.10.orig/Doc/tools/extensions/glossary_search.py 2025-04-29 22:11:52.033722879 +0200 --- Python-3.12.12.orig/Doc/tools/extensions/glossary_search.py 2025-11-16 00:09:33.421856281 +0100
+++ Python-3.12.10/Doc/tools/extensions/glossary_search.py 2025-04-29 22:11:52.048797629 +0200 +++ Python-3.12.12/Doc/tools/extensions/glossary_search.py 2025-11-16 00:09:33.436945736 +0100
@@ -1,18 +1,14 @@ @@ -1,18 +1,14 @@
"""Feature search results for glossary items prominently.""" """Feature search results for glossary items prominently."""
@@ -516,10 +516,10 @@ Index: Python-3.12.10/Doc/tools/extensions/glossary_search.py
app.connect('doctree-resolved', process_glossary_nodes) app.connect('doctree-resolved', process_glossary_nodes)
app.connect('build-finished', write_glossary_json) app.connect('build-finished', write_glossary_json)
Index: Python-3.12.10/Doc/tools/extensions/implementation_detail.py Index: Python-3.12.12/Doc/tools/extensions/implementation_detail.py
=================================================================== ===================================================================
--- Python-3.12.10.orig/Doc/tools/extensions/implementation_detail.py 2025-04-08 13:35:47.000000000 +0200 --- Python-3.12.12.orig/Doc/tools/extensions/implementation_detail.py 2025-10-09 13:07:00.000000000 +0200
+++ Python-3.12.10/Doc/tools/extensions/implementation_detail.py 2025-04-29 22:48:23.397548211 +0200 +++ Python-3.12.12/Doc/tools/extensions/implementation_detail.py 2025-11-16 00:09:33.437321346 +0100
@@ -1,17 +1,10 @@ @@ -1,17 +1,10 @@
"""Support for marking up implementation details.""" """Support for marking up implementation details."""
@@ -570,10 +570,10 @@ Index: Python-3.12.10/Doc/tools/extensions/implementation_detail.py
app.add_directive("impl-detail", ImplementationDetail) app.add_directive("impl-detail", ImplementationDetail)
return { return {
Index: Python-3.12.10/Doc/tools/extensions/issue_role.py Index: Python-3.12.12/Doc/tools/extensions/issue_role.py
=================================================================== ===================================================================
--- Python-3.12.10.orig/Doc/tools/extensions/issue_role.py 2025-04-08 13:35:47.000000000 +0200 --- Python-3.12.12.orig/Doc/tools/extensions/issue_role.py 2025-10-09 13:07:00.000000000 +0200
+++ Python-3.12.10/Doc/tools/extensions/issue_role.py 2025-04-29 22:21:55.278961032 +0200 +++ Python-3.12.12/Doc/tools/extensions/issue_role.py 2025-11-16 00:09:33.437543863 +0100
@@ -1,22 +1,18 @@ @@ -1,22 +1,18 @@
"""Support for referencing issues in the tracker.""" """Support for referencing issues in the tracker."""
@@ -619,10 +619,10 @@ Index: Python-3.12.10/Doc/tools/extensions/issue_role.py
app.add_role("issue", BPOIssue()) app.add_role("issue", BPOIssue())
app.add_role("gh", GitHubIssue()) app.add_role("gh", GitHubIssue())
Index: Python-3.12.10/Doc/tools/extensions/misc_news.py Index: Python-3.12.12/Doc/tools/extensions/misc_news.py
=================================================================== ===================================================================
--- Python-3.12.10.orig/Doc/tools/extensions/misc_news.py 2025-04-08 13:35:47.000000000 +0200 --- Python-3.12.12.orig/Doc/tools/extensions/misc_news.py 2025-10-09 13:07:00.000000000 +0200
+++ Python-3.12.10/Doc/tools/extensions/misc_news.py 2025-04-29 22:11:52.049046825 +0200 +++ Python-3.12.12/Doc/tools/extensions/misc_news.py 2025-11-16 00:09:33.437781606 +0100
@@ -1,7 +1,5 @@ @@ -1,7 +1,5 @@
"""Support for including Misc/NEWS.""" """Support for including Misc/NEWS."""
@@ -675,10 +675,10 @@ Index: Python-3.12.10/Doc/tools/extensions/misc_news.py
app.add_directive("miscnews", MiscNews) app.add_directive("miscnews", MiscNews)
return { return {
Index: Python-3.12.10/Doc/tools/extensions/patchlevel.py Index: Python-3.12.12/Doc/tools/extensions/patchlevel.py
=================================================================== ===================================================================
--- Python-3.12.10.orig/Doc/tools/extensions/patchlevel.py 2025-04-08 13:35:47.000000000 +0200 --- Python-3.12.12.orig/Doc/tools/extensions/patchlevel.py 2025-10-09 13:07:00.000000000 +0200
+++ Python-3.12.10/Doc/tools/extensions/patchlevel.py 2025-04-29 22:11:52.049253068 +0200 +++ Python-3.12.12/Doc/tools/extensions/patchlevel.py 2025-11-16 00:09:33.437983170 +0100
@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
import re import re
import sys import sys
@@ -716,10 +716,10 @@ Index: Python-3.12.10/Doc/tools/extensions/patchlevel.py
version = f"{info.major}.{info.minor}" version = f"{info.major}.{info.minor}"
release = f"{info.major}.{info.minor}.{info.micro}" release = f"{info.major}.{info.minor}.{info.micro}"
if info.releaselevel != "final": if info.releaselevel != "final":
Index: Python-3.12.10/Doc/tools/extensions/pydoc_topics.py Index: Python-3.12.12/Doc/tools/extensions/pydoc_topics.py
=================================================================== ===================================================================
--- Python-3.12.10.orig/Doc/tools/extensions/pydoc_topics.py 2025-04-08 13:35:47.000000000 +0200 --- Python-3.12.12.orig/Doc/tools/extensions/pydoc_topics.py 2025-10-09 13:07:00.000000000 +0200
+++ Python-3.12.10/Doc/tools/extensions/pydoc_topics.py 2025-04-29 22:33:59.916893510 +0200 +++ Python-3.12.12/Doc/tools/extensions/pydoc_topics.py 2025-11-16 00:09:33.438175026 +0100
@@ -1,21 +1,23 @@ @@ -1,21 +1,23 @@
"""Support for building "topic help" for pydoc.""" """Support for building "topic help" for pydoc."""

View File

@@ -3,9 +3,11 @@
Misc/NEWS | 2 +- Misc/NEWS | 2 +-
2 files changed, 1 insertion(+), 3 deletions(-) 2 files changed, 1 insertion(+), 3 deletions(-)
--- a/Doc/using/configure.rst Index: Python-3.12.12/Doc/using/configure.rst
+++ b/Doc/using/configure.rst ===================================================================
@@ -640,13 +640,11 @@ macOS Options --- 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
@@ -640,13 +640,11 @@
See ``Mac/README.rst``. See ``Mac/README.rst``.
@@ -19,9 +21,11 @@
.. option:: --enable-framework=INSTALLDIR .. option:: --enable-framework=INSTALLDIR
Create a Python.framework rather than a traditional Unix install. Optional Create a Python.framework rather than a traditional Unix install. Optional
--- a/Misc/NEWS Index: Python-3.12.12/Misc/NEWS
+++ b/Misc/NEWS ===================================================================
@@ -15146,7 +15146,7 @@ C API --- 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 @@
- bpo-40939: Removed documentation for the removed ``PyParser_*`` C API. - bpo-40939: Removed documentation for the removed ``PyParser_*`` C API.
- bpo-43795: The list in :ref:`limited-api-list` now shows the public name - bpo-43795: The list in :ref:`limited-api-list` now shows the public name

View File

@@ -1,3 +1,14 @@
-------------------------------------------------------------------
Thu Nov 13 17:13:03 UTC 2025 - Matej Cepl <mcepl@cepl.eu>
- Add CVE-2025-6075-expandvars-perf-degrad.patch avoid simple
quadratic complexity vulnerabilities of os.path.expandvars()
(CVE-2025-6075, bsc#1252974).
- Reapply patches:
- bsc1243155-sphinx-non-determinism.patch
- doc-py38-to-py36.patch
- fix_configure_rst.patch
------------------------------------------------------------------- -------------------------------------------------------------------
Wed Oct 15 09:10:21 UTC 2025 - Daniel Garcia <daniel.garcia@suse.com> Wed Oct 15 09:10:21 UTC 2025 - Daniel Garcia <daniel.garcia@suse.com>
@@ -10,7 +21,8 @@ Wed Oct 15 09:10:21 UTC 2025 - Daniel Garcia <daniel.garcia@suse.com>
- Security - Security
- gh-139700: Check consistency of the zip64 end of central - gh-139700: Check consistency of the zip64 end of central
directory record. Support records with “zip64 extensible data” directory record. Support records with “zip64 extensible data”
if there are no bytes prepended to the ZIP file. if there are no bytes prepended to the ZIP file
(CVE-2025-8291, bsc#1251305).
- gh-139400: xml.parsers.expat: Make sure that parent Expat - gh-139400: xml.parsers.expat: Make sure that parent Expat
parsers are only garbage-collected once they are no longer parsers are only garbage-collected once they are no longer
referenced by subparsers created by referenced by subparsers created by

View File

@@ -189,6 +189,9 @@ Patch44: doc-py38-to-py36.patch
Patch45: bsc1243155-sphinx-non-determinism.patch Patch45: bsc1243155-sphinx-non-determinism.patch
# PATCH-FIX-OPENSUSE gh139257-Support-docutils-0.22.patch gh#python/cpython#139257 daniel.garcia@suse.com # PATCH-FIX-OPENSUSE gh139257-Support-docutils-0.22.patch gh#python/cpython#139257 daniel.garcia@suse.com
Patch46: gh139257-Support-docutils-0.22.patch 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
BuildRequires: autoconf-archive BuildRequires: autoconf-archive
BuildRequires: automake BuildRequires: automake
BuildRequires: fdupes BuildRequires: fdupes
@@ -479,10 +482,6 @@ rm Lib/site-packages/README.txt
# Add vendored bluez-devel files # Add vendored bluez-devel files
tar xvf %{SOURCE21} tar xvf %{SOURCE21}
# Don't fail on warnings when building documentation
sed -i -e '/^SPHINXERRORHANDLING/s/--fail-on-warning//' Doc/Makefile
sed -i -e '/^SPHINXERRORHANDLING/s/-W//' Doc/Makefile
%build %build
%if %{with doc} %if %{with doc}
TODAY_DATE=`date -r %{SOURCE0} "+%%B %%d, %%Y"` TODAY_DATE=`date -r %{SOURCE0} "+%%B %%d, %%Y"`