diff --git a/SPECS/python3/CVE-2024-9287.patch b/SPECS/python3/CVE-2024-9287.patch new file mode 100644 index 00000000000..ad5a87ab700 --- /dev/null +++ b/SPECS/python3/CVE-2024-9287.patch @@ -0,0 +1,343 @@ +From 697b53a06eca774b496190be50dc5879984b407f Mon Sep 17 00:00:00 2001 +From: Saul Paredes +Date: Wed, 6 Nov 2024 16:43:27 -0800 +Subject: [PATCH] python3: patch CVE-2024-9287 + +Adapted from https://github.com/python/cpython/commit/8450b2482586857d689b6658f08de9c8179af7db (fixed whitespaces) + +Signed-off-by: Saul Paredes +--- + Lib/test/test_venv.py | 81 +++++++++++++++++++ + Lib/venv/__init__.py | 42 ++++++++-- + Lib/venv/scripts/common/activate | 10 +-- + Lib/venv/scripts/nt/activate.bat | 30 +++---- + 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 + + 7 files changed, 147 insertions(+), 33 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 2f44176..e01cf03 100644 +--- a/Lib/test/test_venv.py ++++ b/Lib/test/test_venv.py +@@ -17,6 +17,7 @@ import subprocess + import sys + import sysconfig + import tempfile ++import shlex + from test.support import (captured_stdout, captured_stderr, + skip_if_broken_multiprocessing_synchronize, verbose, + requires_subprocess, is_emscripten, is_wasi, +@@ -96,6 +97,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.""" + +@@ -445,6 +450,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 2173c9b..53486d5 100644 +--- 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',) +@@ -395,11 +396,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): +@@ -439,6 +470,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) +diff --git a/Lib/venv/scripts/common/activate b/Lib/venv/scripts/common/activate +index d5914e0..47602ca 100644 +--- a/Lib/venv/scripts/common/activate ++++ b/Lib/venv/scripts/common/activate +@@ -39,14 +39,14 @@ deactivate nondestructive + if [ "${OSTYPE:-}" = "cygwin" ] || [ "${OSTYPE:-}" = "msys" ] ; then + # transform D:\path\to\venv to /d/path/to/venv on MSYS + # and to /cygdrive/d/path/to/venv on Cygwin +- export VIRTUAL_ENV=$(cygpath "__VENV_DIR__") ++ export VIRTUAL_ENV=$(cygpath __VENV_DIR__) + else + # use the path as-is +- export VIRTUAL_ENV="__VENV_DIR__" ++ export VIRTUAL_ENV=__VENV_DIR__ + fi + + _OLD_VIRTUAL_PATH="$PATH" +-PATH="$VIRTUAL_ENV/__VENV_BIN_NAME__:$PATH" ++PATH="$VIRTUAL_ENV/"__VENV_BIN_NAME__":$PATH" + export PATH + + # unset PYTHONHOME if set +@@ -59,9 +59,9 @@ fi + + if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then + _OLD_VIRTUAL_PS1="${PS1:-}" +- PS1="__VENV_PROMPT__${PS1:-}" ++ PS1=__VENV_PROMPT__"${PS1:-}" + export PS1 +- VIRTUAL_ENV_PROMPT="__VENV_PROMPT__" ++ VIRTUAL_ENV_PROMPT=__VENV_PROMPT__ + export VIRTUAL_ENV_PROMPT + fi + +diff --git a/Lib/venv/scripts/nt/activate.bat b/Lib/venv/scripts/nt/activate.bat +index 5daa45a..0b3e583 100644 +--- a/Lib/venv/scripts/nt/activate.bat ++++ b/Lib/venv/scripts/nt/activate.bat +@@ -5,13 +5,13 @@ for /f "tokens=2 delims=:." %%a in ('"%SystemRoot%\System32\chcp.com"') do ( + set _OLD_CODEPAGE=%%a + ) + if defined _OLD_CODEPAGE ( +- "%SystemRoot%\System32\chcp.com" 65001 > nul +-) +- +-set VIRTUAL_ENV=__VENV_DIR__ +- +-if not defined PROMPT set PROMPT=$P$G +- ++ "%SystemRoot%\System32\chcp.com" 65001 > nul ++) ++ ++set "VIRTUAL_ENV=__VENV_DIR__" ++ ++if not defined PROMPT set PROMPT=$P$G ++ + if defined _OLD_VIRTUAL_PROMPT set PROMPT=%_OLD_VIRTUAL_PROMPT% + if defined _OLD_VIRTUAL_PYTHONHOME set PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME% + +@@ -21,14 +21,14 @@ set PROMPT=__VENV_PROMPT__%PROMPT% + if defined PYTHONHOME set _OLD_VIRTUAL_PYTHONHOME=%PYTHONHOME% + 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 VIRTUAL_ENV_PROMPT=__VENV_PROMPT__ +- +-:END +-if defined _OLD_CODEPAGE ( ++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 "VIRTUAL_ENV_PROMPT=__VENV_PROMPT__" ++ ++:END ++if defined _OLD_CODEPAGE ( + "%SystemRoot%\System32\chcp.com" %_OLD_CODEPAGE% > nul + set _OLD_CODEPAGE= + ) +diff --git a/Lib/venv/scripts/posix/activate.csh b/Lib/venv/scripts/posix/activate.csh +index 5e8d66f..08f7929 100644 +--- a/Lib/venv/scripts/posix/activate.csh ++++ b/Lib/venv/scripts/posix/activate.csh +@@ -9,17 +9,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 +- set prompt = "__VENV_PROMPT__$prompt" +- setenv VIRTUAL_ENV_PROMPT "__VENV_PROMPT__" ++ set prompt = __VENV_PROMPT__"$prompt" ++ setenv VIRTUAL_ENV_PROMPT __VENV_PROMPT__ + endif + + alias pydoc python -m pydoc +diff --git a/Lib/venv/scripts/posix/activate.fish b/Lib/venv/scripts/posix/activate.fish +index 91ad644..508cab0 100644 +--- a/Lib/venv/scripts/posix/activate.fish ++++ b/Lib/venv/scripts/posix/activate.fish +@@ -33,10 +33,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 +@@ -56,7 +56,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" | . +@@ -65,5 +65,5 @@ if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" + end + + set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" +- set -gx VIRTUAL_ENV_PROMPT "__VENV_PROMPT__" ++ set -gx VIRTUAL_ENV_PROMPT __VENV_PROMPT__ + end +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 0000000..17fc917 +--- /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. +-- +2.25.1 + diff --git a/SPECS/python3/python3.spec b/SPECS/python3/python3.spec index 50058cdc7d0..805ff917c04 100644 --- a/SPECS/python3/python3.spec +++ b/SPECS/python3/python3.spec @@ -6,7 +6,7 @@ Summary: A high-level scripting language Name: python3 Version: 3.12.3 -Release: 4%{?dist} +Release: 5%{?dist} License: PSF Vendor: Microsoft Corporation Distribution: Azure Linux @@ -21,6 +21,7 @@ Patch1: CVE-2024-7592.patch Patch2: CVE-2024-6923.patch Patch3: CVE-2024-6232.patch Patch4: CVE-2024-8088.patch +Patch5: CVE-2024-9287.patch BuildRequires: bzip2-devel BuildRequires: expat-devel >= 2.1.0 @@ -242,6 +243,9 @@ rm -rf %{buildroot}%{_bindir}/__pycache__ %{_libdir}/python%{majmin}/test/* %changelog +* Wed Nov 6 2024 Saul Paredes - 3.12.3-5 +- Patch CVE-2024-9287 + * Fri Sep 20 2024 Himaja Kesari - 3.12.3-4 - Patch CVE-2024-6232 and CVE-2024-8088 diff --git a/toolkit/resources/manifests/package/pkggen_core_aarch64.txt b/toolkit/resources/manifests/package/pkggen_core_aarch64.txt index 9d525530102..262f912915c 100644 --- a/toolkit/resources/manifests/package/pkggen_core_aarch64.txt +++ b/toolkit/resources/manifests/package/pkggen_core_aarch64.txt @@ -240,9 +240,9 @@ ca-certificates-base-3.0.0-7.azl3.noarch.rpm ca-certificates-3.0.0-7.azl3.noarch.rpm dwz-0.14-2.azl3.aarch64.rpm unzip-6.0-20.azl3.aarch64.rpm -python3-3.12.3-4.azl3.aarch64.rpm -python3-devel-3.12.3-4.azl3.aarch64.rpm -python3-libs-3.12.3-4.azl3.aarch64.rpm +python3-3.12.3-5.azl3.aarch64.rpm +python3-devel-3.12.3-5.azl3.aarch64.rpm +python3-libs-3.12.3-5.azl3.aarch64.rpm python3-setuptools-69.0.3-4.azl3.noarch.rpm python3-pygments-2.7.4-2.azl3.noarch.rpm which-2.21-8.azl3.aarch64.rpm diff --git a/toolkit/resources/manifests/package/pkggen_core_x86_64.txt b/toolkit/resources/manifests/package/pkggen_core_x86_64.txt index 2cc91b471c6..5c80d145bce 100644 --- a/toolkit/resources/manifests/package/pkggen_core_x86_64.txt +++ b/toolkit/resources/manifests/package/pkggen_core_x86_64.txt @@ -240,9 +240,9 @@ ca-certificates-base-3.0.0-7.azl3.noarch.rpm ca-certificates-3.0.0-7.azl3.noarch.rpm dwz-0.14-2.azl3.x86_64.rpm unzip-6.0-20.azl3.x86_64.rpm -python3-3.12.3-4.azl3.x86_64.rpm -python3-devel-3.12.3-4.azl3.x86_64.rpm -python3-libs-3.12.3-4.azl3.x86_64.rpm +python3-3.12.3-5.azl3.x86_64.rpm +python3-devel-3.12.3-5.azl3.x86_64.rpm +python3-libs-3.12.3-5.azl3.x86_64.rpm python3-setuptools-69.0.3-4.azl3.noarch.rpm python3-pygments-2.7.4-2.azl3.noarch.rpm which-2.21-8.azl3.x86_64.rpm diff --git a/toolkit/resources/manifests/package/toolchain_aarch64.txt b/toolkit/resources/manifests/package/toolchain_aarch64.txt index d6aad71ae70..f05f5c8432b 100644 --- a/toolkit/resources/manifests/package/toolchain_aarch64.txt +++ b/toolkit/resources/manifests/package/toolchain_aarch64.txt @@ -529,18 +529,18 @@ pyproject-rpm-macros-1.12.0-2.azl3.noarch.rpm pyproject-srpm-macros-1.12.0-2.azl3.noarch.rpm python-markupsafe-debuginfo-2.1.3-1.azl3.aarch64.rpm python-wheel-wheel-0.43.0-1.azl3.noarch.rpm -python3-3.12.3-4.azl3.aarch64.rpm +python3-3.12.3-5.azl3.aarch64.rpm python3-audit-3.1.2-1.azl3.aarch64.rpm python3-cracklib-2.9.11-1.azl3.aarch64.rpm -python3-curses-3.12.3-4.azl3.aarch64.rpm +python3-curses-3.12.3-5.azl3.aarch64.rpm python3-Cython-3.0.5-2.azl3.aarch64.rpm -python3-debuginfo-3.12.3-4.azl3.aarch64.rpm -python3-devel-3.12.3-4.azl3.aarch64.rpm +python3-debuginfo-3.12.3-5.azl3.aarch64.rpm +python3-devel-3.12.3-5.azl3.aarch64.rpm python3-flit-core-3.9.0-1.azl3.noarch.rpm python3-gpg-1.23.2-2.azl3.aarch64.rpm python3-jinja2-3.1.2-1.azl3.noarch.rpm python3-libcap-ng-0.8.4-1.azl3.aarch64.rpm -python3-libs-3.12.3-4.azl3.aarch64.rpm +python3-libs-3.12.3-5.azl3.aarch64.rpm python3-libxml2-2.11.5-1.azl3.aarch64.rpm python3-lxml-4.9.3-1.azl3.aarch64.rpm python3-magic-5.45-1.azl3.noarch.rpm @@ -552,8 +552,8 @@ python3-pygments-2.7.4-2.azl3.noarch.rpm python3-rpm-4.18.2-1.azl3.aarch64.rpm python3-rpm-generators-14-11.azl3.noarch.rpm python3-setuptools-69.0.3-4.azl3.noarch.rpm -python3-test-3.12.3-4.azl3.aarch64.rpm -python3-tools-3.12.3-4.azl3.aarch64.rpm +python3-test-3.12.3-5.azl3.aarch64.rpm +python3-tools-3.12.3-5.azl3.aarch64.rpm python3-wheel-0.43.0-1.azl3.noarch.rpm readline-8.2-1.azl3.aarch64.rpm readline-debuginfo-8.2-1.azl3.aarch64.rpm diff --git a/toolkit/resources/manifests/package/toolchain_x86_64.txt b/toolkit/resources/manifests/package/toolchain_x86_64.txt index aacd1792796..02645c293ad 100644 --- a/toolkit/resources/manifests/package/toolchain_x86_64.txt +++ b/toolkit/resources/manifests/package/toolchain_x86_64.txt @@ -535,18 +535,18 @@ pyproject-rpm-macros-1.12.0-2.azl3.noarch.rpm pyproject-srpm-macros-1.12.0-2.azl3.noarch.rpm python-markupsafe-debuginfo-2.1.3-1.azl3.x86_64.rpm python-wheel-wheel-0.43.0-1.azl3.noarch.rpm -python3-3.12.3-4.azl3.x86_64.rpm +python3-3.12.3-5.azl3.x86_64.rpm python3-audit-3.1.2-1.azl3.x86_64.rpm python3-cracklib-2.9.11-1.azl3.x86_64.rpm -python3-curses-3.12.3-4.azl3.x86_64.rpm +python3-curses-3.12.3-5.azl3.x86_64.rpm python3-Cython-3.0.5-2.azl3.x86_64.rpm -python3-debuginfo-3.12.3-4.azl3.x86_64.rpm -python3-devel-3.12.3-4.azl3.x86_64.rpm +python3-debuginfo-3.12.3-5.azl3.x86_64.rpm +python3-devel-3.12.3-5.azl3.x86_64.rpm python3-flit-core-3.9.0-1.azl3.noarch.rpm python3-gpg-1.23.2-2.azl3.x86_64.rpm python3-jinja2-3.1.2-1.azl3.noarch.rpm python3-libcap-ng-0.8.4-1.azl3.x86_64.rpm -python3-libs-3.12.3-4.azl3.x86_64.rpm +python3-libs-3.12.3-5.azl3.x86_64.rpm python3-libxml2-2.11.5-1.azl3.x86_64.rpm python3-lxml-4.9.3-1.azl3.x86_64.rpm python3-magic-5.45-1.azl3.noarch.rpm @@ -558,8 +558,8 @@ python3-pygments-2.7.4-2.azl3.noarch.rpm python3-rpm-4.18.2-1.azl3.x86_64.rpm python3-rpm-generators-14-11.azl3.noarch.rpm python3-setuptools-69.0.3-4.azl3.noarch.rpm -python3-test-3.12.3-4.azl3.x86_64.rpm -python3-tools-3.12.3-4.azl3.x86_64.rpm +python3-test-3.12.3-5.azl3.x86_64.rpm +python3-tools-3.12.3-5.azl3.x86_64.rpm python3-wheel-0.43.0-1.azl3.noarch.rpm readline-8.2-1.azl3.x86_64.rpm readline-debuginfo-8.2-1.azl3.x86_64.rpm