diff --git a/tests/.fmf/version b/.fmf/version similarity index 100% rename from tests/.fmf/version rename to .fmf/version diff --git a/00251-change-user-install-location.patch b/00251-change-user-install-location.patch index c3938ae..9deba18 100644 --- a/00251-change-user-install-location.patch +++ b/00251-change-user-install-location.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Mon, 15 Feb 2021 12:19:27 +0100 -Subject: [PATCH] 00251: Change user install location +Subject: 00251: Change user install location MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -30,10 +30,10 @@ Co-authored-by: Lumír Balhar 3 files changed, 71 insertions(+), 4 deletions(-) diff --git a/Lib/site.py b/Lib/site.py -index 924b2460d9..51b5baca93 100644 +index aed254ad50..568dbdb945 100644 --- a/Lib/site.py +++ b/Lib/site.py -@@ -387,8 +387,15 @@ def getsitepackages(prefixes=None): +@@ -398,8 +398,15 @@ def getsitepackages(prefixes=None): return sitepackages def addsitepackages(known_paths, prefixes=None): @@ -51,7 +51,7 @@ index 924b2460d9..51b5baca93 100644 if os.path.isdir(sitedir): addsitedir(sitedir, known_paths) diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py -index 122d441bd1..2d354a11da 100644 +index acc8d4d182..6355669f62 100644 --- a/Lib/sysconfig.py +++ b/Lib/sysconfig.py @@ -104,6 +104,11 @@ @@ -86,7 +86,7 @@ index 122d441bd1..2d354a11da 100644 _SCHEME_KEYS = ('stdlib', 'platstdlib', 'purelib', 'platlib', 'include', 'scripts', 'data') -@@ -263,11 +281,40 @@ def _extend_dict(target_dict, other_dict): +@@ -268,11 +286,40 @@ def _extend_dict(target_dict, other_dict): target_dict[key] = value @@ -119,7 +119,7 @@ index 122d441bd1..2d354a11da 100644 + # we only change the defaults here, so explicit --prefix will take precedence + # https://fedoraproject.org/wiki/Changes/Making_sudo_pip_safe + if (scheme == 'posix_prefix' and -+ _PREFIX == '/usr' and ++ sys.prefix == '/usr' and + 'RPM_BUILD_ROOT' not in os.environ): + _extend_dict(vars, _config_vars_local()) + else: @@ -129,10 +129,10 @@ index 122d441bd1..2d354a11da 100644 # On Windows we want to substitute 'lib' for schemes rather # than the native value (without modifying vars, in case it diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py -index 1137c2032b..8fc2b84f52 100644 +index 67647e1b78..7baddaa9d6 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py -@@ -110,8 +110,19 @@ def test_get_path(self): +@@ -119,8 +119,19 @@ def test_get_path(self): for scheme in _INSTALL_SCHEMES: for name in _INSTALL_SCHEMES[scheme]: expected = _INSTALL_SCHEMES[scheme][name].format(**config_vars) @@ -153,7 +153,7 @@ index 1137c2032b..8fc2b84f52 100644 os.path.normpath(expected), ) -@@ -344,7 +355,7 @@ def test_get_config_h_filename(self): +@@ -353,7 +364,7 @@ def test_get_config_h_filename(self): self.assertTrue(os.path.isfile(config_h), config_h) def test_get_scheme_names(self): @@ -162,7 +162,7 @@ index 1137c2032b..8fc2b84f52 100644 if HAS_USER_BASE: wanted.extend(['nt_user', 'osx_framework_user', 'posix_user']) self.assertEqual(get_scheme_names(), tuple(sorted(wanted))) -@@ -356,6 +367,8 @@ def test_symlink(self): # Issue 7880 +@@ -365,6 +376,8 @@ def test_symlink(self): # Issue 7880 cmd = "-c", "import sysconfig; print(sysconfig.get_platform())" self.assertEqual(py.call_real(*cmd), py.call_link(*cmd)) diff --git a/00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch b/00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch index 2392a78..8a6f95e 100644 --- a/00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch +++ b/00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch @@ -1,8 +1,8 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= Date: Tue, 25 Oct 2022 12:02:33 +0200 -Subject: [PATCH] 00371: Revert "bpo-1596321: Fix threading._shutdown() for the - main thread (GH-28549) (GH-28589)" +Subject: 00371: Revert "bpo-1596321: Fix threading._shutdown() for the main + thread (GH-28549) (GH-28589)" This reverts commit 38c67738c64304928c68d5c2bd78bbb01d979b94. It introduced regression causing FreeIPA's tests to fail. @@ -16,7 +16,7 @@ https://github.com/GrahamDumpleton/mod_wsgi/issues/730 2 files changed, 8 insertions(+), 50 deletions(-) diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py -index 2e4b860b97..3066b23ee1 100644 +index 75a56f7830..c2509fced1 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -1100,39 +1100,6 @@ def noop(): pass @@ -60,10 +60,10 @@ index 2e4b860b97..3066b23ee1 100644 code = """if 1: import _thread diff --git a/Lib/threading.py b/Lib/threading.py -index 98cb43c697..ee647f8549 100644 +index 064c74d40f..9e3abacd42 100644 --- a/Lib/threading.py +++ b/Lib/threading.py -@@ -1585,29 +1585,20 @@ def _shutdown(): +@@ -1587,29 +1587,20 @@ def _shutdown(): global _SHUTTING_DOWN _SHUTTING_DOWN = True diff --git a/00415-cve-2023-27043-gh-102988-reject-malformed-addresses-in-email-parseaddr-111116.patch b/00415-cve-2023-27043-gh-102988-reject-malformed-addresses-in-email-parseaddr-111116.patch deleted file mode 100644 index 192c8b7..0000000 --- a/00415-cve-2023-27043-gh-102988-reject-malformed-addresses-in-email-parseaddr-111116.patch +++ /dev/null @@ -1,483 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Victor Stinner -Date: Fri, 15 Dec 2023 16:10:40 +0100 -Subject: [PATCH] 00415: [CVE-2023-27043] gh-102988: Reject malformed addresses - in email.parseaddr() (#111116) - -Detect email address parsing errors and return empty tuple to -indicate the parsing error (old API). Add an optional 'strict' -parameter to getaddresses() and parseaddr() functions. Patch by -Thomas Dwyer. - -Co-Authored-By: Thomas Dwyer ---- - Doc/library/email.utils.rst | 19 +- - Lib/email/utils.py | 151 +++++++++++++- - Lib/test/test_email/test_email.py | 187 +++++++++++++++++- - ...-10-20-15-28-08.gh-issue-102988.dStNO7.rst | 8 + - 4 files changed, 344 insertions(+), 21 deletions(-) - create mode 100644 Misc/NEWS.d/next/Library/2023-10-20-15-28-08.gh-issue-102988.dStNO7.rst - -diff --git a/Doc/library/email.utils.rst b/Doc/library/email.utils.rst -index 345b64001c..d693a9bc39 100644 ---- a/Doc/library/email.utils.rst -+++ b/Doc/library/email.utils.rst -@@ -58,13 +58,18 @@ of the new API. - begins with angle brackets, they are stripped off. - - --.. function:: parseaddr(address) -+.. function:: parseaddr(address, *, strict=True) - - Parse address -- which should be the value of some address-containing field such - as :mailheader:`To` or :mailheader:`Cc` -- into its constituent *realname* and - *email address* parts. Returns a tuple of that information, unless the parse - fails, in which case a 2-tuple of ``('', '')`` is returned. - -+ If *strict* is true, use a strict parser which rejects malformed inputs. -+ -+ .. versionchanged:: 3.13 -+ Add *strict* optional parameter and reject malformed inputs by default. -+ - - .. function:: formataddr(pair, charset='utf-8') - -@@ -82,12 +87,15 @@ of the new API. - Added the *charset* option. - - --.. function:: getaddresses(fieldvalues) -+.. function:: getaddresses(fieldvalues, *, strict=True) - - This method returns a list of 2-tuples of the form returned by ``parseaddr()``. - *fieldvalues* is a sequence of header field values as might be returned by -- :meth:`Message.get_all `. Here's a simple -- example that gets all the recipients of a message:: -+ :meth:`Message.get_all `. -+ -+ If *strict* is true, use a strict parser which rejects malformed inputs. -+ -+ Here's a simple example that gets all the recipients of a message:: - - from email.utils import getaddresses - -@@ -97,6 +105,9 @@ of the new API. - resent_ccs = msg.get_all('resent-cc', []) - all_recipients = getaddresses(tos + ccs + resent_tos + resent_ccs) - -+ .. versionchanged:: 3.13 -+ Add *strict* optional parameter and reject malformed inputs by default. -+ - - .. function:: parsedate(date) - -diff --git a/Lib/email/utils.py b/Lib/email/utils.py -index aa949aa933..af2fb14754 100644 ---- a/Lib/email/utils.py -+++ b/Lib/email/utils.py -@@ -48,6 +48,7 @@ - specialsre = re.compile(r'[][\\()<>@,:;".]') - escapesre = re.compile(r'[\\"]') - -+ - def _has_surrogates(s): - """Return True if s may contain surrogate-escaped binary data.""" - # This check is based on the fact that unless there are surrogates, utf8 -@@ -106,12 +107,127 @@ def formataddr(pair, charset='utf-8'): - return address - - -+def _iter_escaped_chars(addr): -+ pos = 0 -+ escape = False -+ for pos, ch in enumerate(addr): -+ if escape: -+ yield (pos, '\\' + ch) -+ escape = False -+ elif ch == '\\': -+ escape = True -+ else: -+ yield (pos, ch) -+ if escape: -+ yield (pos, '\\') - --def getaddresses(fieldvalues): -- """Return a list of (REALNAME, EMAIL) for each fieldvalue.""" -- all = COMMASPACE.join(str(v) for v in fieldvalues) -- a = _AddressList(all) -- return a.addresslist -+ -+def _strip_quoted_realnames(addr): -+ """Strip real names between quotes.""" -+ if '"' not in addr: -+ # Fast path -+ return addr -+ -+ start = 0 -+ open_pos = None -+ result = [] -+ for pos, ch in _iter_escaped_chars(addr): -+ if ch == '"': -+ if open_pos is None: -+ open_pos = pos -+ else: -+ if start != open_pos: -+ result.append(addr[start:open_pos]) -+ start = pos + 1 -+ open_pos = None -+ -+ if start < len(addr): -+ result.append(addr[start:]) -+ -+ return ''.join(result) -+ -+ -+supports_strict_parsing = True -+ -+def getaddresses(fieldvalues, *, strict=True): -+ """Return a list of (REALNAME, EMAIL) or ('','') for each fieldvalue. -+ -+ When parsing fails for a fieldvalue, a 2-tuple of ('', '') is returned in -+ its place. -+ -+ If strict is true, use a strict parser which rejects malformed inputs. -+ """ -+ -+ # If strict is true, if the resulting list of parsed addresses is greater -+ # than the number of fieldvalues in the input list, a parsing error has -+ # occurred and consequently a list containing a single empty 2-tuple [('', -+ # '')] is returned in its place. This is done to avoid invalid output. -+ # -+ # Malformed input: getaddresses(['alice@example.com ']) -+ # Invalid output: [('', 'alice@example.com'), ('', 'bob@example.com')] -+ # Safe output: [('', '')] -+ -+ if not strict: -+ all = COMMASPACE.join(str(v) for v in fieldvalues) -+ a = _AddressList(all) -+ return a.addresslist -+ -+ fieldvalues = [str(v) for v in fieldvalues] -+ fieldvalues = _pre_parse_validation(fieldvalues) -+ addr = COMMASPACE.join(fieldvalues) -+ a = _AddressList(addr) -+ result = _post_parse_validation(a.addresslist) -+ -+ # Treat output as invalid if the number of addresses is not equal to the -+ # expected number of addresses. -+ n = 0 -+ for v in fieldvalues: -+ # When a comma is used in the Real Name part it is not a deliminator. -+ # So strip those out before counting the commas. -+ v = _strip_quoted_realnames(v) -+ # Expected number of addresses: 1 + number of commas -+ n += 1 + v.count(',') -+ if len(result) != n: -+ return [('', '')] -+ -+ return result -+ -+ -+def _check_parenthesis(addr): -+ # Ignore parenthesis in quoted real names. -+ addr = _strip_quoted_realnames(addr) -+ -+ opens = 0 -+ for pos, ch in _iter_escaped_chars(addr): -+ if ch == '(': -+ opens += 1 -+ elif ch == ')': -+ opens -= 1 -+ if opens < 0: -+ return False -+ return (opens == 0) -+ -+ -+def _pre_parse_validation(email_header_fields): -+ accepted_values = [] -+ for v in email_header_fields: -+ if not _check_parenthesis(v): -+ v = "('', '')" -+ accepted_values.append(v) -+ -+ return accepted_values -+ -+ -+def _post_parse_validation(parsed_email_header_tuples): -+ accepted_values = [] -+ # The parser would have parsed a correctly formatted domain-literal -+ # The existence of an [ after parsing indicates a parsing failure -+ for v in parsed_email_header_tuples: -+ if '[' in v[1]: -+ v = ('', '') -+ accepted_values.append(v) -+ -+ return accepted_values - - - def _format_timetuple_and_zone(timetuple, zone): -@@ -205,16 +321,33 @@ def parsedate_to_datetime(data): - tzinfo=datetime.timezone(datetime.timedelta(seconds=tz))) - - --def parseaddr(addr): -+def parseaddr(addr, *, strict=True): - """ - Parse addr into its constituent realname and email address parts. - - Return a tuple of realname and email address, unless the parse fails, in - which case return a 2-tuple of ('', ''). -+ -+ If strict is True, use a strict parser which rejects malformed inputs. - """ -- addrs = _AddressList(addr).addresslist -- if not addrs: -- return '', '' -+ if not strict: -+ addrs = _AddressList(addr).addresslist -+ if not addrs: -+ return ('', '') -+ return addrs[0] -+ -+ if isinstance(addr, list): -+ addr = addr[0] -+ -+ if not isinstance(addr, str): -+ return ('', '') -+ -+ addr = _pre_parse_validation([addr])[0] -+ addrs = _post_parse_validation(_AddressList(addr).addresslist) -+ -+ if not addrs or len(addrs) > 1: -+ return ('', '') -+ - return addrs[0] - - -diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py -index a373c53c7c..c616398eb1 100644 ---- a/Lib/test/test_email/test_email.py -+++ b/Lib/test/test_email/test_email.py -@@ -16,6 +16,7 @@ - - import email - import email.policy -+import email.utils - - from email.charset import Charset - from email.generator import Generator, DecodedGenerator, BytesGenerator -@@ -3352,15 +3353,137 @@ def test_getaddresses_comma_in_name(self): - ], - ) - -+ def test_parsing_errors(self): -+ """Test for parsing errors from CVE-2023-27043 and CVE-2019-16056""" -+ alice = 'alice@example.org' -+ bob = 'bob@example.com' -+ empty = ('', '') -+ -+ # Test utils.getaddresses() and utils.parseaddr() on malformed email -+ # addresses: default behavior (strict=True) rejects malformed address, -+ # and strict=False which tolerates malformed address. -+ for invalid_separator, expected_non_strict in ( -+ ('(', [(f'<{bob}>', alice)]), -+ (')', [('', alice), empty, ('', bob)]), -+ ('<', [('', alice), empty, ('', bob), empty]), -+ ('>', [('', alice), empty, ('', bob)]), -+ ('[', [('', f'{alice}[<{bob}>]')]), -+ (']', [('', alice), empty, ('', bob)]), -+ ('@', [empty, empty, ('', bob)]), -+ (';', [('', alice), empty, ('', bob)]), -+ (':', [('', alice), ('', bob)]), -+ ('.', [('', alice + '.'), ('', bob)]), -+ ('"', [('', alice), ('', f'<{bob}>')]), -+ ): -+ address = f'{alice}{invalid_separator}<{bob}>' -+ with self.subTest(address=address): -+ self.assertEqual(utils.getaddresses([address]), -+ [empty]) -+ self.assertEqual(utils.getaddresses([address], strict=False), -+ expected_non_strict) -+ -+ self.assertEqual(utils.parseaddr([address]), -+ empty) -+ self.assertEqual(utils.parseaddr([address], strict=False), -+ ('', address)) -+ -+ # Comma (',') is treated differently depending on strict parameter. -+ # Comma without quotes. -+ address = f'{alice},<{bob}>' -+ self.assertEqual(utils.getaddresses([address]), -+ [('', alice), ('', bob)]) -+ self.assertEqual(utils.getaddresses([address], strict=False), -+ [('', alice), ('', bob)]) -+ self.assertEqual(utils.parseaddr([address]), -+ empty) -+ self.assertEqual(utils.parseaddr([address], strict=False), -+ ('', address)) -+ -+ # Real name between quotes containing comma. -+ address = '"Alice, alice@example.org" ' -+ expected_strict = ('Alice, alice@example.org', 'bob@example.com') -+ self.assertEqual(utils.getaddresses([address]), [expected_strict]) -+ self.assertEqual(utils.getaddresses([address], strict=False), [expected_strict]) -+ self.assertEqual(utils.parseaddr([address]), expected_strict) -+ self.assertEqual(utils.parseaddr([address], strict=False), -+ ('', address)) -+ -+ # Valid parenthesis in comments. -+ address = 'alice@example.org (Alice)' -+ expected_strict = ('Alice', 'alice@example.org') -+ self.assertEqual(utils.getaddresses([address]), [expected_strict]) -+ self.assertEqual(utils.getaddresses([address], strict=False), [expected_strict]) -+ self.assertEqual(utils.parseaddr([address]), expected_strict) -+ self.assertEqual(utils.parseaddr([address], strict=False), -+ ('', address)) -+ -+ # Invalid parenthesis in comments. -+ address = 'alice@example.org )Alice(' -+ self.assertEqual(utils.getaddresses([address]), [empty]) -+ self.assertEqual(utils.getaddresses([address], strict=False), -+ [('', 'alice@example.org'), ('', ''), ('', 'Alice')]) -+ self.assertEqual(utils.parseaddr([address]), empty) -+ self.assertEqual(utils.parseaddr([address], strict=False), -+ ('', address)) -+ -+ # Two addresses with quotes separated by comma. -+ address = '"Jane Doe" , "John Doe" ' -+ self.assertEqual(utils.getaddresses([address]), -+ [('Jane Doe', 'jane@example.net'), -+ ('John Doe', 'john@example.net')]) -+ self.assertEqual(utils.getaddresses([address], strict=False), -+ [('Jane Doe', 'jane@example.net'), -+ ('John Doe', 'john@example.net')]) -+ self.assertEqual(utils.parseaddr([address]), empty) -+ self.assertEqual(utils.parseaddr([address], strict=False), -+ ('', address)) -+ -+ # Test email.utils.supports_strict_parsing attribute -+ self.assertEqual(email.utils.supports_strict_parsing, True) -+ - def test_getaddresses_nasty(self): -- eq = self.assertEqual -- eq(utils.getaddresses(['foo: ;']), [('', '')]) -- eq(utils.getaddresses( -- ['[]*-- =~$']), -- [('', ''), ('', ''), ('', '*--')]) -- eq(utils.getaddresses( -- ['foo: ;', '"Jason R. Mastaler" ']), -- [('', ''), ('Jason R. Mastaler', 'jason@dom.ain')]) -+ for addresses, expected in ( -+ (['"Sürname, Firstname" '], -+ [('Sürname, Firstname', 'to@example.com')]), -+ -+ (['foo: ;'], -+ [('', '')]), -+ -+ (['foo: ;', '"Jason R. Mastaler" '], -+ [('', ''), ('Jason R. Mastaler', 'jason@dom.ain')]), -+ -+ ([r'Pete(A nice \) chap) '], -+ [('Pete (A nice ) chap his account his host)', 'pete@silly.test')]), -+ -+ (['(Empty list)(start)Undisclosed recipients :(nobody(I know))'], -+ [('', '')]), -+ -+ (['Mary <@machine.tld:mary@example.net>, , jdoe@test . example'], -+ [('Mary', 'mary@example.net'), ('', ''), ('', 'jdoe@test.example')]), -+ -+ (['John Doe '], -+ [('John Doe (comment)', 'jdoe@machine.example')]), -+ -+ (['"Mary Smith: Personal Account" '], -+ [('Mary Smith: Personal Account', 'smith@home.example')]), -+ -+ (['Undisclosed recipients:;'], -+ [('', '')]), -+ -+ ([r', "Giant; \"Big\" Box" '], -+ [('', 'boss@nil.test'), ('Giant; "Big" Box', 'bob@example.net')]), -+ ): -+ with self.subTest(addresses=addresses): -+ self.assertEqual(utils.getaddresses(addresses), -+ expected) -+ self.assertEqual(utils.getaddresses(addresses, strict=False), -+ expected) -+ -+ addresses = ['[]*-- =~$'] -+ self.assertEqual(utils.getaddresses(addresses), -+ [('', '')]) -+ self.assertEqual(utils.getaddresses(addresses, strict=False), -+ [('', ''), ('', ''), ('', '*--')]) - - def test_getaddresses_embedded_comment(self): - """Test proper handling of a nested comment""" -@@ -3551,6 +3674,54 @@ def test_mime_classes_policy_argument(self): - m = cls(*constructor, policy=email.policy.default) - self.assertIs(m.policy, email.policy.default) - -+ def test_iter_escaped_chars(self): -+ self.assertEqual(list(utils._iter_escaped_chars(r'a\\b\"c\\"d')), -+ [(0, 'a'), -+ (2, '\\\\'), -+ (3, 'b'), -+ (5, '\\"'), -+ (6, 'c'), -+ (8, '\\\\'), -+ (9, '"'), -+ (10, 'd')]) -+ self.assertEqual(list(utils._iter_escaped_chars('a\\')), -+ [(0, 'a'), (1, '\\')]) -+ -+ def test_strip_quoted_realnames(self): -+ def check(addr, expected): -+ self.assertEqual(utils._strip_quoted_realnames(addr), expected) -+ -+ check('"Jane Doe" , "John Doe" ', -+ ' , ') -+ check(r'"Jane \"Doe\"." ', -+ ' ') -+ -+ # special cases -+ check(r'before"name"after', 'beforeafter') -+ check(r'before"name"', 'before') -+ check(r'b"name"', 'b') # single char -+ check(r'"name"after', 'after') -+ check(r'"name"a', 'a') # single char -+ check(r'"name"', '') -+ -+ # no change -+ for addr in ( -+ 'Jane Doe , John Doe ', -+ 'lone " quote', -+ ): -+ self.assertEqual(utils._strip_quoted_realnames(addr), addr) -+ -+ -+ def test_check_parenthesis(self): -+ addr = 'alice@example.net' -+ self.assertTrue(utils._check_parenthesis(f'{addr} (Alice)')) -+ self.assertFalse(utils._check_parenthesis(f'{addr} )Alice(')) -+ self.assertFalse(utils._check_parenthesis(f'{addr} (Alice))')) -+ self.assertFalse(utils._check_parenthesis(f'{addr} ((Alice)')) -+ -+ # Ignore real name between quotes -+ self.assertTrue(utils._check_parenthesis(f'")Alice((" {addr}')) -+ - - # Test the iterator/generators - class TestIterators(TestEmailBase): -diff --git a/Misc/NEWS.d/next/Library/2023-10-20-15-28-08.gh-issue-102988.dStNO7.rst b/Misc/NEWS.d/next/Library/2023-10-20-15-28-08.gh-issue-102988.dStNO7.rst -new file mode 100644 -index 0000000000..3d0e9e4078 ---- /dev/null -+++ b/Misc/NEWS.d/next/Library/2023-10-20-15-28-08.gh-issue-102988.dStNO7.rst -@@ -0,0 +1,8 @@ -+:func:`email.utils.getaddresses` and :func:`email.utils.parseaddr` now -+return ``('', '')`` 2-tuples in more situations where invalid email -+addresses are encountered instead of potentially inaccurate values. Add -+optional *strict* parameter to these two functions: use ``strict=False`` to -+get the old behavior, accept malformed inputs. -+``getattr(email.utils, 'supports_strict_parsing', False)`` can be use to check -+if the *strict* paramater is available. Patch by Thomas Dwyer and Victor -+Stinner to improve the CVE-2023-27043 fix. diff --git a/00425-only-check-for-test-wheeldata-when-it-s-actually-used.patch b/00425-only-check-for-test-wheeldata-when-it-s-actually-used.patch deleted file mode 100644 index ea2df3a..0000000 --- a/00425-only-check-for-test-wheeldata-when-it-s-actually-used.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Karolina Surma -Date: Wed, 10 Apr 2024 15:35:04 +0200 -Subject: [PATCH] 00425: Only check for 'test/wheeldata' when it's actually - used - -We build Python in Fedora 39+ with option `--with-wheel-pkg-dir` -pointing to a custom wheel directory and delete the contents of -upstream's `test/wheeldata`. Don't include the directory in the test set -if the wheels are used from a different location. ---- - Lib/test/test_tools/test_makefile.py | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/Lib/test/test_tools/test_makefile.py b/Lib/test/test_tools/test_makefile.py -index 17a1a6d0d3..9ce874033d 100644 ---- a/Lib/test/test_tools/test_makefile.py -+++ b/Lib/test/test_tools/test_makefile.py -@@ -66,6 +66,9 @@ def test_makefile_test_folders(self): - ) - used.append(relpath) - -+ if sysconfig.get_config_var('WHEEL_PKG_DIR'): -+ test_dirs.remove('test/wheeldata') -+ - # Check that there are no extra entries: - unique_test_dirs = set(test_dirs) - self.assertSetEqual(unique_test_dirs, set(used)) diff --git a/00460-gh-132415-update-vendored-setuptools-in-lib-test-wheeldata.patch b/00460-gh-132415-update-vendored-setuptools-in-lib-test-wheeldata.patch new file mode 100644 index 0000000..d6c067b --- /dev/null +++ b/00460-gh-132415-update-vendored-setuptools-in-lib-test-wheeldata.patch @@ -0,0 +1,96 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Adam Turner <9087854+AA-Turner@users.noreply.github.com> +Date: Fri, 25 Apr 2025 00:46:20 +0100 +Subject: 00460: gh-132415: Update vendored setuptools in + ``Lib/test/wheeldata`` + +(cherry picked from commit c9f3f5b4ed52d7bed6073ffa39717ece47202558) +(actual changes in .whl files removed to make this patch smaller) + +gh-127906: Add missing sys import to test_cppext + +(cherry picked from commit 9cba14881b371b1e95d57877896169c4605f9b75) + +Co-Authored-By: Victor Stinner +--- + Lib/test/support/__init__.py | 5 ++--- + Lib/test/test_cext/__init__.py | 2 +- + Lib/test/test_cppext/__init__.py | 2 +- + Lib/test/test_cppext/setup.py | 1 + + Lib/test/test_peg_generator/test_c_parser.py | 2 +- + 5 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py +index 1ee8ffc1b7..cab0f49366 100644 +--- a/Lib/test/support/__init__.py ++++ b/Lib/test/support/__init__.py +@@ -2308,7 +2308,7 @@ def _findwheel(pkgname): + # Context manager that creates a virtual environment, install setuptools in it, + # and returns the paths to the venv directory and the python executable + @contextlib.contextmanager +-def setup_venv_with_pip_setuptools_wheel(venv_dir): ++def setup_venv_with_pip_setuptools(venv_dir): + import subprocess + from .os_helper import temp_cwd + +@@ -2331,8 +2331,7 @@ def setup_venv_with_pip_setuptools_wheel(venv_dir): + + cmd = (python, '-X', 'dev', + '-m', 'pip', 'install', +- _findwheel('setuptools'), +- _findwheel('wheel')) ++ _findwheel('setuptools')) + if verbose: + print() + print('Run:', ' '.join(cmd)) +diff --git a/Lib/test/test_cext/__init__.py b/Lib/test/test_cext/__init__.py +index d5ea1dc660..04a6361ff3 100644 +--- a/Lib/test/test_cext/__init__.py ++++ b/Lib/test/test_cext/__init__.py +@@ -53,7 +53,7 @@ def check_build(self, extension_name, std=None, limited=False): + self.skipTest('Py_LIMITED_API is incompatible with Py_TRACE_REFS') + + venv_dir = 'env' +- with support.setup_venv_with_pip_setuptools_wheel(venv_dir) as python_exe: ++ with support.setup_venv_with_pip_setuptools(venv_dir) as python_exe: + self._check_build(extension_name, python_exe, + std=std, limited=limited) + +diff --git a/Lib/test/test_cppext/__init__.py b/Lib/test/test_cppext/__init__.py +index 2198b7b2c0..31ea4ac7a1 100644 +--- a/Lib/test/test_cppext/__init__.py ++++ b/Lib/test/test_cppext/__init__.py +@@ -51,7 +51,7 @@ def check_build(self, extension_name, std=None, limited=False): + self.skipTest('Py_LIMITED_API is incompatible with Py_TRACE_REFS') + + venv_dir = 'env' +- with support.setup_venv_with_pip_setuptools_wheel(venv_dir) as python_exe: ++ with support.setup_venv_with_pip_setuptools(venv_dir) as python_exe: + self._check_build(extension_name, python_exe, + std=std, limited=limited) + +diff --git a/Lib/test/test_cppext/setup.py b/Lib/test/test_cppext/setup.py +index 019ff18446..25d71cd9a2 100644 +--- a/Lib/test/test_cppext/setup.py ++++ b/Lib/test/test_cppext/setup.py +@@ -3,6 +3,7 @@ + import os + import platform + import shlex ++import sys + import sysconfig + from test import support + +diff --git a/Lib/test/test_peg_generator/test_c_parser.py b/Lib/test/test_peg_generator/test_c_parser.py +index eb31569c03..2fe1367b51 100644 +--- a/Lib/test/test_peg_generator/test_c_parser.py ++++ b/Lib/test/test_peg_generator/test_c_parser.py +@@ -99,7 +99,7 @@ def setUpClass(cls): + cls.addClassCleanup(shutil.rmtree, cls.library_dir) + + with contextlib.ExitStack() as stack: +- python_exe = stack.enter_context(support.setup_venv_with_pip_setuptools_wheel("venv")) ++ python_exe = stack.enter_context(support.setup_venv_with_pip_setuptools("venv")) + sitepackages = subprocess.check_output( + [python_exe, "-c", "import sysconfig; print(sysconfig.get_path('platlib'))"], + text=True, diff --git a/00461-downstream-only-install-wheel-in-test-venvs-when-setuptools-71.patch b/00461-downstream-only-install-wheel-in-test-venvs-when-setuptools-71.patch new file mode 100644 index 0000000..5d1416c --- /dev/null +++ b/00461-downstream-only-install-wheel-in-test-venvs-when-setuptools-71.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= +Date: Fri, 25 Apr 2025 09:33:37 +0200 +Subject: 00461: Downstream only: Install wheel in test venvs when setuptools < + 71 + +--- + Lib/test/support/__init__.py | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py +index cab0f49366..26c0af4b13 100644 +--- a/Lib/test/support/__init__.py ++++ b/Lib/test/support/__init__.py +@@ -2329,9 +2329,18 @@ def setup_venv_with_pip_setuptools(venv_dir): + else: + python = os.path.join(venv, 'bin', python_exe) + ++ setuptools_whl = _findwheel('setuptools') ++ whl_filename = os.path.basename(setuptools_whl) ++ setuptools_major = int(whl_filename.split('-')[1].split('.')[0]) ++ if setuptools_major >= 71: # we need 70.1+, but that's OK ++ wheels = (setuptools_whl,) ++ else: ++ wheels = (setuptools_whl, _findwheel('wheel')) ++ + cmd = (python, '-X', 'dev', + '-m', 'pip', 'install', +- _findwheel('setuptools')) ++ *wheels, ++ ) + if verbose: + print() + print('Run:', ' '.join(cmd)) diff --git a/00462-fix-pyssl_seterror-handling-ssl_error_syscall.patch b/00462-fix-pyssl_seterror-handling-ssl_error_syscall.patch new file mode 100644 index 0000000..93984f2 --- /dev/null +++ b/00462-fix-pyssl_seterror-handling-ssl_error_syscall.patch @@ -0,0 +1,196 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: yevgeny hong +Date: Tue, 26 Mar 2024 16:45:43 +0900 +Subject: 00462: Fix PySSL_SetError handling SSL_ERROR_SYSCALL + +Python 3.10 changed from using SSL_write() and SSL_read() to SSL_write_ex() and +SSL_read_ex(), but did not update handling of the return value. + +Change error handling so that the return value is not examined. +OSError (not EOF) is now returned when retval is 0. + +This resolves the issue of failing tests when a system is +stressed on OpenSSL 3.5. + +Co-authored-by: Serhiy Storchaka +Co-authored-by: Petr Viktorin +--- + Lib/test/test_ssl.py | 28 ++++++----- + ...-02-18-09-50-31.gh-issue-115627.HGchj0.rst | 2 + + Modules/_ssl.c | 48 +++++++------------ + 3 files changed, 35 insertions(+), 43 deletions(-) + create mode 100644 Misc/NEWS.d/next/Library/2024-02-18-09-50-31.gh-issue-115627.HGchj0.rst + +diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py +index b13e37d0cd..daeb8cba74 100644 +--- a/Lib/test/test_ssl.py ++++ b/Lib/test/test_ssl.py +@@ -2427,16 +2427,18 @@ def run(self): + self.write(msg.lower()) + except OSError as e: + # handles SSLError and socket errors ++ if isinstance(e, ConnectionError): ++ # OpenSSL 1.1.1 sometimes raises ++ # ConnectionResetError when connection is not ++ # shut down gracefully. ++ if self.server.chatty and support.verbose: ++ print(f" Connection reset by peer: {self.addr}") ++ ++ self.close() ++ self.running = False ++ return + if self.server.chatty and support.verbose: +- if isinstance(e, ConnectionError): +- # OpenSSL 1.1.1 sometimes raises +- # ConnectionResetError when connection is not +- # shut down gracefully. +- print( +- f" Connection reset by peer: {self.addr}" +- ) +- else: +- handle_error("Test server failure:\n") ++ handle_error("Test server failure:\n") + try: + self.write(b"ERROR\n") + except OSError: +@@ -3148,8 +3150,8 @@ def test_wrong_cert_tls13(self): + suppress_ragged_eofs=False) as s: + s.connect((HOST, server.port)) + with self.assertRaisesRegex( +- ssl.SSLError, +- 'alert unknown ca|EOF occurred|TLSV1_ALERT_UNKNOWN_CA' ++ OSError, ++ 'alert unknown ca|EOF occurred|TLSV1_ALERT_UNKNOWN_CA|closed by the remote host|Connection reset by peer' + ): + # TLS 1.3 perform client cert exchange after handshake + s.write(b'data') +@@ -4422,8 +4424,8 @@ def msg_cb(conn, direction, version, content_type, msg_type, data): + # test sometimes fails with EOF error. Test passes as long as + # server aborts connection with an error. + with self.assertRaisesRegex( +- ssl.SSLError, +- '(certificate required|EOF occurred)' ++ OSError, ++ 'certificate required|EOF occurred|closed by the remote host|Connection reset by peer' + ): + # receive CertificateRequest + data = s.recv(1024) +diff --git a/Misc/NEWS.d/next/Library/2024-02-18-09-50-31.gh-issue-115627.HGchj0.rst b/Misc/NEWS.d/next/Library/2024-02-18-09-50-31.gh-issue-115627.HGchj0.rst +new file mode 100644 +index 0000000000..75d926ab59 +--- /dev/null ++++ b/Misc/NEWS.d/next/Library/2024-02-18-09-50-31.gh-issue-115627.HGchj0.rst +@@ -0,0 +1,2 @@ ++Fix the :mod:`ssl` module error handling of connection terminate by peer. ++It now throws an OSError with the appropriate error code instead of an EOFError. +diff --git a/Modules/_ssl.c b/Modules/_ssl.c +index aae4dc323d..27dd7bbe11 100644 +--- a/Modules/_ssl.c ++++ b/Modules/_ssl.c +@@ -573,7 +573,7 @@ PySSL_ChainExceptions(PySSLSocket *sslsock) { + } + + static PyObject * +-PySSL_SetError(PySSLSocket *sslsock, int ret, const char *filename, int lineno) ++PySSL_SetError(PySSLSocket *sslsock, const char *filename, int lineno) + { + PyObject *type; + char *errstr = NULL; +@@ -586,7 +586,6 @@ PySSL_SetError(PySSLSocket *sslsock, int ret, const char *filename, int lineno) + _sslmodulestate *state = get_state_sock(sslsock); + type = state->PySSLErrorObject; + +- assert(ret <= 0); + e = ERR_peek_last_error(); + + if (sslsock->ssl != NULL) { +@@ -619,32 +618,21 @@ PySSL_SetError(PySSLSocket *sslsock, int ret, const char *filename, int lineno) + case SSL_ERROR_SYSCALL: + { + if (e == 0) { +- PySocketSockObject *s = GET_SOCKET(sslsock); +- if (ret == 0 || (((PyObject *)s) == Py_None)) { ++ /* underlying BIO reported an I/O error */ ++ ERR_clear_error(); ++#ifdef MS_WINDOWS ++ if (err.ws) { ++ return PyErr_SetFromWindowsErr(err.ws); ++ } ++#endif ++ if (err.c) { ++ errno = err.c; ++ return PyErr_SetFromErrno(PyExc_OSError); ++ } ++ else { + p = PY_SSL_ERROR_EOF; + type = state->PySSLEOFErrorObject; + errstr = "EOF occurred in violation of protocol"; +- } else if (s && ret == -1) { +- /* underlying BIO reported an I/O error */ +- ERR_clear_error(); +-#ifdef MS_WINDOWS +- if (err.ws) { +- return PyErr_SetFromWindowsErr(err.ws); +- } +-#endif +- if (err.c) { +- errno = err.c; +- return PyErr_SetFromErrno(PyExc_OSError); +- } +- else { +- p = PY_SSL_ERROR_EOF; +- type = state->PySSLEOFErrorObject; +- errstr = "EOF occurred in violation of protocol"; +- } +- } else { /* possible? */ +- p = PY_SSL_ERROR_SYSCALL; +- type = state->PySSLSyscallErrorObject; +- errstr = "Some I/O error occurred"; + } + } else { + if (ERR_GET_LIB(e) == ERR_LIB_SSL && +@@ -1007,7 +995,7 @@ _ssl__SSLSocket_do_handshake_impl(PySSLSocket *self) + err.ssl == SSL_ERROR_WANT_WRITE); + Py_XDECREF(sock); + if (ret < 1) +- return PySSL_SetError(self, ret, __FILE__, __LINE__); ++ return PySSL_SetError(self, __FILE__, __LINE__); + if (PySSL_ChainExceptions(self) < 0) + return NULL; + Py_RETURN_NONE; +@@ -2424,7 +2412,7 @@ _ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b) + + Py_XDECREF(sock); + if (retval == 0) +- return PySSL_SetError(self, retval, __FILE__, __LINE__); ++ return PySSL_SetError(self, __FILE__, __LINE__); + if (PySSL_ChainExceptions(self) < 0) + return NULL; + return PyLong_FromSize_t(count); +@@ -2454,7 +2442,7 @@ _ssl__SSLSocket_pending_impl(PySSLSocket *self) + self->err = err; + + if (count < 0) +- return PySSL_SetError(self, count, __FILE__, __LINE__); ++ return PySSL_SetError(self, __FILE__, __LINE__); + else + return PyLong_FromLong(count); + } +@@ -2577,7 +2565,7 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, Py_ssize_t len, + err.ssl == SSL_ERROR_WANT_WRITE); + + if (retval == 0) { +- PySSL_SetError(self, retval, __FILE__, __LINE__); ++ PySSL_SetError(self, __FILE__, __LINE__); + goto error; + } + if (self->exc != NULL) +@@ -2703,7 +2691,7 @@ _ssl__SSLSocket_shutdown_impl(PySSLSocket *self) + } + if (ret < 0) { + Py_XDECREF(sock); +- PySSL_SetError(self, ret, __FILE__, __LINE__); ++ PySSL_SetError(self, __FILE__, __LINE__); + return NULL; + } + if (self->exc != NULL) diff --git a/00474-cve-2025-15366.patch b/00474-cve-2025-15366.patch new file mode 100644 index 0000000..50f62d9 --- /dev/null +++ b/00474-cve-2025-15366.patch @@ -0,0 +1,61 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Seth Michael Larson +Date: Tue, 20 Jan 2026 14:45:42 -0600 +Subject: 00474: CVE-2025-15366 + +gh-143921: Reject control characters in IMAP commands + +(cherry-picked from commit 6262704b134db2a4ba12e85ecfbd968534f28b45) +--- + Lib/imaplib.py | 4 +++- + Lib/test/test_imaplib.py | 6 ++++++ + .../Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst | 1 + + 3 files changed, 10 insertions(+), 1 deletion(-) + create mode 100644 Misc/NEWS.d/next/Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst + +diff --git a/Lib/imaplib.py b/Lib/imaplib.py +index e337fe6471..c7f44f05b1 100644 +--- a/Lib/imaplib.py ++++ b/Lib/imaplib.py +@@ -132,7 +132,7 @@ + # We compile these in _mode_xxx. + _Literal = br'.*{(?P\d+)}$' + _Untagged_status = br'\* (?P\d+) (?P[A-Z-]+)( (?P.*))?' +- ++_control_chars = re.compile(b'[\x00-\x1F\x7F]') + + + class IMAP4: +@@ -994,6 +994,8 @@ def _command(self, name, *args): + if arg is None: continue + if isinstance(arg, str): + arg = bytes(arg, self._encoding) ++ if _control_chars.search(arg): ++ raise ValueError("Control characters not allowed in commands") + data = data + b' ' + arg + + literal = self.literal +diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py +index 4429a90050..73c25bc733 100644 +--- a/Lib/test/test_imaplib.py ++++ b/Lib/test/test_imaplib.py +@@ -504,6 +504,12 @@ def test_login(self): + self.assertEqual(data[0], b'LOGIN completed') + self.assertEqual(client.state, 'AUTH') + ++ def test_control_characters(self): ++ client, _ = self._setup(SimpleIMAPHandler) ++ for c0 in support.control_characters_c0(): ++ with self.assertRaises(ValueError): ++ client.login(f'user{c0}', 'pass') ++ + def test_logout(self): + client, _ = self._setup(SimpleIMAPHandler) + typ, data = client.login('user', 'pass') +diff --git a/Misc/NEWS.d/next/Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst b/Misc/NEWS.d/next/Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst +new file mode 100644 +index 0000000000..4e13fe92bc +--- /dev/null ++++ b/Misc/NEWS.d/next/Security/2026-01-16-11-41-06.gh-issue-143921.AeCOor.rst +@@ -0,0 +1 @@ ++Reject control characters in IMAP commands. diff --git a/00475-cve-2025-15367.patch b/00475-cve-2025-15367.patch new file mode 100644 index 0000000..12b945f --- /dev/null +++ b/00475-cve-2025-15367.patch @@ -0,0 +1,61 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Seth Michael Larson +Date: Tue, 20 Jan 2026 14:46:32 -0600 +Subject: 00475: CVE-2025-15367 + +gh-143923: Reject control characters in POP3 commands + +(cherry-picked from commit b234a2b67539f787e191d2ef19a7cbdce32874e7) +--- + Lib/poplib.py | 2 ++ + Lib/test/test_poplib.py | 8 ++++++++ + .../2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst | 1 + + 3 files changed, 11 insertions(+) + create mode 100644 Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst + +diff --git a/Lib/poplib.py b/Lib/poplib.py +index 9eb662d000..5c83522504 100644 +--- a/Lib/poplib.py ++++ b/Lib/poplib.py +@@ -122,6 +122,8 @@ def _putline(self, line): + def _putcmd(self, line): + if self._debugging: print('*cmd*', repr(line)) + line = bytes(line, self.encoding) ++ if re.search(b'[\x00-\x1F\x7F]', line): ++ raise ValueError('Control characters not allowed in commands') + self._putline(line) + + +diff --git a/Lib/test/test_poplib.py b/Lib/test/test_poplib.py +index f1ebbeafe0..50d8c255d6 100644 +--- a/Lib/test/test_poplib.py ++++ b/Lib/test/test_poplib.py +@@ -12,6 +12,7 @@ + import unittest + from unittest import TestCase, skipUnless + from test import support as test_support ++from test.support import control_characters_c0 + from test.support import hashlib_helper + from test.support import socket_helper + from test.support import threading_helper +@@ -395,6 +396,13 @@ def test_quit(self): + self.assertIsNone(self.client.sock) + self.assertIsNone(self.client.file) + ++ def test_control_characters(self): ++ for c0 in control_characters_c0(): ++ with self.assertRaises(ValueError): ++ self.client.user(f'user{c0}') ++ with self.assertRaises(ValueError): ++ self.client.pass_(f'{c0}pass') ++ + @requires_ssl + def test_stls_capa(self): + capa = self.client.capa() +diff --git a/Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst b/Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst +new file mode 100644 +index 0000000000..3cde4df3e0 +--- /dev/null ++++ b/Misc/NEWS.d/next/Security/2026-01-16-11-43-47.gh-issue-143923.DuytMe.rst +@@ -0,0 +1 @@ ++Reject control characters in POP3 commands. diff --git a/00494-increase-the-timeout-of-test_large_content_length_truncated.patch b/00494-increase-the-timeout-of-test_large_content_length_truncated.patch new file mode 100644 index 0000000..9d0ef51 --- /dev/null +++ b/00494-increase-the-timeout-of-test_large_content_length_truncated.patch @@ -0,0 +1,23 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Karolina Surma +Date: Fri, 14 Aug 2026 09:38:26 +0200 +Subject: 00494: Increase the timeout of test_large_content_length_truncated + +It has started to fail randomly when run on s390x architecture. +--- + Lib/test/test_httpservers.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py +index 96fc9ca574..6a3f5731a4 100644 +--- a/Lib/test/test_httpservers.py ++++ b/Lib/test/test_httpservers.py +@@ -907,7 +907,7 @@ def test_large_content_length(self): + self.assertEqual(res.read(), b'%d %d' % (size, size) + self.linesep) + + def test_large_content_length_truncated(self): +- with support.swap_attr(self.request_handler, 'timeout', 0.001): ++ with support.swap_attr(self.request_handler, 'timeout', support.LOOPBACK_TIMEOUT): + for w in range(18, 65): + size = 1 << w + headers = {'Content-Length' : str(size)} diff --git a/plan.fmf b/plan.fmf new file mode 100644 index 0000000..bb48d32 --- /dev/null +++ b/plan.fmf @@ -0,0 +1,67 @@ +execute: + how: tmt + +provision: + hardware: + memory: '>= 3 GB' + +environment: + pybasever: '3.12' + +discover: + - name: tests_python + how: shell + url: https://src.fedoraproject.org/tests/python.git + tests: + - name: smoke + path: /smoke + test: "VERSION=${pybasever} ./venv.sh" + - name: smoke_virtualenv + path: /smoke + test: "VERSION=${pybasever} METHOD=virtualenv ./venv.sh" + - name: debugsmoke + path: /smoke + test: "PYTHON=python${pybasever}d TOX=false VERSION=${pybasever} ./venv.sh" + - name: selftest + path: /selftest + test: "VERSION=${pybasever} X='-i test_check_probes' ./parallel.sh" + - name: debugtest + path: /selftest + test: "VERSION=${pybasever} PYTHON=python${pybasever}d X='-i test_check_probes' ./parallel.sh" + - name: debugflags + path: /flags + test: "python${pybasever}d ./assertflags.py -O0" + - name: marshalparser + path: /marshalparser + test: "VERSION=${pybasever} SAMPLE=10 ./test_marshalparser_compatibility.sh" + - name: required_symbols + path: /required-symbols + test: "VERSION=${pybasever} ./check.sh" + +prepare: + - name: Install dependencies + how: install + package: + - gcc # for extension building in venv and selftest + - gcc-c++ # for test_cppext + - gdb # for test_gdb + - "python${pybasever}" # the test subject + - "python${pybasever}-debug" # for leak testing + - "python${pybasever}-devel" # for extension building in venv and selftest + - "python${pybasever}-tkinter" # for selftest + - "python${pybasever}-test" # for selftest + - tox # for venv tests + - virtualenv # for virtualenv tests + - glibc-all-langpacks # for locale tests + - marshalparser # for testing compatibility (magic numbers) with marshalparser + - binutils # for nm (symbol inspection) + - rpm # for debugging + - dnf # for upgrade and downgrade + - perf # for test_perf_profiler + - name: Update packages + how: shell + script: dnf upgrade -y + - name: rpm_qa + order: 100 + how: shell + script: rpm -qa | sort | tee $TMT_PLAN_DATA/rpmqa.txt diff --git a/python3.12.spec b/python3.12.spec index 6d23850..0c61ac1 100644 --- a/python3.12.spec +++ b/python3.12.spec @@ -13,11 +13,11 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well -%global general_version %{pybasever}.3 +%global general_version %{pybasever}.14 #global prerel ... %global upstream_version %{general_version}%{?prerel} Version: %{general_version}%{?prerel:~%{prerel}} -Release: 2%{?dist} +Release: 1%{?dist} License: Python-2.0.1 @@ -71,55 +71,52 @@ License: Python-2.0.1 # If the rpmwheels condition is disabled, we use the bundled wheel packages # from Python with the versions below. # This needs to be manually updated when we update Python. -%global pip_version 24.0 -%global setuptools_version 67.6.1 +%global pip_version 25.0.1 +%global setuptools_version 79.0.1 %global wheel_version 0.40.0 # All of those also include a list of indirect bundled libs: # pip # $ %%{_rpmconfigdir}/pythonbundles.py <(unzip -p Lib/ensurepip/_bundled/pip-*.whl pip/_vendor/vendor.txt) %global pip_bundled_provides %{expand: -Provides: bundled(python3dist(cachecontrol)) = 0.13.1 -Provides: bundled(python3dist(certifi)) = 2023.7.22 -Provides: bundled(python3dist(chardet)) = 5.1 -Provides: bundled(python3dist(colorama)) = 0.4.6 -Provides: bundled(python3dist(distlib)) = 0.3.8 -Provides: bundled(python3dist(distro)) = 1.8 -Provides: bundled(python3dist(idna)) = 3.4 -Provides: bundled(python3dist(msgpack)) = 1.0.5 -Provides: bundled(python3dist(packaging)) = 21.3 -Provides: bundled(python3dist(platformdirs)) = 3.8.1 -Provides: bundled(python3dist(pygments)) = 2.15.1 -Provides: bundled(python3dist(pyparsing)) = 3.1 -Provides: bundled(python3dist(pyproject-hooks)) = 1 -Provides: bundled(python3dist(requests)) = 2.31 +Provides: bundled(python3dist(cachecontrol)) = 0.14.1 +Provides: bundled(python3dist(certifi)) = 2024.8.30 +Provides: bundled(python3dist(distlib)) = 0.3.9 +Provides: bundled(python3dist(distro)) = 1.9 +Provides: bundled(python3dist(idna)) = 3.10 +Provides: bundled(python3dist(msgpack)) = 1.1 +Provides: bundled(python3dist(packaging)) = 24.2 +Provides: bundled(python3dist(platformdirs)) = 4.3.6 +Provides: bundled(python3dist(pygments)) = 2.18 +Provides: bundled(python3dist(pyproject-hooks)) = 1.2 +Provides: bundled(python3dist(requests)) = 2.32.3 Provides: bundled(python3dist(resolvelib)) = 1.0.1 -Provides: bundled(python3dist(rich)) = 13.4.2 -Provides: bundled(python3dist(setuptools)) = 68 -Provides: bundled(python3dist(six)) = 1.16 -Provides: bundled(python3dist(tenacity)) = 8.2.2 -Provides: bundled(python3dist(tomli)) = 2.0.1 -Provides: bundled(python3dist(truststore)) = 0.8 -Provides: bundled(python3dist(typing-extensions)) = 4.7.1 -Provides: bundled(python3dist(urllib3)) = 1.26.17 -Provides: bundled(python3dist(webencodings)) = 0.5.1 +Provides: bundled(python3dist(rich)) = 13.9.4 +Provides: bundled(python3dist(setuptools)) = 70.3 +Provides: bundled(python3dist(tomli)) = 2.2.1 +Provides: bundled(python3dist(truststore)) = 0.10 +Provides: bundled(python3dist(typing-extensions)) = 4.12.2 +Provides: bundled(python3dist(urllib3)) = 1.26.20 } # setuptools -# vendor.txt files not in .whl -# $ %%{_rpmconfigdir}/pythonbundles.py \ -# <(curl -L https://github.com/pypa/setuptools/raw/v%%{setuptools_version}/setuptools/_vendor/vendored.txt) \ -# <(curl -L https://github.com/pypa/setuptools/raw/v%%{setuptools_version}/pkg_resources/_vendor/vendored.txt) +# vendor.txt not in .whl +# %%{_rpmconfigdir}/pythonbundles.py <(unzip -l Lib/test/wheeldata/setuptools-*.whl | grep -E '_vendor/.+dist-info/RECORD' | sed -E 's@^.*/([^-]+)-([^-]+)\.dist-info/.*$@\1==\2@') %global setuptools_bundled_provides %{expand: -Provides: bundled(python3dist(importlib-metadata)) = 6 -Provides: bundled(python3dist(importlib-resources)) = 5.10.2 -Provides: bundled(python3dist(jaraco-text)) = 3.7 -Provides: bundled(python3dist(more-itertools)) = 8.8 -Provides: bundled(python3dist(ordered-set)) = 3.1.1 -Provides: bundled(python3dist(packaging)) = 23 -Provides: bundled(python3dist(platformdirs)) = 2.6.2 +Provides: bundled(python3dist(autocommand)) = 2.2.2 +Provides: bundled(python3dist(backports-tarfile)) = 1.2 +Provides: bundled(python3dist(importlib-metadata)) = 8 +Provides: bundled(python3dist(inflect)) = 7.3.1 +Provides: bundled(python3dist(jaraco-collections)) = 5.1 +Provides: bundled(python3dist(jaraco-context)) = 5.3 +Provides: bundled(python3dist(jaraco-functools)) = 4.0.1 +Provides: bundled(python3dist(jaraco-text)) = 3.12.1 +Provides: bundled(python3dist(more-itertools)) = 10.3 +Provides: bundled(python3dist(packaging)) = 24.2 +Provides: bundled(python3dist(platformdirs)) = 4.2.2 Provides: bundled(python3dist(tomli)) = 2.0.1 -Provides: bundled(python3dist(typing-extensions)) = 4.0.1 -Provides: bundled(python3dist(typing-extensions)) = 4.4 -Provides: bundled(python3dist(zipp)) = 3.7 +Provides: bundled(python3dist(typeguard)) = 4.3 +Provides: bundled(python3dist(typing-extensions)) = 4.12.2 +Provides: bundled(python3dist(wheel)) = 0.45.1 +Provides: bundled(python3dist(zipp)) = 3.19.2 } # wheel # $ %%{_rpmconfigdir}/pythonbundles.py <(unzip -p Lib/test/wheeldata/wheel-*.whl wheel/vendored/vendor.txt) @@ -243,8 +240,7 @@ BuildRequires: bluez-libs-devel BuildRequires: bzip2 BuildRequires: bzip2-devel BuildRequires: desktop-file-utils -# See the runtime requirement in the -libs subpackage -BuildRequires: expat-devel >= 2.6 +BuildRequires: expat-devel BuildRequires: findutils BuildRequires: gcc-c++ @@ -265,12 +261,12 @@ BuildRequires: libnsl2-devel BuildRequires: libtirpc-devel BuildRequires: libGL-devel BuildRequires: libuuid-devel +BuildRequires: libxcrypt-devel BuildRequires: libX11-devel BuildRequires: make BuildRequires: mpdecimal-devel BuildRequires: ncurses-devel -BuildRequires: openssl-devel BuildRequires: pkgconfig BuildRequires: python-rpm-macros BuildRequires: readline-devel @@ -279,11 +275,20 @@ BuildRequires: sqlite-devel BuildRequires: gdb BuildRequires: tar -BuildRequires: tcl-devel +BuildRequires: tcl-devel < 1:9 BuildRequires: tix-devel -BuildRequires: tk-devel +BuildRequires: tk-devel < 1:9 BuildRequires: tzdata +# Support for OpenSSL 4 only landed in Python 3.15 for now +# https://github.com/python/cpython/issues/146207 +BuildRequires: (openssl-devel < 1:4 or openssl3-devel) + +# Perf support is only available on x86_64 and aarch64 right now +%ifarch x86_64 aarch64 +BuildRequires: perf +%endif + %if %{with valgrind} BuildRequires: valgrind-devel %endif @@ -291,6 +296,7 @@ BuildRequires: valgrind-devel BuildRequires: xz-devel BuildRequires: zlib-devel +BuildRequires: systemtap-sdt-devel BuildRequires: /usr/bin/dtrace # workaround http://bugs.python.org/issue19804 (test_uuid requires ifconfig) @@ -302,7 +308,7 @@ BuildRequires: /usr/sbin/ifconfig BuildRequires: %{python_wheel_pkg_prefix}-pip-wheel >= 23.1.2 %if %{with tests} BuildRequires: %{python_wheel_pkg_prefix}-setuptools-wheel -BuildRequires: %{python_wheel_pkg_prefix}-wheel-wheel +BuildRequires: (%{python_wheel_pkg_prefix}-wheel-wheel if %{python_wheel_pkg_prefix}-setuptools-wheel < 71) %endif %endif @@ -341,7 +347,7 @@ Source11: idle3.appdata.xml # (Patches taken from github.com/fedora-python/cpython) -# 00251 # cae5a6abc5df08239c85b83e4e250b6f2702e4f5 +# 00251 # 6a4ec74157aa01f1ada9f29f30a371cd9e5369e8 # Change user install location # # Set values of base and platbase in sysconfig from /usr @@ -369,23 +375,52 @@ Patch251: 00251-change-user-install-location.patch # https://github.com/GrahamDumpleton/mod_wsgi/issues/730 Patch371: 00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch -# 00415 # 5b830b814be638d1a167802780b5f498a4a5e97c -# [CVE-2023-27043] gh-102988: Reject malformed addresses in email.parseaddr() (#111116) +# 00460 # 1da89114f7ee7e7f392128a9861d9c2b41c0ddeb +# gh-132415: Update vendored setuptools in ``Lib/test/wheeldata`` # -# Detect email address parsing errors and return empty tuple to -# indicate the parsing error (old API). Add an optional 'strict' -# parameter to getaddresses() and parseaddr() functions. Patch by -# Thomas Dwyer. -Patch415: 00415-cve-2023-27043-gh-102988-reject-malformed-addresses-in-email-parseaddr-111116.patch +# (actual changes in .whl files removed to make this patch smaller) +# +# gh-127906: Add missing sys import to test_cppext +Patch460: 00460-gh-132415-update-vendored-setuptools-in-lib-test-wheeldata.patch -# 00425 # a563ac3076a00f0f48b3f94ff63d91d37cb4f1e9 -# Only check for 'test/wheeldata' when it's actually used +# 00461 # f7bc103c7bcc6e48789b225e06daf835793e1086 +# Downstream only: Install wheel in test venvs when setuptools < 71 +Patch461: 00461-downstream-only-install-wheel-in-test-venvs-when-setuptools-71.patch + +# 00462 # 5324dc5f57e0068f7e4f7b2f20006e88ff5f4e47 +# Fix PySSL_SetError handling SSL_ERROR_SYSCALL # -# We build Python in Fedora 39+ with option `--with-wheel-pkg-dir` -# pointing to a custom wheel directory and delete the contents of -# upstream's `test/wheeldata`. Don't include the directory in the test set -# if the wheels are used from a different location. -Patch425: 00425-only-check-for-test-wheeldata-when-it-s-actually-used.patch +# Python 3.10 changed from using SSL_write() and SSL_read() to SSL_write_ex() and +# SSL_read_ex(), but did not update handling of the return value. +# +# Change error handling so that the return value is not examined. +# OSError (not EOF) is now returned when retval is 0. +# +# This resolves the issue of failing tests when a system is +# stressed on OpenSSL 3.5. +Patch462: 00462-fix-pyssl_seterror-handling-ssl_error_syscall.patch + +# 00474 # 837ddca0372fa87ff9cee47142200caa21e77def +# CVE-2025-15366 +# +# gh-143921: Reject control characters in IMAP commands +# +# (cherry-picked from commit 6262704b134db2a4ba12e85ecfbd968534f28b45) +Patch474: 00474-cve-2025-15366.patch + +# 00475 # 3748209a316662d4e85981ca1a7418547a1d25c6 +# CVE-2025-15367 +# +# gh-143923: Reject control characters in POP3 commands +# +# (cherry-picked from commit b234a2b67539f787e191d2ef19a7cbdce32874e7) +Patch475: 00475-cve-2025-15367.patch + +# 00494 # 430aab133397ed44cc9ee621fd311e02fee317b5 +# Increase the timeout of test_large_content_length_truncated +# +# It has started to fail randomly when run on s390x architecture. +Patch494: 00494-increase-the-timeout-of-test_large_content_length_truncated.patch # (New patches go here ^^^) # @@ -539,12 +574,24 @@ Recommends: (%{pkgname}-tkinter%{?_isa} = %{version}-%{release} if tk%{?_isa}) Requires: tzdata # The requirement on libexpat is generated, but we need to version it. -# When built with expat >= 2.6, but installed with older expat, we get: +# When built with a specific expat version, but installed with an older one, +# we sometimes get: # ImportError: /usr/lib64/python3.X/lib-dynload/pyexpat.cpython-....so: -# undefined symbol: XML_SetReparseDeferralEnabled +# undefined symbol: XML_... +# The pyexpat module has build-time checks for expat version to only use the +# available symbols. However, there is no runtime protection, so when the module +# is later installed with an older expat, it may error due to undefined symbols. # This breaks many things, including python -m venv. +# We avoid this problem by requiring at least the same version of expat that +# was used during the build time. # Other subpackages (like -debug) also need this, but they all depend on -libs. -Requires: expat >= 2.6 +# Since expat 2.7.4, the library has versioned symbols and this is no longer needed, +# as the generated requirement will be in the form of libexpat.so.1(LIBEXPAT_2.7.2) etc. +%global expat_version %(LANG=C rpm -q --qf '%%{version}' expat.%{_target_cpu} | sed 's/.*not installed/0/') +%if v"%{expat_version}" < v"2.7.4" +Requires: expat%{?_isa} >= %{expat_version} +%endif + %description -n %{pkgname}-libs This package contains runtime libraries for use by Python: @@ -649,7 +696,7 @@ Requires: %{pkgname}-libs%{?_isa} = %{version}-%{release} %if %{with rpmwheels} Requires: %{python_wheel_pkg_prefix}-setuptools-wheel -Requires: %{python_wheel_pkg_prefix}-wheel-wheel +Requires: (%{python_wheel_pkg_prefix}-wheel-wheel if %{python_wheel_pkg_prefix}-setuptools-wheel < 71) %else Provides: bundled(python3dist(setuptools)) = %{setuptools_version} %setuptools_bundled_provides @@ -717,6 +764,7 @@ The debug runtime additionally supports debug builds of C-API extensions if [ -f %{_rpmconfigdir}/pythonbundles.py ]; then %{_rpmconfigdir}/pythonbundles.py <(unzip -p Lib/ensurepip/_bundled/pip-*.whl pip/_vendor/vendor.txt) --compare-with '%pip_bundled_provides' %{_rpmconfigdir}/pythonbundles.py <(unzip -p Lib/test/wheeldata/wheel-*.whl wheel/vendored/vendor.txt) --compare-with '%wheel_bundled_provides' + %{_rpmconfigdir}/pythonbundles.py <(unzip -l Lib/test/wheeldata/setuptools-*.whl | grep -E '_vendor/.+dist-info/RECORD' | sed -E 's@^.*/([^-]+)-([^-]+)\.dist-info/.*$@\1==\2@') --compare-with '%setuptools_bundled_provides' fi %if %{with rpmwheels} @@ -818,7 +866,6 @@ BuildPython() { --with-computed-gotos=%{computed_gotos_flag} \ --with-dbmliborder=gdbm:ndbm:bdb \ --with-system-expat \ - --with-system-ffi \ --with-system-libmpdec \ --enable-loadable-sqlite-extensions \ --with-dtrace \ @@ -1122,6 +1169,11 @@ for file in %{buildroot}%{pylibdir}/pydoc_data/topics.py $(grep --include='*.py' rm ${directory}/{__pycache__/${module}.cpython-%{pyshortver}.opt-?.pyc,${module}.py} done +%if %{without rpmwheels} +# Inject SBOM into the installed wheels (if the macro is available) +%{?python_wheel_inject_sbom:%python_wheel_inject_sbom %{buildroot}%{pylibdir}/ensurepip/_bundled/*.whl} +%endif + # ====================================================== # Checks for packaging issues # ====================================================== @@ -1183,11 +1235,13 @@ CheckPython() { # test_check_probes is failing since it was introduced in 3.12.0rc1, # the test is skipped until it is fixed in upstream. # see: https://github.com/python/cpython/issues/104280#issuecomment-1669249980 + # test_gdb is skipped due to https://bugzilla.redhat.com/2275274#c11 LD_LIBRARY_PATH=$ConfDir $ConfDir/python -m test.regrtest \ -wW --slowest %{_smp_mflags} --timeout=2700 \ -i test_freeze_simple_script \ -i test_check_probes \ + -x test_gdb \ %ifarch %{mips64} -x test_ctypes \ %endif @@ -1704,6 +1758,119 @@ CheckPython optimized # ====================================================== %changelog +* Thu Aug 13 2026 Karolina Surma - 3.12.14-1 +- Update to Python 3.12.14 + +* Tue Jul 28 2026 Lukáš Zachar - 3.12.13-6 +- Security fix for CVE-2026-15308 +Resolves: rhbz#2498688 + +* Tue Jul 28 2026 Miro Hrončok - 3.12.13-5 +- Skip UDP Lite tests if it's not supported +- Fixes FTBFS on Linux kernel 7.1 and newer + +* Thu Jul 16 2026 Fedora Release Engineering - 3.12.13-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_45_Mass_Rebuild + +* Thu Apr 16 2026 Charalampos Stratakis - 3.12.13-3 +- Security fixes for CVE-2026-1502, CVE-2026-4786, CVE-2026-6100, CVE-2026-2297, CVE-2026-3644, CVE-2026-4224 +Resolves: rhbz#2444705, rhbz#2448189, rhbz#2448205, rhbz#2457942, rhbz#2458014, rhbz#2458222 + +* Thu Mar 26 2026 Lumír Balhar - 3.12.13-2 +- Security fix for CVE-2026-4519 (rhbz#2449728) + +* Tue Mar 03 2026 Tomáš Hrnčiar - 3.12.13-1 +- Update to 3.12.13 + +* Fri Feb 06 2026 Tomáš Hrnčiar - 3.12.12-4 +- Security fixes for CVE-2026-0865, CVE-2025-15366 and CVE-2025-15367 + +* Fri Jan 16 2026 Lumír Balhar - 3.12.12-3 +- Security fix for CVE-2025-13836 + +* Tue Jan 06 2026 Lumír Balhar - 3.12.12-2 +- Security fix for CVE-2025-12084 +- Require at least the same expat version as used during the build time + +* Fri Oct 10 2025 Karolina Surma - 3.12.12-1 +- Update to 3.12.12 + +* Fri Jul 25 2025 Fedora Release Engineering - 3.12.11-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild + +* Thu Jun 12 2025 Charalampos Stratakis - 3.12.11-2 +- Enable PAC and BTI hardware protections for aarch64 + +* Wed Jun 04 2025 Tomáš Hrnčiar - 3.12.11-1 +- Update to 3.12.11 + +* Fri May 09 2025 Charalampos Stratakis - 3.12.10-4 +- Fix PySSL_SetError handling SSL_ERROR_SYSCALL +- This fixes random flakiness of test_ssl on stressed machines + +* Tue May 06 2025 Miro Hrončok - 3.12.10-3 +- Drop requirement on python-wheel-wheel with setuptools >= 71 + +* Tue Apr 22 2025 Charalampos Stratakis - 3.12.10-2 +- Apply Intel's CET for mitigation against control-flow hijacking attacks + +* Wed Apr 09 2025 Miro Hrončok - 3.12.10-1 +- Update to 3.12.10 + +* Mon Mar 31 2025 Charalampos Stratakis - 3.12.9-3 +- Properly apply exported CFLAGS for dtrace/systemtap builds +- Fixes: rhbz#2356301 + +* Thu Feb 06 2025 Miro Hrončok - 3.12.9-2 +- Rebuilt with mpdecimal 4.0.0 + +* Tue Feb 04 2025 Charalampos Stratakis - 3.12.9-1 +- Update to 3.12.9 +- Security fix for CVE-2025-0938 +- Fixes: rhbz#2343275 + +* Sat Feb 01 2025 Björn Esser - 3.12.8-4 +- Add explicit BR: libxcrypt-devel + +* Sat Jan 18 2025 Fedora Release Engineering - 3.12.8-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild + +* Fri Dec 06 2024 Charalampos Stratakis - 3.12.8-2 +- Security fix for CVE-2024-12254 +- Fixes: rhbz#2330926 + +* Tue Dec 03 2024 Charalampos Stratakis - 3.12.8-1 +- Update to 3.12.8 +- Security fix for CVE-2024-9287 +- Fixes: rhbz#2321656 + +* Tue Oct 01 2024 Tomáš Hrnčiar - 3.12.7-1 +- Update to 3.12.7 + +* Mon Sep 09 2024 Tomáš Hrnčiar - 3.12.6-1 +- Update to 3.12.6 +- Fixes: rhbz#2310090 + +* Fri Aug 23 2024 Charalampos Stratakis - 3.12.5-2 +- Security fix for CVE-2024-8088 +- Fixes: rhbz#2307461 + +* Wed Aug 07 2024 Tomáš Hrnčiar - 3.12.5-1 +- Update to 3.12.5 +- Fixes: rhbz#2303159 (email header injection) + +* Tue Jul 23 2024 Lumír Balhar - 3.12.4-3 +- Require systemtap-sdt-devel for sys/sdt.h + +* Fri Jul 19 2024 Fedora Release Engineering - 3.12.4-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild + +* Fri Jun 07 2024 Tomáš Hrnčiar - 3.12.4-1 +- Update to 3.12.4 + +* Thu Jun 06 2024 Python Maint - 3.12.3-3 +- Build as non-main Python + * Wed Apr 17 2024 Miro Hrončok - 3.12.3-2 - Require expat >= 2.6 to prevent errors when creating venvs with older expat diff --git a/rpminspect.yaml b/rpminspect.yaml index 83dfb5e..8cc18cb 100644 --- a/rpminspect.yaml +++ b/rpminspect.yaml @@ -1,22 +1,22 @@ # exclude test XML data (not always valid) from XML validity check: xml: ignore: - - /usr/lib*/python*/test/xmltestdata/* - - /usr/lib*/python*/test/xmltestdata/*/* + - '/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.*: + '/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 + - '/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 diff --git a/sources b/sources index a31bb26..f116187 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (Python-3.12.3.tar.xz) = 4a2213b108e7f1f1525baa8348e68b2a2336d925e60d0a59f0225fc470768a2c8031edafc0b8243f94dbae18afda335ee5adf2785328c2218fd64cbb439f13a4 -SHA512 (Python-3.12.3.tar.xz.asc) = c291ec5b5e4f8deba867cc517624dd9a174745f04061ef737e58f3d52b9b30318264aec350e339fe88ccb493809ca1a90a378e86d86b8ec4a4f578b1a5843624 +SHA512 (Python-3.12.14.tar.xz) = 9007399ffdd3a493c91a98cd7a6cb93acfb8de80f3be2f5480cda36f134d49b5043a60bc6b5c62ed18cc6a2e4e3c81cb7556ac5f337e2cd58ff3449a8099ed22 +SHA512 (Python-3.12.14.tar.xz.asc) = 69cc4757f5d79ea46f9b632d5b34f9f16855cb1f767f77c827ad65546ba8f77b68e75a661ebc4e4f453edd7a98a73d916491597f67d4fed9c891aa599a869324 diff --git a/tests/provision.fmf b/tests/provision.fmf deleted file mode 100644 index 1a4f0f0..0000000 --- a/tests/provision.fmf +++ /dev/null @@ -1,4 +0,0 @@ ---- -standard-inventory-qcow2: - qemu: - m: 3G # Amount of VM memory diff --git a/tests/tests.yml b/tests/tests.yml deleted file mode 100644 index cc1e061..0000000 --- a/tests/tests.yml +++ /dev/null @@ -1,56 +0,0 @@ ---- -- hosts: localhost - tags: - - classic - tasks: - - dnf: - name: "*" - state: latest - -- hosts: localhost - roles: - - role: standard-test-basic - tags: - - classic - repositories: - - repo: "https://src.fedoraproject.org/tests/python.git" - dest: "python" - pybasever: "3.12" - tests: - - rpm_qa: - run: rpm -qa - - smoke: - dir: python/smoke - run: "VERSION={{ pybasever }} ./venv.sh" - - smoke_virtualenv: - dir: python/smoke - run: "VERSION={{ pybasever }} METHOD=virtualenv ./venv.sh" - - debugsmoke: - dir: python/smoke - run: "PYTHON=python{{ pybasever }}d TOX=false VERSION={{ pybasever }} ./venv.sh" - - selftest: - dir: python/selftest - run: "VERSION={{ pybasever }} X='-i test_check_probes' ./parallel.sh" - - debugtest: - dir: python/selftest - run: "VERSION={{ pybasever }} PYTHON=python{{ pybasever }}d X='-i test_check_probes' ./parallel.sh" - - debugflags: - dir: python/flags - run: "python{{ pybasever }}d ./assertflags.py -O0" - - marshalparser: - dir: python/marshalparser - run: "VERSION={{ pybasever }} SAMPLE=10 test_marshalparser_compatibility.sh" - required_packages: - - gcc # for extension building in venv and selftest - - gcc-c++ # for test_cppext - - gdb # for test_gdb - - "python{{ pybasever }}" # the test subject - - "python{{ pybasever }}-debug" # for leak testing - - "python{{ pybasever }}-devel" # for extension building in venv and selftest - - "python{{ pybasever }}-tkinter" # for selftest - - "python{{ pybasever }}-test" # for selftest - - tox # for venv tests - - virtualenv # for virtualenv tests - - glibc-all-langpacks # for locale tests - - marshalparser # for testing compatibility (magic numbers) with marshalparser - - rpm # for debugging