SHA256
1
0
forked from pool/python39

Compare commits

...

No commits in common. "devel" and "devel" have entirely different histories.
devel ... devel

9 changed files with 604 additions and 52 deletions

@ -10,9 +10,11 @@ Subject: [PATCH 1/2] fix(doc-tools): use sphinx.locale._ as gettext() for
Misc/NEWS.d/next/Documentation/2022-10-19-07-15-52.gh-issue-98366.UskMXF.rst | 1 + Misc/NEWS.d/next/Documentation/2022-10-19-07-15-52.gh-issue-98366.UskMXF.rst | 1 +
2 files changed, 5 insertions(+), 4 deletions(-) 2 files changed, 5 insertions(+), 4 deletions(-)
--- a/Doc/tools/extensions/pyspecific.py Index: Python-3.9.22/Doc/tools/extensions/pyspecific.py
+++ b/Doc/tools/extensions/pyspecific.py ===================================================================
@@ -26,7 +26,7 @@ try: --- Python-3.9.22.orig/Doc/tools/extensions/pyspecific.py 2025-04-11 09:49:58.417019238 +0200
+++ Python-3.9.22/Doc/tools/extensions/pyspecific.py 2025-04-11 09:50:56.818993764 +0200
@@ -27,7 +27,7 @@
from sphinx.errors import NoUri from sphinx.errors import NoUri
except ImportError: except ImportError:
from sphinx.environment import NoUri from sphinx.environment import NoUri
@ -21,7 +23,7 @@ Subject: [PATCH 1/2] fix(doc-tools): use sphinx.locale._ as gettext() for
from sphinx.util import status_iterator, logging from sphinx.util import status_iterator, logging
from sphinx.util.nodes import split_explicit_title from sphinx.util.nodes import split_explicit_title
from sphinx.writers.text import TextWriter, TextTranslator from sphinx.writers.text import TextWriter, TextTranslator
@@ -110,7 +110,7 @@ class ImplementationDetail(Directive): @@ -111,7 +111,7 @@
def run(self): def run(self):
pnode = nodes.compound(classes=['impl-detail']) pnode = nodes.compound(classes=['impl-detail'])
@ -30,7 +32,7 @@ Subject: [PATCH 1/2] fix(doc-tools): use sphinx.locale._ as gettext() for
content = self.content content = self.content
add_text = nodes.strong(label, label) add_text = nodes.strong(label, label)
if self.arguments: if self.arguments:
@@ -179,7 +179,7 @@ class AuditEvent(Directive): @@ -180,7 +180,7 @@
else: else:
args = [] args = []
@ -39,16 +41,18 @@ Subject: [PATCH 1/2] fix(doc-tools): use sphinx.locale._ as gettext() for
text = label.format(name="``{}``".format(name), text = label.format(name="``{}``".format(name),
args=", ".join("``{}``".format(a) for a in args if a)) args=", ".join("``{}``".format(a) for a in args if a))
@@ -358,7 +358,7 @@ class DeprecatedRemoved(Directive): @@ -380,7 +380,7 @@
else: else:
label = self._removed_label label = self._removed_label
- label = translators['sphinx'].gettext(label) - label = translators['sphinx'].gettext(label)
+ label = sphinx_gettext(label) + label = sphinx_gettext(label)
text = label.format(deprecated=self.arguments[0], removed=self.arguments[1]) text = label.format(deprecated=version[0], removed=version[1])
if len(self.arguments) == 3: if len(self.arguments) == 3:
inodes, messages = self.state.inline_text(self.arguments[2], inodes, messages = self.state.inline_text(self.arguments[2],
--- /dev/null Index: Python-3.9.22/Misc/NEWS.d/next/Documentation/2022-10-19-07-15-52.gh-issue-98366.UskMXF.rst
+++ b/Misc/NEWS.d/next/Documentation/2022-10-19-07-15-52.gh-issue-98366.UskMXF.rst ===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ Python-3.9.22/Misc/NEWS.d/next/Documentation/2022-10-19-07-15-52.gh-issue-98366.UskMXF.rst 2025-04-11 09:50:08.952333342 +0200
@@ -0,0 +1 @@ @@ -0,0 +1 @@
+Use sphinx.locale._ as the gettext function in pyspecific.py. +Use sphinx.locale._ as the gettext function in pyspecific.py.

@ -0,0 +1,97 @@
From 37bc08c699f48461be5e000b2da9212237a1ca0f Mon Sep 17 00:00:00 2001
From: JohnJamesUtley <jjutley231@gmail.com>
Date: Tue, 25 Apr 2023 16:01:03 -0400
Subject: [PATCH 1/4] Adds checks to ensure that bracketed hosts found by
urlsplit are of IPv6 or IPvFuture format
---
Lib/test/test_urlparse.py | 26 ++++++++++
Lib/urllib/parse.py | 16 +++++-
Misc/NEWS.d/next/Library/2023-04-26-09-54-25.gh-issue-103848.aDSnpR.rst | 2
3 files changed, 43 insertions(+), 1 deletion(-)
create mode 100644 Misc/NEWS.d/next/Library/2023-04-26-09-54-25.gh-issue-103848.aDSnpR.rst
--- a/Lib/test/test_urlparse.py
+++ b/Lib/test/test_urlparse.py
@@ -1135,6 +1135,32 @@ class UrlParseTestCase(unittest.TestCase
self.assertEqual(p2.scheme, 'tel')
self.assertEqual(p2.path, '+31641044153')
+ def test_invalid_bracketed_hosts(self):
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[192.0.2.146]/Path?Query')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[important.com:8000]/Path?Query')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[v123r.IP]/Path?Query')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[v12ae]/Path?Query')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[v.IP]/Path?Query')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[v123.]/Path?Query')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[v]/Path?Query')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[0439:23af::2309::fae7:1234]/Path?Query')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[0439:23af:2309::fae7:1234:2342:438e:192.0.2.146]/Path?Query')
+ self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@]v6a.ip[/Path')
+
+ def test_splitting_bracketed_hosts(self):
+ p1 = urllib.parse.urlsplit('scheme://user@[v6a.ip]/path?query')
+ self.assertEqual(p1.hostname, 'v6a.ip')
+ self.assertEqual(p1.username, 'user')
+ self.assertEqual(p1.path, '/path')
+ p2 = urllib.parse.urlsplit('scheme://user@[0439:23af:2309::fae7%test]/path?query')
+ self.assertEqual(p2.hostname, '0439:23af:2309::fae7%test')
+ self.assertEqual(p2.username, 'user')
+ self.assertEqual(p2.path, '/path')
+ p3 = urllib.parse.urlsplit('scheme://user@[0439:23af:2309::fae7:1234:192.0.2.146%test]/path?query')
+ self.assertEqual(p3.hostname, '0439:23af:2309::fae7:1234:192.0.2.146%test')
+ self.assertEqual(p3.username, 'user')
+ self.assertEqual(p3.path, '/path')
+
def test_port_casting_failure_message(self):
message = "Port could not be cast to integer value as 'oracle'"
p1 = urllib.parse.urlparse('http://Server=sde; Service=sde:oracle')
--- a/Lib/urllib/parse.py
+++ b/Lib/urllib/parse.py
@@ -36,6 +36,7 @@ import sys
import types
import collections
import warnings
+import ipaddress
__all__ = ["urlparse", "urlunparse", "urljoin", "urldefrag",
"urlsplit", "urlunsplit", "urlencode", "parse_qs",
@@ -442,6 +443,17 @@ def _checknetloc(netloc):
raise ValueError("netloc '" + netloc + "' contains invalid " +
"characters under NFKC normalization")
+# Valid bracketed hosts are defined in
+# https://www.rfc-editor.org/rfc/rfc3986#page-49 and https://url.spec.whatwg.org/
+def _check_bracketed_host(hostname):
+ if hostname.startswith('v'):
+ if not re.match(r"\Av[a-fA-F0-9]+\..+\Z", hostname):
+ raise ValueError(f"IPvFuture address is invalid")
+ else:
+ ip = ipaddress.ip_address(hostname) # Throws Value Error if not IPv6 or IPv4
+ if isinstance(ip, ipaddress.IPv4Address):
+ raise ValueError(f"An IPv4 address cannot be in brackets")
+
def urlsplit(url, scheme='', allow_fragments=True):
"""Parse a URL into 5 components:
<scheme>://<netloc>/<path>?<query>#<fragment>
@@ -488,12 +500,14 @@ def urlsplit(url, scheme='', allow_fragm
break
else:
scheme, url = url[:i].lower(), url[i+1:]
-
if url[:2] == '//':
netloc, url = _splitnetloc(url, 2)
if (('[' in netloc and ']' not in netloc) or
(']' in netloc and '[' not in netloc)):
raise ValueError("Invalid IPv6 URL")
+ if '[' in netloc and ']' in netloc:
+ bracketed_host = netloc.partition('[')[2].partition(']')[0]
+ _check_bracketed_host(bracketed_host)
if allow_fragments and '#' in url:
url, fragment = url.split('#', 1)
if '?' in url:
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-04-26-09-54-25.gh-issue-103848.aDSnpR.rst
@@ -0,0 +1,2 @@
+Add checks to ensure that ``[`` bracketed ``]`` hosts found by
+:func:`urllib.parse.urlsplit` are of IPv6 or IPvFuture format.

@ -0,0 +1,282 @@
From ae0d64cb185900712c40a65d7d8aa118f9903d57 Mon Sep 17 00:00:00 2001
From: Victor Stinner <vstinner@python.org>
Date: Fri, 1 Nov 2024 14:11:47 +0100
Subject: [PATCH] [3.11] gh-124651: Quote template strings in `venv` activation
scripts (GH-124712) (GH-126185) (#126269)
(cherry picked from commit ae961ae94bf19c8f8c7fbea3d1c25cc55ce8ae97)
---
Lib/test/test_venv.py | 81 ++++++++++
Lib/venv/__init__.py | 42 ++++-
Lib/venv/scripts/common/activate | 6
Lib/venv/scripts/nt/activate.bat | 4
Lib/venv/scripts/posix/activate.csh | 6
Lib/venv/scripts/posix/activate.fish | 6
Misc/NEWS.d/next/Library/2024-09-28-02-03-04.gh-issue-124651.bLBGtH.rst | 1
7 files changed, 130 insertions(+), 16 deletions(-)
create mode 100644 Misc/NEWS.d/next/Library/2024-09-28-02-03-04.gh-issue-124651.bLBGtH.rst
--- a/Lib/test/test_venv.py
+++ b/Lib/test/test_venv.py
@@ -14,6 +14,7 @@ import struct
import subprocess
import sys
import tempfile
+import shlex
from test.support import (captured_stdout, captured_stderr, requires_zlib,
can_symlink, EnvironmentVarGuard, rmtree,
import_module,
@@ -85,6 +86,10 @@ class BaseTest(unittest.TestCase):
result = f.read()
return result
+ def assertEndsWith(self, string, tail):
+ if not string.endswith(tail):
+ self.fail(f"String {string!r} does not end with {tail!r}")
+
class BasicTest(BaseTest):
"""Test venv module functionality."""
@@ -342,6 +347,82 @@ class BasicTest(BaseTest):
'import sys; print(sys.executable)'])
self.assertEqual(out.strip(), envpy.encode())
+ # gh-124651: test quoted strings
+ @unittest.skipIf(os.name == 'nt', 'contains invalid characters on Windows')
+ def test_special_chars_bash(self):
+ """
+ Test that the template strings are quoted properly (bash)
+ """
+ rmtree(self.env_dir)
+ bash = shutil.which('bash')
+ if bash is None:
+ self.skipTest('bash required for this test')
+ env_name = '"\';&&$e|\'"'
+ env_dir = os.path.join(os.path.realpath(self.env_dir), env_name)
+ builder = venv.EnvBuilder(clear=True)
+ builder.create(env_dir)
+ activate = os.path.join(env_dir, self.bindir, 'activate')
+ test_script = os.path.join(self.env_dir, 'test_special_chars.sh')
+ with open(test_script, "w") as f:
+ f.write(f'source {shlex.quote(activate)}\n'
+ 'python -c \'import sys; print(sys.executable)\'\n'
+ 'python -c \'import os; print(os.environ["VIRTUAL_ENV"])\'\n'
+ 'deactivate\n')
+ out, err = check_output([bash, test_script])
+ lines = out.splitlines()
+ self.assertTrue(env_name.encode() in lines[0])
+ self.assertEndsWith(lines[1], env_name.encode())
+
+ # gh-124651: test quoted strings
+ @unittest.skipIf(os.name == 'nt', 'contains invalid characters on Windows')
+ def test_special_chars_csh(self):
+ """
+ Test that the template strings are quoted properly (csh)
+ """
+ rmtree(self.env_dir)
+ csh = shutil.which('tcsh') or shutil.which('csh')
+ if csh is None:
+ self.skipTest('csh required for this test')
+ env_name = '"\';&&$e|\'"'
+ env_dir = os.path.join(os.path.realpath(self.env_dir), env_name)
+ builder = venv.EnvBuilder(clear=True)
+ builder.create(env_dir)
+ activate = os.path.join(env_dir, self.bindir, 'activate.csh')
+ test_script = os.path.join(self.env_dir, 'test_special_chars.csh')
+ with open(test_script, "w") as f:
+ f.write(f'source {shlex.quote(activate)}\n'
+ 'python -c \'import sys; print(sys.executable)\'\n'
+ 'python -c \'import os; print(os.environ["VIRTUAL_ENV"])\'\n'
+ 'deactivate\n')
+ out, err = check_output([csh, test_script])
+ lines = out.splitlines()
+ self.assertTrue(env_name.encode() in lines[0])
+ self.assertEndsWith(lines[1], env_name.encode())
+
+ # gh-124651: test quoted strings on Windows
+ @unittest.skipUnless(os.name == 'nt', 'only relevant on Windows')
+ def test_special_chars_windows(self):
+ """
+ Test that the template strings are quoted properly on Windows
+ """
+ rmtree(self.env_dir)
+ env_name = "'&&^$e"
+ env_dir = os.path.join(os.path.realpath(self.env_dir), env_name)
+ builder = venv.EnvBuilder(clear=True)
+ builder.create(env_dir)
+ activate = os.path.join(env_dir, self.bindir, 'activate.bat')
+ test_batch = os.path.join(self.env_dir, 'test_special_chars.bat')
+ with open(test_batch, "w") as f:
+ f.write('@echo off\n'
+ f'"{activate}" & '
+ f'{self.exe} -c "import sys; print(sys.executable)" & '
+ f'{self.exe} -c "import os; print(os.environ[\'VIRTUAL_ENV\'])" & '
+ 'deactivate')
+ out, err = check_output([test_batch])
+ lines = out.splitlines()
+ self.assertTrue(env_name.encode() in lines[0])
+ self.assertEndsWith(lines[1], env_name.encode())
+
@unittest.skipUnless(os.name == 'nt', 'only relevant on Windows')
def test_unicode_in_batch_file(self):
"""
--- a/Lib/venv/__init__.py
+++ b/Lib/venv/__init__.py
@@ -11,6 +11,7 @@ import subprocess
import sys
import sysconfig
import types
+import shlex
CORE_VENV_DEPS = ('pip', 'setuptools')
@@ -348,11 +349,41 @@ class EnvBuilder:
:param context: The information for the environment creation request
being processed.
"""
- text = text.replace('__VENV_DIR__', context.env_dir)
- text = text.replace('__VENV_NAME__', context.env_name)
- text = text.replace('__VENV_PROMPT__', context.prompt)
- text = text.replace('__VENV_BIN_NAME__', context.bin_name)
- text = text.replace('__VENV_PYTHON__', context.env_exe)
+ replacements = {
+ '__VENV_DIR__': context.env_dir,
+ '__VENV_NAME__': context.env_name,
+ '__VENV_PROMPT__': context.prompt,
+ '__VENV_BIN_NAME__': context.bin_name,
+ '__VENV_PYTHON__': context.env_exe,
+ }
+
+ def quote_ps1(s):
+ """
+ This should satisfy PowerShell quoting rules [1], unless the quoted
+ string is passed directly to Windows native commands [2].
+ [1]: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_quoting_rules
+ [2]: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_parsing#passing-arguments-that-contain-quote-characters
+ """
+ s = s.replace("'", "''")
+ return f"'{s}'"
+
+ def quote_bat(s):
+ return s
+
+ # gh-124651: need to quote the template strings properly
+ quote = shlex.quote
+ script_path = context.script_path
+ if script_path.endswith('.ps1'):
+ quote = quote_ps1
+ elif script_path.endswith('.bat'):
+ quote = quote_bat
+ else:
+ # fallbacks to POSIX shell compliant quote
+ quote = shlex.quote
+
+ replacements = {key: quote(s) for key, s in replacements.items()}
+ for key, quoted in replacements.items():
+ text = text.replace(key, quoted)
return text
def install_scripts(self, context, path):
@@ -392,6 +423,7 @@ class EnvBuilder:
with open(srcfile, 'rb') as f:
data = f.read()
if not srcfile.endswith(('.exe', '.pdb')):
+ context.script_path = srcfile
try:
data = data.decode('utf-8')
data = self.replace_variables(data, context)
--- a/Lib/venv/scripts/common/activate
+++ b/Lib/venv/scripts/common/activate
@@ -37,11 +37,11 @@ deactivate () {
# unset irrelevant variables
deactivate nondestructive
-VIRTUAL_ENV="__VENV_DIR__"
+VIRTUAL_ENV=__VENV_DIR__
export VIRTUAL_ENV
_OLD_VIRTUAL_PATH="$PATH"
-PATH="$VIRTUAL_ENV/__VENV_BIN_NAME__:$PATH"
+PATH="$VIRTUAL_ENV/"__VENV_BIN_NAME__":$PATH"
export PATH
# unset PYTHONHOME if set
@@ -54,7 +54,7 @@ fi
if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then
_OLD_VIRTUAL_PS1="${PS1:-}"
- PS1="__VENV_PROMPT__${PS1:-}"
+ PS1=__VENV_PROMPT__"${PS1:-}"
export PS1
fi
--- a/Lib/venv/scripts/nt/activate.bat
+++ b/Lib/venv/scripts/nt/activate.bat
@@ -8,7 +8,7 @@ if defined _OLD_CODEPAGE (
"%SystemRoot%\System32\chcp.com" 65001 > nul
)
-set VIRTUAL_ENV=__VENV_DIR__
+set "VIRTUAL_ENV=__VENV_DIR__"
if not defined PROMPT set PROMPT=$P$G
@@ -24,7 +24,7 @@ set PYTHONHOME=
if defined _OLD_VIRTUAL_PATH set PATH=%_OLD_VIRTUAL_PATH%
if not defined _OLD_VIRTUAL_PATH set _OLD_VIRTUAL_PATH=%PATH%
-set PATH=%VIRTUAL_ENV%\__VENV_BIN_NAME__;%PATH%
+set "PATH=%VIRTUAL_ENV%\__VENV_BIN_NAME__;%PATH%"
:END
if defined _OLD_CODEPAGE (
--- a/Lib/venv/scripts/posix/activate.csh
+++ b/Lib/venv/scripts/posix/activate.csh
@@ -8,16 +8,16 @@ alias deactivate 'test $?_OLD_VIRTUAL_PA
# Unset irrelevant variables.
deactivate nondestructive
-setenv VIRTUAL_ENV "__VENV_DIR__"
+setenv VIRTUAL_ENV __VENV_DIR__
set _OLD_VIRTUAL_PATH="$PATH"
-setenv PATH "$VIRTUAL_ENV/__VENV_BIN_NAME__:$PATH"
+setenv PATH "$VIRTUAL_ENV/"__VENV_BIN_NAME__":$PATH"
set _OLD_VIRTUAL_PROMPT="$prompt"
if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then
- set prompt = "__VENV_PROMPT__$prompt"
+ set prompt = __VENV_PROMPT__"$prompt"
endif
alias pydoc python -m pydoc
--- a/Lib/venv/scripts/posix/activate.fish
+++ b/Lib/venv/scripts/posix/activate.fish
@@ -29,10 +29,10 @@ end
# Unset irrelevant variables.
deactivate nondestructive
-set -gx VIRTUAL_ENV "__VENV_DIR__"
+set -gx VIRTUAL_ENV __VENV_DIR__
set -gx _OLD_VIRTUAL_PATH $PATH
-set -gx PATH "$VIRTUAL_ENV/__VENV_BIN_NAME__" $PATH
+set -gx PATH "$VIRTUAL_ENV/"__VENV_BIN_NAME__ $PATH
# Unset PYTHONHOME if set.
if set -q PYTHONHOME
@@ -52,7 +52,7 @@ if test -z "$VIRTUAL_ENV_DISABLE_PROMPT"
set -l old_status $status
# Output the venv prompt; color taken from the blue of the Python logo.
- printf "%s%s%s" (set_color 4B8BBE) "__VENV_PROMPT__" (set_color normal)
+ printf "%s%s%s" (set_color 4B8BBE) __VENV_PROMPT__ (set_color normal)
# Restore the return status of the previous command.
echo "exit $old_status" | .
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-09-28-02-03-04.gh-issue-124651.bLBGtH.rst
@@ -0,0 +1 @@
+Properly quote template strings in :mod:`venv` activation scripts.

3
Python-3.9.22.tar.xz Normal file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8c136d199d3637a1fce98a16adc809c1d83c922d02d41f3614b34f8b6e7d38ec
size 19652572

File diff suppressed because one or more lines are too long

@ -1,3 +1,128 @@
-------------------------------------------------------------------
Wed Apr 9 20:04:17 UTC 2025 - Matej Cepl <mcepl@cepl.eu>
- Update to 3.9.22:
- gh-131809: Update bundled libexpat to 2.7.1
- gh-131261: Upgrade to libexpat 2.7.0
- gh-105704: When using urllib.parse.urlsplit() and
urllib.parse.urlparse() host parsing would not reject domain
names containing square brackets ([ and ]). Square brackets
are only valid for IPv6 and IPvFuture hosts according to RFC
3986 Section 3.2.2 (bsc#1236705, CVE-2025-0938,
gh#python/cpython#105704).
- gh-121284: Fix bug in the folding of rfc2047 encoded-words
when flattening an email message using a modern email
policy. Previously when an encoded-word was too long for
a line, it would be decoded, split across lines, and
re-encoded. But commas and other special characters in the
original text could be left unencoded and unquoted. This
could theoretically be used to spoof header lines using a
carefully constructed encoded-word if the resulting rendered
email was transmitted or re-parsed.
- gh-119511: Fix a potential denial of service in the imaplib
module. When connecting to a malicious server, it could
cause an arbitrary amount of memory to be allocated. On many
systems this is harmless as unused virtual memory is only
a mapping, but if this hit a virtual address size limit
it could lead to a MemoryError or other process crash. On
unusual systems or builds where all allocated memory is
touched and backed by actual ram or storage it couldve
consumed resources doing so until similarly crashing.
- gh-121277: Writers of CPythons documentation can now use
next as the version for the versionchanged, versionadded,
deprecated directives.
- Remote upstreamed patch:
- CVE-2025-0938-sq-brackets-domain-names.patch
-------------------------------------------------------------------
Mon Mar 10 15:44:31 UTC 2025 - Bernhard Wiedemann <bwiedemann@suse.com>
- Skip PGO with %want_reproducible_builds (bsc#1239210)
-------------------------------------------------------------------
Tue Feb 4 14:43:13 UTC 2025 - Matej Cepl <mcepl@cepl.eu>
- Add CVE-2025-0938-sq-brackets-domain-names.patch which
disallows square brackets ([ and ]) in domain names for parsed
URLs (bsc#1236705, CVE-2025-0938, gh#python/cpython#105704)
-------------------------------------------------------------------
Wed Dec 4 19:51:41 UTC 2024 - Matej Cepl <mcepl@cepl.eu>
- Update to 3.9.21:
- Tests
- gh-125041: Re-enable skipped tests for zlib on the
s390x architecture: only skip checks of the compressed
bytes, which can be different between zlibs software
implementation and the hardware-accelerated implementation.
- gh-109396: Fix test_socket.test_hmac_sha1() in FIPS
mode. Use a longer key: FIPS mode requires at least of at
least 112 bits. The previous key was only 32 bits. Patch by
Victor Stinner.
- gh-100454: Fix SSL tests CI for OpenSSL 3.1+
- Security
- gh-126623: Upgrade libexpat to 2.6.4
- gh-122792: Changed IPv4-mapped ipaddress.IPv6Address to
consistently use the mapped IPv4 address value for deciding
properties. Properties which have their behavior fixed are
is_multicast, is_reserved, is_link_local, is_global, and
is_unspecified (bsc#1233307, CVE-2024-11168).
- Library
- gh-124651: Properly quote template strings in venv
activation scripts (bsc#1232241, CVE-2024-9287).
- gh-103848: Add checks to ensure that [ bracketed ] hosts
found by urllib.parse.urlsplit() are of IPv6 or IPvFuture
format.
- Documentation
- gh-95588: Clarified the conflicting advice given in the ast
documentation about ast.literal_eval() being “safe” for use
on untrusted input while at the same time warning that it
can crash the process. The latter statement is true and is
deemed unfixable without a large amount of work unsuitable
for a bugfix. So we keep the warning and no longer claim
that literal_eval is safe.
- Remove upstreamed patches:
- CVE-2024-11168-validation-IPv6-addrs.patch
- CVE-2024-9287-venv_path_unquoted.patch
-------------------------------------------------------------------
Thu Nov 14 07:06:20 UTC 2024 - Matej Cepl <mcepl@cepl.eu>
- Remove -IVendor/ from python-config boo#1231795
-------------------------------------------------------------------
Wed Nov 13 13:25:01 UTC 2024 - Matej Cepl <mcepl@cepl.eu>
- Add CVE-2024-11168-validation-IPv6-addrs.patch
fixing bsc#1233307 (CVE-2024-11168,
gh#python/cpython#103848): Improper validation of IPv6 and
IPvFuture addresses.
-------------------------------------------------------------------
Fri Nov 1 21:16:32 UTC 2024 - Matej Cepl <mcepl@cepl.eu>
- Update CVE-2024-9287-venv_path_unquoted.patch according to the
upstream PR gh#python/cpython!126301.
-------------------------------------------------------------------
Thu Oct 24 16:09:00 UTC 2024 - Matej Cepl <mcepl@cepl.eu>
- Add CVE-2024-9287-venv_path_unquoted.patch to properly quote
path names provided when creating a virtual environment
(bsc#1232241, CVE-2024-9287)
-------------------------------------------------------------------
Wed Oct 2 16:18:29 UTC 2024 - Matej Cepl <mcepl@cepl.eu>
- Drop .pyc files from docdir for reproducible builds
(bsc#1230906).
-------------------------------------------------------------------
Fri Sep 20 14:57:10 UTC 2024 - Matej Cepl <mcepl@cepl.eu>
- Add sphinx-802.patch to overcome working both with the most
recent and older Sphinx versions.
------------------------------------------------------------------- -------------------------------------------------------------------
Mon Sep 9 18:02:59 UTC 2024 - Matej Cepl <mcepl@cepl.eu> Mon Sep 9 18:02:59 UTC 2024 - Matej Cepl <mcepl@cepl.eu>
@ -34,7 +159,7 @@ Mon Sep 9 18:02:59 UTC 2024 - Matej Cepl <mcepl@cepl.eu>
:class:`zipfile.Path` causing infinite loops (gh-122905) without breaking :class:`zipfile.Path` causing infinite loops (gh-122905) without breaking
contents using legitimate characters (bsc#1229704, CVE-2024-8088). contents using legitimate characters (bsc#1229704, CVE-2024-8088).
- gh-123067: Fix quadratic complexity in parsing ``"``-quoted cookie values - gh-123067: Fix quadratic complexity in parsing ``"``-quoted cookie values
with backslashes by :mod:`http.cookies`. with backslashes by :mod:`http.cookies` (bsc#1229596, CVE-2024-7592).
- gh-121650: :mod:`email` headers with embedded newlines are now quoted on - gh-121650: :mod:`email` headers with embedded newlines are now quoted on
output. The :mod:`~email.generator` will now refuse to serialize (write) output. The :mod:`~email.generator` will now refuse to serialize (write)
headers that are unsafely folded or delimited; see headers that are unsafely folded or delimited; see
@ -76,8 +201,7 @@ Mon Sep 9 18:02:59 UTC 2024 - Matej Cepl <mcepl@cepl.eu>
Thu Sep 5 13:44:48 UTC 2024 - Matej Cepl <mcepl@cepl.eu> Thu Sep 5 13:44:48 UTC 2024 - Matej Cepl <mcepl@cepl.eu>
- Add CVE-2024-6232-cookies-quad-complex.patch to avoid quadratic - Add CVE-2024-6232-cookies-quad-complex.patch to avoid quadratic
complexity in parsing "-quoted cookie values with backslashes complexity in parsing tarfile headers (bsc#1230227, CVE-2024-6232).
(bsc#1229596, CVE-2024-6232).
------------------------------------------------------------------- -------------------------------------------------------------------
Thu Sep 5 08:11:45 UTC 2024 - Matej Cepl <mcepl@cepl.eu> Thu Sep 5 08:11:45 UTC 2024 - Matej Cepl <mcepl@cepl.eu>

@ -1,7 +1,7 @@
# #
# spec file for package python39 # spec file for package python39
# #
# Copyright (c) 2024 SUSE LLC # Copyright (c) 2025 SUSE LLC
# #
# All modifications and additions to the file contributed by third parties # All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed # remain the property of their copyright owners, unless otherwise agreed
@ -36,7 +36,7 @@
%bcond_without general %bcond_without general
%endif %endif
%if 0%{?do_profiling} %if 0%{?do_profiling} && !0%{?want_reproducible_builds}
%bcond_without profileopt %bcond_without profileopt
%else %else
%bcond_with profileopt %bcond_with profileopt
@ -99,13 +99,13 @@
%define dynlib() %{sitedir}/lib-dynload/%{1}.cpython-%{abi_tag}-%{archname}-%{_os}%{?_gnu}%{?armsuffix}.so %define dynlib() %{sitedir}/lib-dynload/%{1}.cpython-%{abi_tag}-%{archname}-%{_os}%{?_gnu}%{?armsuffix}.so
%bcond_without profileopt %bcond_without profileopt
Name: %{python_pkg_name}%{psuffix} Name: %{python_pkg_name}%{psuffix}
Version: 3.9.20 Version: 3.9.22
Release: 0 Release: 0
Summary: Python 3 Interpreter Summary: Python 3 Interpreter
License: Python-2.0 License: Python-2.0
URL: https://www.python.org/ URL: https://www.python.org/
Source0: https://www.python.org/ftp/python/%{folderversion}/%{tarname}.tar.xz Source0: https://www.python.org/ftp/python/%{folderversion}/%{tarname}.tar.xz
Source1: https://www.python.org/ftp/python/%{folderversion}/%{tarname}.tar.xz.asc Source1: https://www.python.org/ftp/python/%{folderversion}/%{tarname}.tar.xz.sigstore
Source2: baselibs.conf Source2: baselibs.conf
Source3: README.SUSE Source3: README.SUSE
Source7: macros.python3 Source7: macros.python3
@ -134,10 +134,6 @@ Source100: PACKAGING-NOTES
# to /usr/local if executable is /usr/bin/python* and RPM build # to /usr/local if executable is /usr/bin/python* and RPM build
# is not detected to make pip and distutils install into separate location # is not detected to make pip and distutils install into separate location
Patch02: F00251-change-user-install-location.patch Patch02: F00251-change-user-install-location.patch
# PATCH-FEATURE-UPSTREAM decimal.patch bsc#1189356 mcepl@suse.com
# fix building with mpdecimal
# https://www.bytereef.org/contrib/decimal.diff
Patch05: decimal.patch
# PATCH-FEATURE-UPSTREAM distutils-reproducible-compile.patch gh#python/cpython#8057 mcepl@suse.com # PATCH-FEATURE-UPSTREAM distutils-reproducible-compile.patch gh#python/cpython#8057 mcepl@suse.com
# Improve reproduceability # Improve reproduceability
Patch06: distutils-reproducible-compile.patch Patch06: distutils-reproducible-compile.patch
@ -161,37 +157,43 @@ Patch33: no-skipif-doctests.patch
# PATCH-FIX-SLE skip-test_pyobject_freed_is_freed.patch mcepl@suse.com # PATCH-FIX-SLE skip-test_pyobject_freed_is_freed.patch mcepl@suse.com
# skip a test failing on SLE-15 # skip a test failing on SLE-15
Patch34: skip-test_pyobject_freed_is_freed.patch Patch34: skip-test_pyobject_freed_is_freed.patch
# PATCH-FEATURE-UPSTREAM decimal.patch bsc#1189356 mcepl@suse.com
# fix building with mpdecimal
# https://www.bytereef.org/contrib/decimal.diff
Patch35: decimal.patch
# PATCH-FIX-UPSTREAM support-expat-CVE-2022-25236-patched.patch jsc#SLE-21253 mcepl@suse.com # PATCH-FIX-UPSTREAM support-expat-CVE-2022-25236-patched.patch jsc#SLE-21253 mcepl@suse.com
# Makes Python resilient to changes of API of libexpat # Makes Python resilient to changes of API of libexpat
Patch35: support-expat-CVE-2022-25236-patched.patch Patch40: support-expat-CVE-2022-25236-patched.patch
# PATCH-FIX-UPSTREAM CVE-2023-52425-libexpat-2.6.0-backport.patch gh#python/cpython#117187 mcepl@suse.com # PATCH-FIX-UPSTREAM CVE-2023-52425-libexpat-2.6.0-backport.patch gh#python/cpython#117187 mcepl@suse.com
# Make the test suite work with libexpat < 2.6.0 # Make the test suite work with libexpat < 2.6.0
Patch36: CVE-2023-52425-libexpat-2.6.0-backport.patch Patch41: CVE-2023-52425-libexpat-2.6.0-backport.patch
# PATCH-FIX-UPSTREAM 98437-sphinx.locale._-as-gettext-in-pyspecific.patch gh#python/cpython#98366 mcepl@suse.com # PATCH-FIX-UPSTREAM 98437-sphinx.locale._-as-gettext-in-pyspecific.patch gh#python/cpython#98366 mcepl@suse.com
# this patch makes things totally awesome # this patch makes things totally awesome
Patch37: 98437-sphinx.locale._-as-gettext-in-pyspecific.patch Patch42: 98437-sphinx.locale._-as-gettext-in-pyspecific.patch
# PATCH-FIX-UPSTREAM bpo-37596-make-set-marshalling.patch bsc#1211765 mcepl@suse.com # PATCH-FIX-UPSTREAM bpo-37596-make-set-marshalling.patch bsc#1211765 mcepl@suse.com
# Make `set` and `frozenset` marshalling deterministic # Make `set` and `frozenset` marshalling deterministic
Patch38: bpo-37596-make-set-marshalling.patch Patch43: bpo-37596-make-set-marshalling.patch
# PATCH-FIX-UPSTREAM gh-78214-marshal_stabilize_FLAG_REF.patch bsc#1213463 mcepl@suse.com # PATCH-FIX-UPSTREAM gh-78214-marshal_stabilize_FLAG_REF.patch bsc#1213463 mcepl@suse.com
# marshal: Stabilize FLAG_REF usage # marshal: Stabilize FLAG_REF usage
Patch39: gh-78214-marshal_stabilize_FLAG_REF.patch Patch44: gh-78214-marshal_stabilize_FLAG_REF.patch
# PATCH-FIX-UPSTREAM 99366-patch.dict-can-decorate-async.patch bsc#[0-9]+ mcepl@suse.com # PATCH-FIX-UPSTREAM 99366-patch.dict-can-decorate-async.patch bsc#[0-9]+ mcepl@suse.com
# Patch for gh#python/cpython#98086 # Patch for gh#python/cpython#98086
Patch40: 99366-patch.dict-can-decorate-async.patch Patch45: 99366-patch.dict-can-decorate-async.patch
# PATCH-FIX-OPENSUSE downport-Sphinx-features.patch mcepl@suse.com # PATCH-FIX-OPENSUSE downport-Sphinx-features.patch mcepl@suse.com
# Make documentation build with older Sphinx # Make documentation build with older Sphinx
Patch41: downport-Sphinx-features.patch Patch46: downport-Sphinx-features.patch
# PATCH-FIX-UPSTREAM bso1227999-reproducible-builds.patch bsc#1227999 mcepl@suse.com # PATCH-FIX-UPSTREAM bso1227999-reproducible-builds.patch bsc#1227999 mcepl@suse.com
# reproducibility patches # reproducibility patches
Patch46: bso1227999-reproducible-builds.patch Patch47: bso1227999-reproducible-builds.patch
# PATCH-FIX-UPSTREAM CVE-2024-5642-OpenSSL-API-buf-overread-NPN.patch bsc#1227233 mcepl@suse.com # PATCH-FIX-UPSTREAM CVE-2024-5642-OpenSSL-API-buf-overread-NPN.patch bsc#1227233 mcepl@suse.com
# Remove for support for anything but OpenSSL 1.1.1 or newer # Remove for support for anything but OpenSSL 1.1.1 or newer
Patch48: CVE-2024-5642-OpenSSL-API-buf-overread-NPN.patch Patch48: CVE-2024-5642-OpenSSL-API-buf-overread-NPN.patch
# PATCH-FIX-UPSTREAM gh120226-fix-sendfile-test-kernel-610.patch gh#python/cpython#120226 mcepl@suse.com # PATCH-FIX-UPSTREAM gh120226-fix-sendfile-test-kernel-610.patch gh#python/cpython#120226 mcepl@suse.com
# Fix test_sendfile_close_peer_in_the_middle_of_receiving on Linux >= 6.10 (GH-120227) # Fix test_sendfile_close_peer_in_the_middle_of_receiving on Linux >= 6.10 (GH-120227)
Patch50: gh120226-fix-sendfile-test-kernel-610.patch Patch50: gh120226-fix-sendfile-test-kernel-610.patch
# PATCH-FIX-UPSTREAM sphinx-802.patch mcepl@suse.com
# status_iterator method moved between the Sphinx versions
Patch51: sphinx-802.patch
BuildRequires: autoconf-archive BuildRequires: autoconf-archive
BuildRequires: automake BuildRequires: automake
BuildRequires: fdupes BuildRequires: fdupes
@ -430,34 +432,40 @@ other applications.
%prep %prep
%setup -q -n %{tarname} %setup -q -n %{tarname}
%patch -P 02 -p1
%patch -P 06 -p1 %patch -p1 -P 02
%patch -P 07 -p1 %patch -p1 -P 06
%patch -P 08 -p1 %patch -p1 -P 07
%patch -P 09 -p1 %patch -p1 -P 08
%patch -P 15 -p1 %patch -p1 -P 09
%patch -P 25 -p1 %patch -p1 -P 15
%patch -P 29 -p1 %patch -p1 -P 25
%patch -P 32 -p1 %patch -p1 -P 29
%patch -p1 -P 32
%if 0%{?sle_version} %if 0%{?sle_version}
%patch -P 33 -p1 %patch -p1 -P 33
%patch -P 34 -p1 %patch -p1 -P 34
%endif %endif
%if %{with mpdecimal} %if %{with mpdecimal}
%patch -P 05 -p1 %patch -p1 -P 35
%endif %endif
%patch -P 35 -p1
%patch -P 36 -p1 %patch -p1 -P 40
%patch -P 37 -p1
%patch -P 38 -p1
%patch -P 39 -p1
%patch -P 40 -p1
%if 0%{?sle_version} && 0%{?sle_version} <= 150500
%patch -p1 -P 41 %patch -p1 -P 41
%endif %patch -p1 -P 42
%patch -p1 -P 43
%patch -p1 -P 44
%patch -p1 -P 45
%if 0%{?sle_version} && 0%{?sle_version} <= 150500
%patch -p1 -P 46 %patch -p1 -P 46
%endif
%patch -p1 -P 47
%patch -p1 -P 48 %patch -p1 -P 48
%patch -p1 -P 50 %patch -p1 -P 50
%patch -p1 -P 51
# drop Autoconf version requirement # drop Autoconf version requirement
sed -i 's/^AC_PREREQ/dnl AC_PREREQ/' configure.ac sed -i 's/^AC_PREREQ/dnl AC_PREREQ/' configure.ac
@ -764,6 +772,9 @@ install -m 755 -D Tools/gdb/libpython.py %{buildroot}%{_datadir}/gdb/auto-load/%
# install devel files to /config # install devel files to /config
#cp Makefile Makefile.pre.in Makefile.pre $RPM_BUILD_ROOT%{sitedir}/config-%{python_abi}/ #cp Makefile Makefile.pre.in Makefile.pre $RPM_BUILD_ROOT%{sitedir}/config-%{python_abi}/
# Remove -IVendor/ from python-config boo#1231795
sed -i 's/-IVendor\///' %{buildroot}%{_bindir}/python%{python_abi}-config
# RPM macros # RPM macros
%if %{primary_interpreter} %if %{primary_interpreter}
mkdir -p %{buildroot}%{_rpmconfigdir}/macros.d/ mkdir -p %{buildroot}%{_rpmconfigdir}/macros.d/
@ -792,6 +803,11 @@ LD_LIBRARY_PATH=. ./python -O -c "from py_compile import compile; compile('$FAIL
echo %{sitedir}/_import_failed > %{buildroot}/%{sitedir}/site-packages/zzzz-import-failed-hooks.pth echo %{sitedir}/_import_failed > %{buildroot}/%{sitedir}/site-packages/zzzz-import-failed-hooks.pth
%endif %endif
# For the purposes of reproducibility, it is necessary to eliminate any *.pyc files inside documentation dirs
if [ -d %{buildroot}%{_defaultdocdir} ] ; then
find %{buildroot}%{_defaultdocdir} -type f -name \*.pyc -ls -exec rm -vf '{}' \;
fi
%if %{with general} %if %{with general}
%files -n %{python_pkg_name}-tk %files -n %{python_pkg_name}-tk
%{sitedir}/tkinter %{sitedir}/tkinter

23
sphinx-802.patch Normal file

@ -0,0 +1,23 @@
---
Doc/tools/extensions/pyspecific.py | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
Index: Python-3.9.22/Doc/tools/extensions/pyspecific.py
===================================================================
--- Python-3.9.22.orig/Doc/tools/extensions/pyspecific.py 2025-04-11 09:50:56.818993764 +0200
+++ Python-3.9.22/Doc/tools/extensions/pyspecific.py 2025-04-11 09:51:18.844485631 +0200
@@ -28,7 +28,13 @@
except ImportError:
from sphinx.environment import NoUri
from sphinx.locale import _ as sphinx_gettext
-from sphinx.util import status_iterator, logging
+try:
+ from sphinx.util.display import status_iterator
+except ImportError:
+ # This method was moved into sphinx.util.display in Sphinx 6.1.0. Before
+ # that it resided in sphinx.util.
+ from sphinx.util import status_iterator
+from sphinx.util import logging
from sphinx.util.nodes import split_explicit_title
from sphinx.writers.text import TextWriter, TextTranslator
from sphinx.writers.latex import LaTeXTranslator

@ -2,9 +2,11 @@
Doc/tools/extensions/pyspecific.py | 7 ++++++- Doc/tools/extensions/pyspecific.py | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-) 1 file changed, 6 insertions(+), 1 deletion(-)
--- a/Doc/tools/extensions/pyspecific.py Index: Python-3.9.22/Doc/tools/extensions/pyspecific.py
+++ b/Doc/tools/extensions/pyspecific.py ===================================================================
@@ -385,7 +385,12 @@ class DeprecatedRemoved(Directive): --- Python-3.9.22.orig/Doc/tools/extensions/pyspecific.py 2025-04-08 17:21:55.000000000 +0200
+++ Python-3.9.22/Doc/tools/extensions/pyspecific.py 2025-04-11 09:49:58.417019238 +0200
@@ -407,7 +407,12 @@
translatable=False) translatable=False)
node.append(para) node.append(para)
env = self.state.document.settings.env env = self.state.document.settings.env