Compare commits
No commits in common. "imports/c10s/python3-3.6.8-67.el10" and "c8" have entirely different histories.
imports/c1
...
c8
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1 @@
|
|||||||
/*.tar.*
|
SOURCES/Python-3.6.8-noexe.tar.xz
|
||||||
|
|||||||
1
.python3.metadata
Normal file
1
.python3.metadata
Normal file
@ -0,0 +1 @@
|
|||||||
|
a39802ac8f0c61645c6a50fbdd32e3ca92862ff5 SOURCES/Python-3.6.8-noexe.tar.xz
|
||||||
@ -0,0 +1,281 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Victor Stinner <vstinner@python.org>
|
||||||
|
Date: Fri, 1 Nov 2024 14:11:47 +0100
|
||||||
|
Subject: [PATCH] 00443: gh-124651: Quote template strings in `venv` activation
|
||||||
|
scripts
|
||||||
|
|
||||||
|
(cherry picked from 3.9)
|
||||||
|
---
|
||||||
|
Lib/test/test_venv.py | 82 +++++++++++++++++++
|
||||||
|
Lib/venv/__init__.py | 42 ++++++++--
|
||||||
|
Lib/venv/scripts/common/activate | 8 +-
|
||||||
|
Lib/venv/scripts/posix/activate.csh | 8 +-
|
||||||
|
Lib/venv/scripts/posix/activate.fish | 8 +-
|
||||||
|
...-09-28-02-03-04.gh-issue-124651.bLBGtH.rst | 1 +
|
||||||
|
6 files changed, 132 insertions(+), 17 deletions(-)
|
||||||
|
create mode 100644 Misc/NEWS.d/next/Library/2024-09-28-02-03-04.gh-issue-124651.bLBGtH.rst
|
||||||
|
|
||||||
|
diff --git a/Lib/test/test_venv.py b/Lib/test/test_venv.py
|
||||||
|
index 842470fef0..67fdcd86bb 100644
|
||||||
|
--- a/Lib/test/test_venv.py
|
||||||
|
+++ b/Lib/test/test_venv.py
|
||||||
|
@@ -13,6 +13,8 @@ import struct
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import tempfile
|
||||||
|
+import shlex
|
||||||
|
+import shutil
|
||||||
|
from test.support import (captured_stdout, captured_stderr, requires_zlib,
|
||||||
|
can_symlink, EnvironmentVarGuard, rmtree)
|
||||||
|
import unittest
|
||||||
|
@@ -80,6 +82,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."""
|
||||||
|
|
||||||
|
@@ -293,6 +299,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):
|
||||||
|
"""
|
||||||
|
diff --git a/Lib/venv/__init__.py b/Lib/venv/__init__.py
|
||||||
|
index 716129d139..0c44dfd07d 100644
|
||||||
|
--- a/Lib/venv/__init__.py
|
||||||
|
+++ b/Lib/venv/__init__.py
|
||||||
|
@@ -10,6 +10,7 @@ import shutil
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import types
|
||||||
|
+import shlex
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@@ -280,11 +281,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):
|
||||||
|
@@ -321,6 +352,7 @@ class EnvBuilder:
|
||||||
|
with open(srcfile, 'rb') as f:
|
||||||
|
data = f.read()
|
||||||
|
if not srcfile.endswith('.exe'):
|
||||||
|
+ context.script_path = srcfile
|
||||||
|
try:
|
||||||
|
data = data.decode('utf-8')
|
||||||
|
data = self.replace_variables(data, context)
|
||||||
|
diff --git a/Lib/venv/scripts/common/activate b/Lib/venv/scripts/common/activate
|
||||||
|
index fff0765af5..c2e2f968fa 100644
|
||||||
|
--- 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,8 +54,8 @@ fi
|
||||||
|
|
||||||
|
if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then
|
||||||
|
_OLD_VIRTUAL_PS1="${PS1:-}"
|
||||||
|
- if [ "x__VENV_PROMPT__" != x ] ; then
|
||||||
|
- PS1="__VENV_PROMPT__${PS1:-}"
|
||||||
|
+ if [ "x"__VENV_PROMPT__ != x ] ; then
|
||||||
|
+ PS1=__VENV_PROMPT__"${PS1:-}"
|
||||||
|
else
|
||||||
|
if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then
|
||||||
|
# special case for Aspen magic directories
|
||||||
|
diff --git a/Lib/venv/scripts/posix/activate.csh b/Lib/venv/scripts/posix/activate.csh
|
||||||
|
index b0c7028a92..0e90d54008 100644
|
||||||
|
--- a/Lib/venv/scripts/posix/activate.csh
|
||||||
|
+++ b/Lib/venv/scripts/posix/activate.csh
|
||||||
|
@@ -8,17 +8,17 @@ alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_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
|
||||||
|
- if ("__VENV_NAME__" != "") then
|
||||||
|
- set env_name = "__VENV_NAME__"
|
||||||
|
+ if (__VENV_NAME__ != "") then
|
||||||
|
+ set env_name = __VENV_NAME__
|
||||||
|
else
|
||||||
|
if (`basename "VIRTUAL_ENV"` == "__") then
|
||||||
|
# special case for Aspen magic directories
|
||||||
|
diff --git a/Lib/venv/scripts/posix/activate.fish b/Lib/venv/scripts/posix/activate.fish
|
||||||
|
index 4d4f0bd7a4..0407f9c7be 100644
|
||||||
|
--- 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,8 +52,8 @@ if test -z "$VIRTUAL_ENV_DISABLE_PROMPT"
|
||||||
|
set -l old_status $status
|
||||||
|
|
||||||
|
# Prompt override?
|
||||||
|
- if test -n "__VENV_PROMPT__"
|
||||||
|
- printf "%s%s" "__VENV_PROMPT__" (set_color normal)
|
||||||
|
+ if test -n __VENV_PROMPT__
|
||||||
|
+ printf "%s%s" __VENV_PROMPT__ (set_color normal)
|
||||||
|
else
|
||||||
|
# ...Otherwise, prepend env
|
||||||
|
set -l _checkbase (basename "$VIRTUAL_ENV")
|
||||||
|
diff --git a/Misc/NEWS.d/next/Library/2024-09-28-02-03-04.gh-issue-124651.bLBGtH.rst b/Misc/NEWS.d/next/Library/2024-09-28-02-03-04.gh-issue-124651.bLBGtH.rst
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..17fc917139
|
||||||
|
--- /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.
|
||||||
110
SOURCES/00444-security-fix-for-cve-2024-11168.patch
Normal file
110
SOURCES/00444-security-fix-for-cve-2024-11168.patch
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Miss Islington (bot)"
|
||||||
|
<31488909+miss-islington@users.noreply.github.com>
|
||||||
|
Date: Tue, 9 May 2023 23:35:24 -0700
|
||||||
|
Subject: [PATCH] 00444: Security fix for CVE-2024-11168
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
gh-103848: Adds checks to ensure that bracketed hosts found by urlsplit are of IPv6 or IPvFuture format (GH-103849)
|
||||||
|
|
||||||
|
Tests are adjusted because Python <3.9 don't support scoped IPv6 addresses.
|
||||||
|
|
||||||
|
(cherry picked from commit 29f348e232e82938ba2165843c448c2b291504c5)
|
||||||
|
|
||||||
|
Co-authored-by: JohnJamesUtley <81572567+JohnJamesUtley@users.noreply.github.com>
|
||||||
|
Co-authored-by: Gregory P. Smith <greg@krypto.org>
|
||||||
|
Co-authored-by: Lumír Balhar <lbalhar@redhat.com>
|
||||||
|
---
|
||||||
|
Lib/test/test_urlparse.py | 26 +++++++++++++++++++
|
||||||
|
Lib/urllib/parse.py | 15 +++++++++++
|
||||||
|
...-04-26-09-54-25.gh-issue-103848.aDSnpR.rst | 2 ++
|
||||||
|
3 files changed, 43 insertions(+)
|
||||||
|
create mode 100644 Misc/NEWS.d/next/Library/2023-04-26-09-54-25.gh-issue-103848.aDSnpR.rst
|
||||||
|
|
||||||
|
diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py
|
||||||
|
index 7fd61ffea9..090d2f17bf 100644
|
||||||
|
--- a/Lib/test/test_urlparse.py
|
||||||
|
+++ b/Lib/test/test_urlparse.py
|
||||||
|
@@ -1076,6 +1076,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]/path?query')
|
||||||
|
+ self.assertEqual(p2.hostname, '0439:23af:2309::fae7')
|
||||||
|
+ 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]/path?query')
|
||||||
|
+ self.assertEqual(p3.hostname, '0439:23af:2309::fae7:1234:192.0.2.146')
|
||||||
|
+ self.assertEqual(p3.username, 'user')
|
||||||
|
+ self.assertEqual(p3.path, '/path')
|
||||||
|
+
|
||||||
|
def test_telurl_params(self):
|
||||||
|
p1 = urllib.parse.urlparse('tel:123-4;phone-context=+1-650-516')
|
||||||
|
self.assertEqual(p1.scheme, 'tel')
|
||||||
|
diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py
|
||||||
|
index 717e990997..bf186b7984 100644
|
||||||
|
--- a/Lib/urllib/parse.py
|
||||||
|
+++ b/Lib/urllib/parse.py
|
||||||
|
@@ -34,6 +34,7 @@ It serves as a useful guide when making changes.
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import collections
|
||||||
|
+import ipaddress
|
||||||
|
|
||||||
|
__all__ = ["urlparse", "urlunparse", "urljoin", "urldefrag",
|
||||||
|
"urlsplit", "urlunsplit", "urlencode", "parse_qs",
|
||||||
|
@@ -425,6 +426,17 @@ def _remove_unsafe_bytes_from_url(url):
|
||||||
|
url = url.replace(b, "")
|
||||||
|
return url
|
||||||
|
|
||||||
|
+# 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>
|
||||||
|
@@ -480,6 +492,9 @@ def urlsplit(url, scheme='', allow_fragments=True):
|
||||||
|
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:
|
||||||
|
diff --git a/Misc/NEWS.d/next/Library/2023-04-26-09-54-25.gh-issue-103848.aDSnpR.rst b/Misc/NEWS.d/next/Library/2023-04-26-09-54-25.gh-issue-103848.aDSnpR.rst
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..81e5904aa6
|
||||||
|
--- /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.
|
||||||
1783
SOURCES/00465-tarfile-cves.patch
Normal file
1783
SOURCES/00465-tarfile-cves.patch
Normal file
File diff suppressed because it is too large
Load Diff
215
SOURCES/00467-tarfile-cve-2025-8194.patch
Normal file
215
SOURCES/00467-tarfile-cve-2025-8194.patch
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
From 738482c8b9a8a8f3ccdb678ad508a86d702a6751 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lumir Balhar <lbalhar@redhat.com>
|
||||||
|
Date: Mon, 11 Aug 2025 13:39:27 +0200
|
||||||
|
Subject: [PATCH] 00467: tarfile CVE-2025-8194
|
||||||
|
|
||||||
|
tarfile now validates archives to ensure member offsets are non-negative (GH-137027)
|
||||||
|
|
||||||
|
Co-authored-by: Gregory P. Smith <greg@krypto.org>
|
||||||
|
---
|
||||||
|
Lib/tarfile.py | 3 +
|
||||||
|
Lib/test/test_tarfile.py | 156 ++++++++++++++++++
|
||||||
|
...-07-23-00-35-29.gh-issue-130577.c7EITy.rst | 3 +
|
||||||
|
3 files changed, 162 insertions(+)
|
||||||
|
create mode 100644 Misc/NEWS.d/next/Library/2025-07-23-00-35-29.gh-issue-130577.c7EITy.rst
|
||||||
|
|
||||||
|
diff --git a/Lib/tarfile.py b/Lib/tarfile.py
|
||||||
|
index 7d94b5c..3e03ebf 100755
|
||||||
|
--- a/Lib/tarfile.py
|
||||||
|
+++ b/Lib/tarfile.py
|
||||||
|
@@ -1589,6 +1589,9 @@ class TarInfo(object):
|
||||||
|
"""Round up a byte count by BLOCKSIZE and return it,
|
||||||
|
e.g. _block(834) => 1024.
|
||||||
|
"""
|
||||||
|
+ # Only non-negative offsets are allowed
|
||||||
|
+ if count < 0:
|
||||||
|
+ raise InvalidHeaderError("invalid offset")
|
||||||
|
blocks, remainder = divmod(count, BLOCKSIZE)
|
||||||
|
if remainder:
|
||||||
|
blocks += 1
|
||||||
|
diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py
|
||||||
|
index 01da819..0a7586a 100644
|
||||||
|
--- a/Lib/test/test_tarfile.py
|
||||||
|
+++ b/Lib/test/test_tarfile.py
|
||||||
|
@@ -43,6 +43,7 @@ bz2name = os.path.join(TEMPDIR, "testtar.tar.bz2")
|
||||||
|
xzname = os.path.join(TEMPDIR, "testtar.tar.xz")
|
||||||
|
tmpname = os.path.join(TEMPDIR, "tmp.tar")
|
||||||
|
dotlessname = os.path.join(TEMPDIR, "testtar")
|
||||||
|
+SPACE = b" "
|
||||||
|
|
||||||
|
sha256_regtype = (
|
||||||
|
"e09e4bc8b3c9d9177e77256353b36c159f5f040531bbd4b024a8f9b9196c71ce"
|
||||||
|
@@ -4018,6 +4019,161 @@ class TestExtractionFilters(unittest.TestCase):
|
||||||
|
self.check_trusted_default(tar, tempdir)
|
||||||
|
|
||||||
|
|
||||||
|
+class OffsetValidationTests(unittest.TestCase):
|
||||||
|
+ tarname = tmpname
|
||||||
|
+ invalid_posix_header = (
|
||||||
|
+ # name: 100 bytes
|
||||||
|
+ tarfile.NUL * tarfile.LENGTH_NAME
|
||||||
|
+ # mode, space, null terminator: 8 bytes
|
||||||
|
+ + b"000755" + SPACE + tarfile.NUL
|
||||||
|
+ # uid, space, null terminator: 8 bytes
|
||||||
|
+ + b"000001" + SPACE + tarfile.NUL
|
||||||
|
+ # gid, space, null terminator: 8 bytes
|
||||||
|
+ + b"000001" + SPACE + tarfile.NUL
|
||||||
|
+ # size, space: 12 bytes
|
||||||
|
+ + b"\xff" * 11 + SPACE
|
||||||
|
+ # mtime, space: 12 bytes
|
||||||
|
+ + tarfile.NUL * 11 + SPACE
|
||||||
|
+ # chksum: 8 bytes
|
||||||
|
+ + b"0011407" + tarfile.NUL
|
||||||
|
+ # type: 1 byte
|
||||||
|
+ + tarfile.REGTYPE
|
||||||
|
+ # linkname: 100 bytes
|
||||||
|
+ + tarfile.NUL * tarfile.LENGTH_LINK
|
||||||
|
+ # magic: 6 bytes, version: 2 bytes
|
||||||
|
+ + tarfile.POSIX_MAGIC
|
||||||
|
+ # uname: 32 bytes
|
||||||
|
+ + tarfile.NUL * 32
|
||||||
|
+ # gname: 32 bytes
|
||||||
|
+ + tarfile.NUL * 32
|
||||||
|
+ # devmajor, space, null terminator: 8 bytes
|
||||||
|
+ + tarfile.NUL * 6 + SPACE + tarfile.NUL
|
||||||
|
+ # devminor, space, null terminator: 8 bytes
|
||||||
|
+ + tarfile.NUL * 6 + SPACE + tarfile.NUL
|
||||||
|
+ # prefix: 155 bytes
|
||||||
|
+ + tarfile.NUL * tarfile.LENGTH_PREFIX
|
||||||
|
+ # padding: 12 bytes
|
||||||
|
+ + tarfile.NUL * 12
|
||||||
|
+ )
|
||||||
|
+ invalid_gnu_header = (
|
||||||
|
+ # name: 100 bytes
|
||||||
|
+ tarfile.NUL * tarfile.LENGTH_NAME
|
||||||
|
+ # mode, null terminator: 8 bytes
|
||||||
|
+ + b"0000755" + tarfile.NUL
|
||||||
|
+ # uid, null terminator: 8 bytes
|
||||||
|
+ + b"0000001" + tarfile.NUL
|
||||||
|
+ # gid, space, null terminator: 8 bytes
|
||||||
|
+ + b"0000001" + tarfile.NUL
|
||||||
|
+ # size, space: 12 bytes
|
||||||
|
+ + b"\xff" * 11 + SPACE
|
||||||
|
+ # mtime, space: 12 bytes
|
||||||
|
+ + tarfile.NUL * 11 + SPACE
|
||||||
|
+ # chksum: 8 bytes
|
||||||
|
+ + b"0011327" + tarfile.NUL
|
||||||
|
+ # type: 1 byte
|
||||||
|
+ + tarfile.REGTYPE
|
||||||
|
+ # linkname: 100 bytes
|
||||||
|
+ + tarfile.NUL * tarfile.LENGTH_LINK
|
||||||
|
+ # magic: 8 bytes
|
||||||
|
+ + tarfile.GNU_MAGIC
|
||||||
|
+ # uname: 32 bytes
|
||||||
|
+ + tarfile.NUL * 32
|
||||||
|
+ # gname: 32 bytes
|
||||||
|
+ + tarfile.NUL * 32
|
||||||
|
+ # devmajor, null terminator: 8 bytes
|
||||||
|
+ + tarfile.NUL * 8
|
||||||
|
+ # devminor, null terminator: 8 bytes
|
||||||
|
+ + tarfile.NUL * 8
|
||||||
|
+ # padding: 167 bytes
|
||||||
|
+ + tarfile.NUL * 167
|
||||||
|
+ )
|
||||||
|
+ invalid_v7_header = (
|
||||||
|
+ # name: 100 bytes
|
||||||
|
+ tarfile.NUL * tarfile.LENGTH_NAME
|
||||||
|
+ # mode, space, null terminator: 8 bytes
|
||||||
|
+ + b"000755" + SPACE + tarfile.NUL
|
||||||
|
+ # uid, space, null terminator: 8 bytes
|
||||||
|
+ + b"000001" + SPACE + tarfile.NUL
|
||||||
|
+ # gid, space, null terminator: 8 bytes
|
||||||
|
+ + b"000001" + SPACE + tarfile.NUL
|
||||||
|
+ # size, space: 12 bytes
|
||||||
|
+ + b"\xff" * 11 + SPACE
|
||||||
|
+ # mtime, space: 12 bytes
|
||||||
|
+ + tarfile.NUL * 11 + SPACE
|
||||||
|
+ # chksum: 8 bytes
|
||||||
|
+ + b"0010070" + tarfile.NUL
|
||||||
|
+ # type: 1 byte
|
||||||
|
+ + tarfile.REGTYPE
|
||||||
|
+ # linkname: 100 bytes
|
||||||
|
+ + tarfile.NUL * tarfile.LENGTH_LINK
|
||||||
|
+ # padding: 255 bytes
|
||||||
|
+ + tarfile.NUL * 255
|
||||||
|
+ )
|
||||||
|
+ valid_gnu_header = tarfile.TarInfo("filename").tobuf(tarfile.GNU_FORMAT)
|
||||||
|
+ data_block = b"\xff" * tarfile.BLOCKSIZE
|
||||||
|
+
|
||||||
|
+ def _write_buffer(self, buffer):
|
||||||
|
+ with open(self.tarname, "wb") as f:
|
||||||
|
+ f.write(buffer)
|
||||||
|
+
|
||||||
|
+ def _get_members(self, ignore_zeros=None):
|
||||||
|
+ with open(self.tarname, "rb") as f:
|
||||||
|
+ with tarfile.open(
|
||||||
|
+ mode="r", fileobj=f, ignore_zeros=ignore_zeros
|
||||||
|
+ ) as tar:
|
||||||
|
+ return tar.getmembers()
|
||||||
|
+
|
||||||
|
+ def _assert_raises_read_error_exception(self):
|
||||||
|
+ with self.assertRaisesRegex(
|
||||||
|
+ tarfile.ReadError, "file could not be opened successfully"
|
||||||
|
+ ):
|
||||||
|
+ self._get_members()
|
||||||
|
+
|
||||||
|
+ def test_invalid_offset_header_validations(self):
|
||||||
|
+ for tar_format, invalid_header in (
|
||||||
|
+ ("posix", self.invalid_posix_header),
|
||||||
|
+ ("gnu", self.invalid_gnu_header),
|
||||||
|
+ ("v7", self.invalid_v7_header),
|
||||||
|
+ ):
|
||||||
|
+ with self.subTest(format=tar_format):
|
||||||
|
+ self._write_buffer(invalid_header)
|
||||||
|
+ self._assert_raises_read_error_exception()
|
||||||
|
+
|
||||||
|
+ def test_early_stop_at_invalid_offset_header(self):
|
||||||
|
+ buffer = self.valid_gnu_header + self.invalid_gnu_header + self.valid_gnu_header
|
||||||
|
+ self._write_buffer(buffer)
|
||||||
|
+ members = self._get_members()
|
||||||
|
+ self.assertEqual(len(members), 1)
|
||||||
|
+ self.assertEqual(members[0].name, "filename")
|
||||||
|
+ self.assertEqual(members[0].offset, 0)
|
||||||
|
+
|
||||||
|
+ def test_ignore_invalid_archive(self):
|
||||||
|
+ # 3 invalid headers with their respective data
|
||||||
|
+ buffer = (self.invalid_gnu_header + self.data_block) * 3
|
||||||
|
+ self._write_buffer(buffer)
|
||||||
|
+ members = self._get_members(ignore_zeros=True)
|
||||||
|
+ self.assertEqual(len(members), 0)
|
||||||
|
+
|
||||||
|
+ def test_ignore_invalid_offset_headers(self):
|
||||||
|
+ for first_block, second_block, expected_offset in (
|
||||||
|
+ (
|
||||||
|
+ (self.valid_gnu_header),
|
||||||
|
+ (self.invalid_gnu_header + self.data_block),
|
||||||
|
+ 0,
|
||||||
|
+ ),
|
||||||
|
+ (
|
||||||
|
+ (self.invalid_gnu_header + self.data_block),
|
||||||
|
+ (self.valid_gnu_header),
|
||||||
|
+ 1024,
|
||||||
|
+ ),
|
||||||
|
+ ):
|
||||||
|
+ self._write_buffer(first_block + second_block)
|
||||||
|
+ members = self._get_members(ignore_zeros=True)
|
||||||
|
+ self.assertEqual(len(members), 1)
|
||||||
|
+ self.assertEqual(members[0].name, "filename")
|
||||||
|
+ self.assertEqual(members[0].offset, expected_offset)
|
||||||
|
+
|
||||||
|
+
|
||||||
|
def setUpModule():
|
||||||
|
support.unlink(TEMPDIR)
|
||||||
|
os.makedirs(TEMPDIR)
|
||||||
|
diff --git a/Misc/NEWS.d/next/Library/2025-07-23-00-35-29.gh-issue-130577.c7EITy.rst b/Misc/NEWS.d/next/Library/2025-07-23-00-35-29.gh-issue-130577.c7EITy.rst
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..342cabb
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/Misc/NEWS.d/next/Library/2025-07-23-00-35-29.gh-issue-130577.c7EITy.rst
|
||||||
|
@@ -0,0 +1,3 @@
|
||||||
|
+:mod:`tarfile` now validates archives to ensure member offsets are
|
||||||
|
+non-negative. (Contributed by Alexander Enrique Urieles Nieto in
|
||||||
|
+:gh:`130577`.)
|
||||||
|
--
|
||||||
|
2.50.1
|
||||||
|
|
||||||
@ -14,7 +14,7 @@ URL: https://www.python.org/
|
|||||||
# WARNING When rebasing to a new Python version,
|
# WARNING When rebasing to a new Python version,
|
||||||
# remember to update the python3-docs package as well
|
# remember to update the python3-docs package as well
|
||||||
Version: %{pybasever}.8
|
Version: %{pybasever}.8
|
||||||
Release: 67%{?dist}
|
Release: 71%{?dist}
|
||||||
License: Python
|
License: Python
|
||||||
|
|
||||||
|
|
||||||
@ -904,6 +904,43 @@ Patch435: 00435-cve-2024-6923.patch
|
|||||||
# Cherry-picked from 3.8.
|
# Cherry-picked from 3.8.
|
||||||
Patch437: 00437-cve-2024-6232.patch
|
Patch437: 00437-cve-2024-6232.patch
|
||||||
|
|
||||||
|
# 00443 # 49e939f29e3551ec4e7bdb2cc8b8745e3d1fca35
|
||||||
|
# gh-124651: Quote template strings in `venv` activation scripts
|
||||||
|
#
|
||||||
|
# (cherry picked from 3.9)
|
||||||
|
Patch443: 00443-gh-124651-quote-template-strings-in-venv-activation-scripts.patch
|
||||||
|
|
||||||
|
# 00444 # fed0071c8c86599091f93967a5fa2cce42ceb840
|
||||||
|
# Security fix for CVE-2024-11168
|
||||||
|
#
|
||||||
|
# gh-103848: Adds checks to ensure that bracketed hosts found by urlsplit are of IPv6 or IPvFuture format (GH-103849)
|
||||||
|
#
|
||||||
|
# Tests are adjusted because Python <3.9 don't support scoped IPv6 addresses.
|
||||||
|
Patch444: 00444-security-fix-for-cve-2024-11168.patch
|
||||||
|
|
||||||
|
# 00465 #
|
||||||
|
# Security fixes for CVE-2025-4517, CVE-2025-4330, CVE-2025-4138, CVE-2024-12718, CVE-2025-4435 on tarfile
|
||||||
|
#
|
||||||
|
# The backported fixes do not contain changes for ntpath.py and related tests,
|
||||||
|
# because the support for symlinks and junctions were added later in Python 3.9,
|
||||||
|
# and it does not make sense to backport them to 3.6 here.
|
||||||
|
#
|
||||||
|
# The patch consist of the following commits:
|
||||||
|
# - https://github.com/python/cpython/commit/9d2c2a8e3b8fe18ee1568bfa4a419847b3e78575
|
||||||
|
# fixes handling of existing files/symlinks in tarfile
|
||||||
|
# - https://github.com/python/cpython/commit/00af9794dd118f7b835dd844b2b609a503ad951e
|
||||||
|
# adds a new "strict" argument to realpath()
|
||||||
|
# - https://github.com/python/cpython/commit/dd8f187d0746da151e0025c51680979ac5b4cfb1
|
||||||
|
# fixes multiple CVE fixes in the tarfile module
|
||||||
|
# - downstream only patch that makes the changes work and compatible with Python 3.6
|
||||||
|
Patch465: 00465-tarfile-cves.patch
|
||||||
|
|
||||||
|
# 00467 #
|
||||||
|
# tarfile CVE-2025-8194
|
||||||
|
#
|
||||||
|
# tarfile now validates archives to ensure member offsets are non-negative (GH-137027)
|
||||||
|
Patch467: 00467-tarfile-cve-2025-8194.patch
|
||||||
|
|
||||||
# (New patches go here ^^^)
|
# (New patches go here ^^^)
|
||||||
#
|
#
|
||||||
# When adding new patches to "python" and "python3" in Fedora, EL, etc.,
|
# When adding new patches to "python" and "python3" in Fedora, EL, etc.,
|
||||||
@ -1235,7 +1272,7 @@ rm Lib/ensurepip/_bundled/*.whl
|
|||||||
%patch346 -p1
|
%patch346 -p1
|
||||||
|
|
||||||
# Patch 351 adds binary file for testing. We need to apply it using Git.
|
# Patch 351 adds binary file for testing. We need to apply it using Git.
|
||||||
git apply %{PATCH351}
|
GIT_DIR=$PWD git apply %{PATCH351}
|
||||||
|
|
||||||
%patch352 -p1
|
%patch352 -p1
|
||||||
%patch353 -p1
|
%patch353 -p1
|
||||||
@ -1271,6 +1308,10 @@ git apply %{PATCH351}
|
|||||||
%patch431 -p1
|
%patch431 -p1
|
||||||
%patch435 -p1
|
%patch435 -p1
|
||||||
%patch437 -p1
|
%patch437 -p1
|
||||||
|
%patch443 -p1
|
||||||
|
%patch444 -p1
|
||||||
|
%patch465 -p1
|
||||||
|
%patch467 -p1
|
||||||
|
|
||||||
# Remove files that should be generated by the build
|
# Remove files that should be generated by the build
|
||||||
# (This is after patching, so that we can use patches directly from upstream)
|
# (This is after patching, so that we can use patches directly from upstream)
|
||||||
@ -2202,6 +2243,22 @@ fi
|
|||||||
# ======================================================
|
# ======================================================
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Aug 11 2025 Lumír Balhar <lbalhar@redhat.com> - 3.6.8-71
|
||||||
|
- Security fix for CVE-2025-8194
|
||||||
|
Resolves: RHEL-106333
|
||||||
|
|
||||||
|
* Tue Jun 24 2025 Lumír Balhar <lbalhar@redhat.com> - 3.6.8-70
|
||||||
|
- Security fixes for CVE-2025-4517, CVE-2025-4330, CVE-2025-4138, CVE-2024-12718, CVE-2025-4435
|
||||||
|
Resolves: RHEL-98030, RHEL-97987, RHEL-98232, RHEL-98065, RHEL-98189
|
||||||
|
|
||||||
|
* Thu Nov 14 2024 Lumír Balhar <lbalhar@redhat.com> - 3.6.8-69
|
||||||
|
- Security fix for CVE-2024-11168
|
||||||
|
Resolves: RHEL-67252
|
||||||
|
|
||||||
|
* Tue Nov 05 2024 Lumír Balhar <lbalhar@redhat.com> - 3.6.8-68
|
||||||
|
- Security fix for CVE-2024-9287
|
||||||
|
Resolves: RHEL-64878
|
||||||
|
|
||||||
* Thu Sep 05 2024 Lumír Balhar <lbalhar@redhat.com> - 3.6.8-67
|
* Thu Sep 05 2024 Lumír Balhar <lbalhar@redhat.com> - 3.6.8-67
|
||||||
- Security fix for CVE-2024-6232
|
- Security fix for CVE-2024-6232
|
||||||
Resolves: RHEL-57399
|
Resolves: RHEL-57399
|
||||||
@ -1,6 +0,0 @@
|
|||||||
--- !Policy
|
|
||||||
product_versions:
|
|
||||||
- rhel-8
|
|
||||||
decision_context: osci_compose_gate
|
|
||||||
rules:
|
|
||||||
- !PassingTestCaseRule {test_case_name: baseos-ci.brew-build.tier1.functional}
|
|
||||||
@ -1,67 +0,0 @@
|
|||||||
# KNOWN BUGS:
|
|
||||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1489816
|
|
||||||
addFilter(r'crypto-policy-non-compliance-openssl')
|
|
||||||
|
|
||||||
|
|
||||||
# TESTS:
|
|
||||||
addFilter(r'(zero-length|pem-certificate|uncompressed-zip) /usr/lib(64)?/python3.\d/test')
|
|
||||||
|
|
||||||
|
|
||||||
# OTHER DELIBERATES:
|
|
||||||
# chroot function
|
|
||||||
addFilter(r'missing-call-to-chdir-with-chroot')
|
|
||||||
|
|
||||||
# intentionally unversioned and selfobsoleted
|
|
||||||
addFilter(r'unversioned-explicit-obsoletes python')
|
|
||||||
addFilter(r'self-obsoletion python3\d obsoletes python3\d')
|
|
||||||
|
|
||||||
# intentionally hardcoded
|
|
||||||
addFilter(r'hardcoded-library-path in %{_prefix}/lib/(debug/%{_libdir}|python%{pybasever})')
|
|
||||||
|
|
||||||
# we have non binary stuff, python files
|
|
||||||
addFilter(r'only-non-binary-in-usr-lib')
|
|
||||||
|
|
||||||
# some devel files that are deliberately needed
|
|
||||||
addFilter(r'devel-file-in-non-devel-package /usr/include/python3\.\dm/pyconfig-(32|64)\.h')
|
|
||||||
addFilter(r'devel-file-in-non-devel-package /usr/lib64/python3\.\d/distutils/tests/xxmodule\.c')
|
|
||||||
|
|
||||||
|
|
||||||
# SORRY, NOT SORRY:
|
|
||||||
# manual pages
|
|
||||||
addFilter(r'no-manual-page-for-binary (idle|pydoc|pyvenv|2to3|python3-debug|pathfix\.py)')
|
|
||||||
addFilter(r'no-manual-page-for-binary python3.*-config$')
|
|
||||||
addFilter(r'no-manual-page-for-binary python3.\dd?m$')
|
|
||||||
|
|
||||||
# missing documentation from subpackages
|
|
||||||
addFilter(r'^python3\d?-(debug|tkinter|test|idle)\.[^:]+: (E|W): no-documentation')
|
|
||||||
|
|
||||||
# platform python is obsoleted, but not provided
|
|
||||||
addFilter(r'obsolete-not-provided platform-python')
|
|
||||||
|
|
||||||
|
|
||||||
# RPMLINT IMPERFECTIONS:
|
|
||||||
# ifarch applied patches are OK
|
|
||||||
# https://fedoraproject.org/wiki/Packaging:Guidelines#Architecture_Support
|
|
||||||
addFilter(r'%ifarch-applied-patch')
|
|
||||||
|
|
||||||
# debugsource
|
|
||||||
addFilter(r'^python3\d?-debugsource\.[^:]+: (E|W): no-documentation')
|
|
||||||
|
|
||||||
# debuginfo
|
|
||||||
addFilter(r'^python3\d?-debuginfo\.[^:]+: (E|W): useless-provides debuginfo\(build-id\)')
|
|
||||||
|
|
||||||
# this is OK for F28+
|
|
||||||
addFilter(r'library-without-ldconfig-post')
|
|
||||||
|
|
||||||
# debug package contains devel and non-devel files
|
|
||||||
addFilter(r'python3\d?-debug.[^:]+: (E|W): (non-)?devel-file-in-(non-)?devel-package')
|
|
||||||
|
|
||||||
# this goes to other subpackage, hence not actually dangling, the read error is bogus
|
|
||||||
addFilter(r'dangling-relative-symlink /usr/lib(64)?/pkgconfig/python-3\.\ddm\.pc python-3\.\d\.pc')
|
|
||||||
addFilter(r'read-error /usr/lib(64)?/pkgconfig/python-3\.\ddm\.pc \[Errno 2\]')
|
|
||||||
|
|
||||||
# we need this macro to evaluate, even if the line starts with #
|
|
||||||
addFilter(r'macro-in-comment %\{_pyconfig(32|64)_h\}')
|
|
||||||
|
|
||||||
# SPELLING ERRORS
|
|
||||||
addFilter(r'spelling-error .* en_US (bytecode|pyc|filename|tkinter|namespaces|pytest) ')
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
# exclude test XML data (not always valid) from XML validity check:
|
|
||||||
xml:
|
|
||||||
ignore:
|
|
||||||
- /usr/lib*/python*/test/xmltestdata/*
|
|
||||||
- /usr/lib*/python*/test/xmltestdata/*/*
|
|
||||||
|
|
||||||
# exclude _socket from ipv4 only functions check, it has both ipv4 and ipv6 only
|
|
||||||
badfuncs:
|
|
||||||
allowed:
|
|
||||||
/usr/lib*/python*/lib-dynload/_socket.*:
|
|
||||||
- inet_aton
|
|
||||||
- inet_ntoa
|
|
||||||
|
|
||||||
# exclude the debug build from annocheck entirely
|
|
||||||
annocheck:
|
|
||||||
ignore:
|
|
||||||
- /usr/bin/python*d
|
|
||||||
- /usr/lib*/libpython*d.so.1.0
|
|
||||||
- /usr/lib*/python*/lib-dynload/*.cpython-*d-*-*-*.so
|
|
||||||
|
|
||||||
# don't report changed content of compiled files
|
|
||||||
# that is expected with every toolchain update and not reproducible yet
|
|
||||||
changedfiles:
|
|
||||||
# note that this is a posix regex, so no \d
|
|
||||||
exclude_path: (\.so(\.[0-9]+(\.[0-9]+)?)?$|^/usr/bin/python[0-9]+\.[0-9]+d?m?$)
|
|
||||||
|
|
||||||
# files change size all the time, we don't need to VERIFY it
|
|
||||||
# however, the INFO is useful, so we don't disable the check entirely
|
|
||||||
filesize:
|
|
||||||
# artificially large number, TODO a better way
|
|
||||||
size_threshold: 100000
|
|
||||||
|
|
||||||
debuginfo:
|
|
||||||
ignore:
|
|
||||||
# libpython3.so doesn't contain compiled code
|
|
||||||
- /usr/lib/debug/usr/lib*/libpython3.so*debug
|
|
||||||
|
|
||||||
# completely disabled inspections:
|
|
||||||
inspections:
|
|
||||||
# we know about our patches, no need to report anything
|
|
||||||
patches: off
|
|
||||||
Loading…
Reference in New Issue
Block a user