diff --git a/CVE-2025-4516-DecodeError-handler.patch b/CVE-2025-4516-DecodeError-handler.patch new file mode 100644 index 0000000..a8b554d --- /dev/null +++ b/CVE-2025-4516-DecodeError-handler.patch @@ -0,0 +1,426 @@ +From 0d5d68f7075788b6912f8632dc841dca97ece409 Mon Sep 17 00:00:00 2001 +From: Serhiy Storchaka +Date: Tue, 20 May 2025 15:46:57 +0300 +Subject: [PATCH] [3.9] gh-133767: Fix use-after-free in the unicode-escape + decoder with an error handler (GH-129648) (GH-133944) + +If the error handler is used, a new bytes object is created to set as +the object attribute of UnicodeDecodeError, and that bytes object then +replaces the original data. A pointer to the decoded data will became invalid +after destroying that temporary bytes object. So we need other way to return +the first invalid escape from _PyUnicode_DecodeUnicodeEscapeInternal(). + +_PyBytes_DecodeEscape() does not have such issue, because it does not +use the error handlers registry, but it should be changed for compatibility +with _PyUnicode_DecodeUnicodeEscapeInternal(). +(cherry picked from commit 9f69a58623bd01349a18ba0c7a9cb1dad6a51e8e) +(cherry picked from commit 6279eb8c076d89d3739a6edb393e43c7929b429d) +(cherry picked from commit a75953b347716fff694aa59a7c7c2489fa50d1f5) +(cherry picked from commit 0c33e5baedf18ebcb04bc41dff7cfc614d5ea5fe) +(cherry picked from commit 8b528cacbbde60504f6ac62784d04889d285f18b) + +Co-authored-by: Serhiy Storchaka +--- + Include/cpython/bytesobject.h | 4 + Include/cpython/unicodeobject.h | 13 ++ + Lib/test/test_codeccallbacks.py | 37 ++++++++ + Lib/test/test_codecs.py | 39 ++++++-- + Misc/NEWS.d/next/Security/2025-05-09-20-22-54.gh-issue-133767.kN2i3Q.rst | 2 + Objects/bytesobject.c | 40 ++++++-- + Objects/unicodeobject.c | 45 +++++++--- + Parser/pegen/parse_string.c | 24 +++-- + 8 files changed, 164 insertions(+), 40 deletions(-) + create mode 100644 Misc/NEWS.d/next/Security/2025-05-09-20-22-54.gh-issue-133767.kN2i3Q.rst + +--- a/Include/cpython/bytesobject.h ++++ b/Include/cpython/bytesobject.h +@@ -25,6 +25,10 @@ PyAPI_FUNC(PyObject*) _PyBytes_FromHex( + int use_bytearray); + + /* Helper for PyBytes_DecodeEscape that detects invalid escape chars. */ ++PyAPI_FUNC(PyObject*) _PyBytes_DecodeEscape2(const char *, Py_ssize_t, ++ const char *, ++ int *, const char **); ++// Export for binary compatibility. + PyAPI_FUNC(PyObject *) _PyBytes_DecodeEscape(const char *, Py_ssize_t, + const char *, const char **); + +--- a/Include/cpython/unicodeobject.h ++++ b/Include/cpython/unicodeobject.h +@@ -866,6 +866,19 @@ PyAPI_FUNC(PyObject*) _PyUnicode_DecodeU + ); + /* Helper for PyUnicode_DecodeUnicodeEscape that detects invalid escape + chars. */ ++PyAPI_FUNC(PyObject*) _PyUnicode_DecodeUnicodeEscapeInternal2( ++ const char *string, /* Unicode-Escape encoded string */ ++ Py_ssize_t length, /* size of string */ ++ const char *errors, /* error handling */ ++ Py_ssize_t *consumed, /* bytes consumed */ ++ int *first_invalid_escape_char, /* on return, if not -1, contain the first ++ invalid escaped char (<= 0xff) or invalid ++ octal escape (> 0xff) in string. */ ++ const char **first_invalid_escape_ptr); /* on return, if not NULL, may ++ point to the first invalid escaped ++ char in string. ++ May be NULL if errors is not NULL. */ ++// Export for binary compatibility. + PyAPI_FUNC(PyObject*) _PyUnicode_DecodeUnicodeEscapeInternal( + const char *string, /* Unicode-Escape encoded string */ + Py_ssize_t length, /* size of string */ +--- a/Lib/test/test_codeccallbacks.py ++++ b/Lib/test/test_codeccallbacks.py +@@ -1,6 +1,7 @@ + import codecs + import html.entities + import itertools ++import re + import sys + import unicodedata + import unittest +@@ -1124,7 +1125,7 @@ class CodecCallbackTest(unittest.TestCas + text = 'abcghi'*n + text.translate(charmap) + +- def test_mutatingdecodehandler(self): ++ def test_mutating_decode_handler(self): + baddata = [ + ("ascii", b"\xff"), + ("utf-7", b"++"), +@@ -1159,6 +1160,40 @@ class CodecCallbackTest(unittest.TestCas + for (encoding, data) in baddata: + self.assertEqual(data.decode(encoding, "test.mutating"), "\u4242") + ++ def test_mutating_decode_handler_unicode_escape(self): ++ decode = codecs.unicode_escape_decode ++ def mutating(exc): ++ if isinstance(exc, UnicodeDecodeError): ++ r = data.get(exc.object[:exc.end]) ++ if r is not None: ++ exc.object = r[0] + exc.object[exc.end:] ++ return ('\u0404', r[1]) ++ raise AssertionError("don't know how to handle %r" % exc) ++ ++ codecs.register_error('test.mutating2', mutating) ++ data = { ++ br'\x0': (b'\\', 0), ++ br'\x3': (b'xxx\\', 3), ++ br'\x5': (b'x\\', 1), ++ } ++ def check(input, expected, msg): ++ with self.assertWarns(DeprecationWarning) as cm: ++ self.assertEqual(decode(input, 'test.mutating2'), (expected, len(input))) ++ self.assertIn(msg, str(cm.warning)) ++ ++ check(br'\x0n\z', '\u0404\n\\z', r"invalid escape sequence '\z'") ++ check(br'\x0z', '\u0404\\z', r"invalid escape sequence '\z'") ++ ++ check(br'\x3n\zr', '\u0404\n\\zr', r"invalid escape sequence '\z'") ++ check(br'\x3zr', '\u0404\\zr', r"invalid escape sequence '\z'") ++ check(br'\x3z5', '\u0404\\z5', r"invalid escape sequence '\z'") ++ check(memoryview(br'\x3z5x')[:-1], '\u0404\\z5', r"invalid escape sequence '\z'") ++ check(memoryview(br'\x3z5xy')[:-2], '\u0404\\z5', r"invalid escape sequence '\z'") ++ ++ check(br'\x5n\z', '\u0404\n\\z', r"invalid escape sequence '\z'") ++ check(br'\x5z', '\u0404\\z', r"invalid escape sequence '\z'") ++ check(memoryview(br'\x5zy')[:-1], '\u0404\\z', r"invalid escape sequence '\z'") ++ + # issue32583 + def test_crashing_decode_handler(self): + # better generating one more character to fill the extra space slot +--- a/Lib/test/test_codecs.py ++++ b/Lib/test/test_codecs.py +@@ -1178,20 +1178,32 @@ class EscapeDecodeTest(unittest.TestCase + check(br"[\501]", b"[A]") + check(br"[\x41]", b"[A]") + check(br"[\x410]", b"[A0]") ++ ++ def test_warnings(self): ++ decode = codecs.escape_decode ++ check = coding_checker(self, decode) + for i in range(97, 123): + b = bytes([i]) + if b not in b'abfnrtvx': +- with self.assertWarns(DeprecationWarning): ++ with self.assertWarnsRegex(DeprecationWarning, ++ r"invalid escape sequence '\\%c'" % i): + check(b"\\" + b, b"\\" + b) +- with self.assertWarns(DeprecationWarning): ++ with self.assertWarnsRegex(DeprecationWarning, ++ r"invalid escape sequence '\\%c'" % (i-32)): + check(b"\\" + b.upper(), b"\\" + b.upper()) +- with self.assertWarns(DeprecationWarning): ++ with self.assertWarnsRegex(DeprecationWarning, ++ r"invalid escape sequence '\\8'"): + check(br"\8", b"\\8") + with self.assertWarns(DeprecationWarning): + check(br"\9", b"\\9") +- with self.assertWarns(DeprecationWarning): ++ with self.assertWarnsRegex(DeprecationWarning, ++ r"invalid escape sequence '\\\xfa'") as cm: + check(b"\\\xfa", b"\\\xfa") + ++ with self.assertWarnsRegex(DeprecationWarning, ++ r"invalid escape sequence '\\z'"): ++ self.assertEqual(decode(br'\x\z', 'ignore'), (b'\\z', 4)) ++ + def test_errors(self): + decode = codecs.escape_decode + self.assertRaises(ValueError, decode, br"\x") +@@ -2393,20 +2405,31 @@ class UnicodeEscapeTest(ReadTest, unitte + check(br"[\x410]", "[A0]") + check(br"\u20ac", "\u20ac") + check(br"\U0001d120", "\U0001d120") ++ ++ def test_decode_warnings(self): ++ decode = codecs.unicode_escape_decode ++ check = coding_checker(self, decode) + for i in range(97, 123): + b = bytes([i]) + if b not in b'abfnrtuvx': +- with self.assertWarns(DeprecationWarning): ++ with self.assertWarnsRegex(DeprecationWarning, ++ r"invalid escape sequence '\\%c'" % i): + check(b"\\" + b, "\\" + chr(i)) + if b.upper() not in b'UN': +- with self.assertWarns(DeprecationWarning): ++ with self.assertWarnsRegex(DeprecationWarning, ++ r"invalid escape sequence '\\%c'" % (i-32)): + check(b"\\" + b.upper(), "\\" + chr(i-32)) +- with self.assertWarns(DeprecationWarning): ++ with self.assertWarnsRegex(DeprecationWarning, ++ r"invalid escape sequence '\\8'"): + check(br"\8", "\\8") + with self.assertWarns(DeprecationWarning): + check(br"\9", "\\9") +- with self.assertWarns(DeprecationWarning): ++ with self.assertWarnsRegex(DeprecationWarning, ++ r"invalid escape sequence '\\\xfa'") as cm: + check(b"\\\xfa", "\\\xfa") ++ with self.assertWarnsRegex(DeprecationWarning, ++ r"invalid escape sequence '\\z'"): ++ self.assertEqual(decode(br'\x\z', 'ignore'), ('\\z', 4)) + + def test_decode_errors(self): + decode = codecs.unicode_escape_decode +--- /dev/null ++++ b/Misc/NEWS.d/next/Security/2025-05-09-20-22-54.gh-issue-133767.kN2i3Q.rst +@@ -0,0 +1,2 @@ ++Fix use-after-free in the "unicode-escape" decoder with a non-"strict" error ++handler. +--- a/Objects/bytesobject.c ++++ b/Objects/bytesobject.c +@@ -1060,10 +1060,11 @@ _PyBytes_FormatEx(const char *format, Py + } + + /* Unescape a backslash-escaped string. */ +-PyObject *_PyBytes_DecodeEscape(const char *s, ++PyObject *_PyBytes_DecodeEscape2(const char *s, + Py_ssize_t len, + const char *errors, +- const char **first_invalid_escape) ++ int *first_invalid_escape_char, ++ const char **first_invalid_escape_ptr) + { + int c; + char *p; +@@ -1077,7 +1078,8 @@ PyObject *_PyBytes_DecodeEscape(const ch + return NULL; + writer.overallocate = 1; + +- *first_invalid_escape = NULL; ++ *first_invalid_escape_char = -1; ++ *first_invalid_escape_ptr = NULL; + + end = s + len; + while (s < end) { +@@ -1152,9 +1154,10 @@ PyObject *_PyBytes_DecodeEscape(const ch + break; + + default: +- if (*first_invalid_escape == NULL) { +- *first_invalid_escape = s-1; /* Back up one char, since we've +- already incremented s. */ ++ if (*first_invalid_escape_char == -1) { ++ *first_invalid_escape_char = (unsigned char)s[-1]; ++ /* Back up one char, since we've already incremented s. */ ++ *first_invalid_escape_ptr = s - 1; + } + *p++ = '\\'; + s--; +@@ -1168,21 +1171,36 @@ PyObject *_PyBytes_DecodeEscape(const ch + return NULL; + } + ++// Export for binary compatibility. ++PyObject *_PyBytes_DecodeEscape(const char *s, ++ Py_ssize_t len, ++ const char *errors, ++ const char **first_invalid_escape) ++{ ++ int first_invalid_escape_char; ++ return _PyBytes_DecodeEscape2( ++ s, len, errors, ++ &first_invalid_escape_char, ++ first_invalid_escape); ++} ++ + PyObject *PyBytes_DecodeEscape(const char *s, + Py_ssize_t len, + const char *errors, + Py_ssize_t Py_UNUSED(unicode), + const char *Py_UNUSED(recode_encoding)) + { +- const char* first_invalid_escape; +- PyObject *result = _PyBytes_DecodeEscape(s, len, errors, +- &first_invalid_escape); ++ int first_invalid_escape_char; ++ const char *first_invalid_escape_ptr; ++ PyObject *result = _PyBytes_DecodeEscape2(s, len, errors, ++ &first_invalid_escape_char, ++ &first_invalid_escape_ptr); + if (result == NULL) + return NULL; +- if (first_invalid_escape != NULL) { ++ if (first_invalid_escape_char != -1) { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "invalid escape sequence '\\%c'", +- (unsigned char)*first_invalid_escape) < 0) { ++ first_invalid_escape_char) < 0) { + Py_DECREF(result); + return NULL; + } +--- a/Objects/unicodeobject.c ++++ b/Objects/unicodeobject.c +@@ -6278,20 +6278,23 @@ PyUnicode_AsUTF16String(PyObject *unicod + static _PyUnicode_Name_CAPI *ucnhash_CAPI = NULL; + + PyObject * +-_PyUnicode_DecodeUnicodeEscapeInternal(const char *s, ++_PyUnicode_DecodeUnicodeEscapeInternal2(const char *s, + Py_ssize_t size, + const char *errors, + Py_ssize_t *consumed, +- const char **first_invalid_escape) ++ int *first_invalid_escape_char, ++ const char **first_invalid_escape_ptr) + { + const char *starts = s; ++ const char *initial_starts = starts; + _PyUnicodeWriter writer; + const char *end; + PyObject *errorHandler = NULL; + PyObject *exc = NULL; + + // so we can remember if we've seen an invalid escape char or not +- *first_invalid_escape = NULL; ++ *first_invalid_escape_char = -1; ++ *first_invalid_escape_ptr = NULL; + + if (size == 0) { + if (consumed) { +@@ -6474,9 +6477,12 @@ _PyUnicode_DecodeUnicodeEscapeInternal(c + goto error; + + default: +- if (*first_invalid_escape == NULL) { +- *first_invalid_escape = s-1; /* Back up one char, since we've +- already incremented s. */ ++ if (*first_invalid_escape_char == -1) { ++ *first_invalid_escape_char = c; ++ if (starts == initial_starts) { ++ /* Back up one char, since we've already incremented s. */ ++ *first_invalid_escape_ptr = s - 1; ++ } + } + WRITE_ASCII_CHAR('\\'); + WRITE_CHAR(c); +@@ -6515,22 +6521,39 @@ _PyUnicode_DecodeUnicodeEscapeInternal(c + return NULL; + } + ++// Export for binary compatibility. ++PyObject * ++_PyUnicode_DecodeUnicodeEscapeInternal(const char *s, ++ Py_ssize_t size, ++ const char *errors, ++ Py_ssize_t *consumed, ++ const char **first_invalid_escape) ++{ ++ int first_invalid_escape_char; ++ return _PyUnicode_DecodeUnicodeEscapeInternal2( ++ s, size, errors, consumed, ++ &first_invalid_escape_char, ++ first_invalid_escape); ++} ++ + PyObject * + _PyUnicode_DecodeUnicodeEscapeStateful(const char *s, + Py_ssize_t size, + const char *errors, + Py_ssize_t *consumed) + { +- const char *first_invalid_escape; +- PyObject *result = _PyUnicode_DecodeUnicodeEscapeInternal(s, size, errors, ++ int first_invalid_escape_char; ++ const char *first_invalid_escape_ptr; ++ PyObject *result = _PyUnicode_DecodeUnicodeEscapeInternal2(s, size, errors, + consumed, +- &first_invalid_escape); ++ &first_invalid_escape_char, ++ &first_invalid_escape_ptr); + if (result == NULL) + return NULL; +- if (first_invalid_escape != NULL) { ++ if (first_invalid_escape_char != -1) { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "invalid escape sequence '\\%c'", +- (unsigned char)*first_invalid_escape) < 0) { ++ first_invalid_escape_char) < 0) { + Py_DECREF(result); + return NULL; + } +--- a/Parser/pegen/parse_string.c ++++ b/Parser/pegen/parse_string.c +@@ -119,12 +119,15 @@ decode_unicode_with_escapes(Parser *pars + len = p - buf; + s = buf; + +- const char *first_invalid_escape; +- v = _PyUnicode_DecodeUnicodeEscapeInternal(s, len, NULL, NULL, &first_invalid_escape); ++ int first_invalid_escape_char; ++ const char *first_invalid_escape_ptr; ++ v = _PyUnicode_DecodeUnicodeEscapeInternal2(s, (Py_ssize_t)len, NULL, NULL, ++ &first_invalid_escape_char, ++ &first_invalid_escape_ptr); + +- if (v != NULL && first_invalid_escape != NULL) { +- if (warn_invalid_escape_sequence(parser, *first_invalid_escape, t) < 0) { +- /* We have not decref u before because first_invalid_escape points ++ if (v != NULL && first_invalid_escape_ptr != NULL) { ++ if (warn_invalid_escape_sequence(parser, *first_invalid_escape_ptr, t) < 0) { ++ /* We have not decref u before because first_invalid_escape_ptr points + inside u. */ + Py_XDECREF(u); + Py_DECREF(v); +@@ -138,14 +141,17 @@ decode_unicode_with_escapes(Parser *pars + static PyObject * + decode_bytes_with_escapes(Parser *p, const char *s, Py_ssize_t len, Token *t) + { +- const char *first_invalid_escape; +- PyObject *result = _PyBytes_DecodeEscape(s, len, NULL, &first_invalid_escape); ++ int first_invalid_escape_char; ++ const char *first_invalid_escape_ptr; ++ PyObject *result = _PyBytes_DecodeEscape2(s, len, NULL, ++ &first_invalid_escape_char, ++ &first_invalid_escape_ptr); + if (result == NULL) { + return NULL; + } + +- if (first_invalid_escape != NULL) { +- if (warn_invalid_escape_sequence(p, *first_invalid_escape, t) < 0) { ++ if (first_invalid_escape_ptr != NULL) { ++ if (warn_invalid_escape_sequence(p, *first_invalid_escape_ptr, t) < 0) { + Py_DECREF(result); + return NULL; + } diff --git a/python39.changes b/python39.changes index e81b29d..71b9a11 100644 --- a/python39.changes +++ b/python39.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------- +Thu May 22 13:01:17 UTC 2025 - Matej Cepl + +- Add CVE-2025-4516-DecodeError-handler.patch fixing + CVE-2025-4516 (bsc#1243273) blocking DecodeError handling + vulnerability, which could lead to DoS. + ------------------------------------------------------------------- Sat May 10 11:38:21 UTC 2025 - Matej Cepl @@ -354,12 +361,12 @@ Fri Feb 23 01:06:42 UTC 2024 - Matej Cepl - Repurpose skip-failing-tests.patch to increase timeout for test.test_asyncio.test_tasks.TimeoutTests.test_timeout_time, which fails on slow machines in IBS (s390x). - + ------------------------------------------------------------------- Tue Feb 20 22:14:02 UTC 2024 - Matej Cepl - Remove double definition of /usr/bin/idle%%{version} in - %%files. + %%files. ------------------------------------------------------------------- Thu Feb 15 10:29:07 UTC 2024 - Daniel Garcia @@ -498,7 +505,7 @@ Wed May 3 14:09:37 UTC 2023 - Matej Cepl ------------------------------------------------------------------- Tue Apr 18 05:00:11 UTC 2023 - Steve Kowalik -- Use python3 modules to build the documentation. +- Use python3 modules to build the documentation. ------------------------------------------------------------------- Wed Mar 1 14:43:31 UTC 2023 - Matej Cepl @@ -1071,7 +1078,7 @@ Sat Mar 26 22:22:24 UTC 2022 - Matej Cepl Tue Feb 22 05:53:06 UTC 2022 - Steve Kowalik - Add patch support-expat-245.patch: - * Support Expat >= 2.4.5 + * Support Expat >= 2.4.5 ------------------------------------------------------------------- Wed Jan 19 21:50:04 UTC 2022 - Matej Cepl @@ -1514,7 +1521,7 @@ Sat Jun 5 21:21:38 UTC 2021 - Matej Cepl ------------------------------------------------------------------- Fri Jun 4 21:36:30 UTC 2021 - Dirk Müller -- allow build with Sphinx >= 3.x +- allow build with Sphinx >= 3.x ------------------------------------------------------------------- Wed Jun 2 13:12:04 UTC 2021 - Dan Čermák @@ -2066,7 +2073,7 @@ Sat Dec 12 14:29:33 UTC 2020 - Matej Cepl Thu Dec 10 00:26:51 UTC 2020 - Benjamin Greiner - Last try before this results in an editwar: - * remove importlib_resources and importlib-metadata + * remove importlib_resources and importlib-metadata provides/obsoletes * import importlib_resources is not the same as import importlib.resources, same for metadata @@ -2183,54 +2190,54 @@ Tue Jul 21 09:53:06 UTC 2020 - Callum Farmer - Removed CVE-2019-20907_tarfile-inf-loop.patch: fixed in upstream - Removed recursion.tar: contained in upstream - Update to 3.9.0b5: - - bpo-41304: Fixes python3x._pth being ignored on Windows, caused + - bpo-41304: Fixes python3x._pth being ignored on Windows, caused by the fix for bpo-29778 (CVE-2020-15801). - bpo-41162: Audit hooks are now cleared later during finalization to avoid missing events. - - bpo-29778: Ensure python3.dll is loaded from correct locations + - bpo-29778: Ensure python3.dll is loaded from correct locations when Python is embedded (CVE-2020-15523). - - bpo-39603: Prevent http header injection by rejecting control + - bpo-39603: Prevent http header injection by rejecting control characters in http.client.putrequest(…). - bpo-41295: Resolve a regression in CPython 3.8.4 where defining - “__setattr__” in a multi-inheritance setup and + “__setattr__” in a multi-inheritance setup and calling up the hierarchy chain could fail if builtins/extension types were involved in the base types. - - bpo-41247: Always cache the running loop holder when running + - bpo-41247: Always cache the running loop holder when running asyncio.set_running_loop. - - bpo-41252: Fix incorrect refcounting in + - bpo-41252: Fix incorrect refcounting in _ssl.c’s _servername_callback(). - - bpo-41215: Use non-NULL default values in the PEG parser + - bpo-41215: Use non-NULL default values in the PEG parser keyword list to overcome a bug that was ' preventing Python from being properly compiled when using the XLC compiler. Patch by Pablo Galindo. - - bpo-41218: Python 3.8.3 had a regression where compiling with - ast.PyCF_ALLOW_TOP_LEVEL_AWAIT would + - bpo-41218: Python 3.8.3 had a regression where compiling with + ast.PyCF_ALLOW_TOP_LEVEL_AWAIT would aggressively mark list comprehension with CO_COROUTINE. Now only list comprehension making use of async/await will tagged as so. - - bpo-41175: Guard against a NULL pointer dereference within + - bpo-41175: Guard against a NULL pointer dereference within bytearrayobject triggered by the bytearray() + bytearray() operation. - - bpo-39960: The “hackcheck” that prevents sneaking around a type’s - __setattr__() by calling the superclass method was + - bpo-39960: The “hackcheck” that prevents sneaking around a type’s + __setattr__() by calling the superclass method was rewritten to allow C implemented heap types. - - bpo-41288: Unpickling invalid NEWOBJ_EX opcode with the + - bpo-41288: Unpickling invalid NEWOBJ_EX opcode with the C implementation raises now UnpicklingError instead of crashing. - - bpo-39017: Avoid infinite loop when reading specially crafted + - bpo-39017: Avoid infinite loop when reading specially crafted TAR files using the tarfile module (CVE-2019-20907, bsc#1174091). - bpo-41235: Fix the error handling in ssl.SSLContext.load_dh_params(). - - bpo-41207: In distutils.spawn, restore expectation that + - bpo-41207: In distutils.spawn, restore expectation that DistutilsExecError is raised when the command is not found. - bpo-39168: Remove the __new__ method of typing.Generic. - - bpo-41194: Fix a crash in the _ast module: it can no longer be + - bpo-41194: Fix a crash in the _ast module: it can no longer be loaded more than once. It now uses a global state rather than a module state. - - bpo-39384: Fixed email.contentmanager to allow set_content() to set a + - bpo-39384: Fixed email.contentmanager to allow set_content() to set a null string. - - bpo-41300: Save files with non-ascii chars. + - bpo-41300: Save files with non-ascii chars. Fix regression released in 3.9.0b4 and 3.8.4. - - bpo-37765: Add keywords to module name completion list. + - bpo-37765: Add keywords to module name completion list. Rewrite Completions section of IDLE doc. - - bpo-40170: Revert PyType_HasFeature() change: it reads - again directly the PyTypeObject.tp_flags - member when the limited C API is not used, rather than always calling + - bpo-40170: Revert PyType_HasFeature() change: it reads + again directly the PyTypeObject.tp_flags + member when the limited C API is not used, rather than always calling PyType_GetFlags() which hides implementation details. ------------------------------------------------------------------- @@ -2751,7 +2758,7 @@ Wed Jun 5 12:19:09 CEST 2019 - Matej Cepl pickling costs between processes - typed_ast is merged back to CPython - LOAD_GLOBAL is now 40% faster - - pickle now uses Protocol 4 by default, improving performance + - pickle now uses Protocol 4 by default, improving performance - Remove patches which were included in the upstream: - 00251-change-user-install-location.patch - 00316-mark-bdist_wininst-unsupported.patch @@ -2896,7 +2903,7 @@ Mon Dec 17 17:24:49 CET 2018 - mcepl@suse.com - Upgrade to 3.7.2rc1: * bugfix release, for the full list of all changes see - https://docs.python.org/3.7/whatsnew/changelog.html#changelog + https://docs.python.org/3.7/whatsnew/changelog.html#changelog - Make run of the test suite more verbose ------------------------------------------------------------------- @@ -3323,7 +3330,7 @@ Mon Mar 13 14:04:22 UTC 2017 - jmatejek@suse.com Sat Feb 25 20:55:57 UTC 2017 - bwiedemann@suse.com - Add 0001-allow-for-reproducible-builds-of-python-packages.patch - upstream https://github.com/python/cpython/pull/296 + upstream https://github.com/python/cpython/pull/296 ------------------------------------------------------------------- Wed Feb 8 12:30:20 UTC 2017 - jmatejek@suse.com @@ -3389,7 +3396,7 @@ Mon Mar 7 20:38:11 UTC 2016 - toddrme2178@gmail.com - Add Python-3.5.1-fix_lru_cache_copying.patch Fix copying the lru_cache() wrapper object. - Fixes deep-copying lru_cache regression, which worked on + Fixes deep-copying lru_cache regression, which worked on previous versions of python but fails on python 3.5. This fixes a bunch of packages in devel:languages:python3. See: https://bugs.python.org/issue25447 @@ -3527,7 +3534,7 @@ Sun Jan 11 13:01:30 UTC 2015 - p.drouand@gmail.com ------------------------------------------------------------------- Sat Oct 18 20:14:54 UTC 2014 - crrodriguez@opensuse.org -- Only pkgconfig(x11) is required for build, not the whole +- Only pkgconfig(x11) is required for build, not the whole set of packages provided by xorg-x11-devel metapackage. ------------------------------------------------------------------- @@ -3587,7 +3594,7 @@ Wed Mar 26 15:24:46 UTC 2014 - jmatejek@suse.com ------------------------------------------------------------------- Mon Mar 24 17:29:31 UTC 2014 - dmueller@suse.com -- remove blacklisting of test_posix on aarch64: qemu bug is fixed +- remove blacklisting of test_posix on aarch64: qemu bug is fixed ------------------------------------------------------------------- Mon Mar 17 18:26:58 UTC 2014 - jmatejek@suse.com @@ -3690,7 +3697,7 @@ Tue Nov 19 14:28:41 UTC 2013 - jmatejek@suse.com ------------------------------------------------------------------- Tue Oct 15 17:44:08 UTC 2013 - crrodriguez@opensuse.org -- build with -DOPENSSL_LOAD_CONF for the same reasons +- build with -DOPENSSL_LOAD_CONF for the same reasons described in the python2 package. ------------------------------------------------------------------- @@ -3702,7 +3709,7 @@ Fri Aug 16 11:35:15 UTC 2013 - jmatejek@suse.com ------------------------------------------------------------------- Thu Aug 8 14:54:49 UTC 2013 - dvaleev@suse.com -- Exclue test_faulthandler from tests on powerpc due to bnc#831629 +- Exclue test_faulthandler from tests on powerpc due to bnc#831629 ------------------------------------------------------------------- Thu Jun 13 15:05:34 UTC 2013 - jmatejek@suse.com @@ -3761,7 +3768,7 @@ Fri Mar 1 07:42:21 UTC 2013 - dmueller@suse.com - add ctypes-libffi-aarch64.patch: * import aarch64 support for libffi in _ctypes module -- add aarch64 to the list of lib64 based archs +- add aarch64 to the list of lib64 based archs - add movetogetdents64.diff: * port to getdents64, as SYS_getdents is not implemented everywhere @@ -3815,9 +3822,9 @@ Mon Oct 29 18:21:45 UTC 2012 - dmueller@suse.com ------------------------------------------------------------------- Thu Oct 25 08:14:36 UTC 2012 - Rene.vanPaassen@gmail.com -- exclude test_math for SLE 11; math library fails on negative +- exclude test_math for SLE 11; math library fails on negative gamma function values close to integers and 0, probably - due to imprecision in -lm on SLE_11_SP2. + due to imprecision in -lm on SLE_11_SP2. ------------------------------------------------------------------- Tue Oct 16 12:15:34 UTC 2012 - coolo@suse.com @@ -3841,7 +3848,7 @@ Mon Oct 1 08:53:03 UTC 2012 - idonmez@suse.com ------------------------------------------------------------------- Thu Sep 27 12:35:01 UTC 2012 - idonmez@suse.com -- Correct dependency for python3-testsuite, +- Correct dependency for python3-testsuite, python3-tkinter -> python3-tk ------------------------------------------------------------------- @@ -3874,7 +3881,7 @@ Fri Aug 3 12:09:34 UTC 2012 - jmatejek@suse.com ------------------------------------------------------------------- Fri Jul 27 09:02:41 UTC 2012 - dvaleev@suse.com -- skip test_io on ppc +- skip test_io on ppc - drop test_io ppc patch ------------------------------------------------------------------- @@ -3923,8 +3930,8 @@ Wed Jan 18 15:49:47 UTC 2012 - jmatejek@suse.com ------------------------------------------------------------------- Sun Dec 25 13:25:01 UTC 2011 - idonmez@suse.com -- Use system ffi, included one is broken see - http://bugs.python.org/issue11729 and +- Use system ffi, included one is broken see + http://bugs.python.org/issue11729 and http://bugs.python.org/issue12081 ------------------------------------------------------------------- diff --git a/python39.spec b/python39.spec index d851366..01e511d 100644 --- a/python39.spec +++ b/python39.spec @@ -192,6 +192,9 @@ Patch50: gh120226-fix-sendfile-test-kernel-610.patch # PATCH-FIX-UPSTREAM sphinx-802.patch mcepl@suse.com # status_iterator method moved between the Sphinx versions Patch51: sphinx-802.patch +# PATCH-FIX-UPSTREAM CVE-2025-4516-DecodeError-handler.patch bsc#1243273 mcepl@suse.com +# this patch makes things totally awesome +Patch52: CVE-2025-4516-DecodeError-handler.patch BuildRequires: autoconf-archive BuildRequires: automake BuildRequires: fdupes @@ -463,6 +466,7 @@ other applications. %patch -p1 -P 48 %patch -p1 -P 50 %patch -p1 -P 51 +%patch -p1 -P 52 # drop Autoconf version requirement sed -i 's/^AC_PREREQ/dnl AC_PREREQ/' configure.ac