From db50b5723ad48dca7bca678e07d122bb7e5f5999 Mon Sep 17 00:00:00 2001
From: rockyautomation <rockyautomation@rockylinux.org>
Date: Tue, 5 Nov 2024 07:35:57 +0000
Subject: [PATCH] import python3.11-3.11.10-1.el8_10

---
 .python3.11.metadata                          |   2 +-
 ...-addresses-in-email-parseaddr-111116.patch | 526 +-----------------
 SOURCES/Python-3.11.10.tar.xz.asc             |  16 +
 SPECS/python3.11.spec                         |  39 +-
 4 files changed, 38 insertions(+), 545 deletions(-)
 create mode 100644 SOURCES/Python-3.11.10.tar.xz.asc

diff --git a/.python3.11.metadata b/.python3.11.metadata
index 6856768..b0af48e 100644
--- a/.python3.11.metadata
+++ b/.python3.11.metadata
@@ -1,2 +1,2 @@
-9b1e896523fc510691126c864406d9360a3d1e986acbda59cda57b5abda45b87 SOURCES/Python-3.11.9.tar.xz
+07a4356e912900e61a15cb0949a06c4a05012e213ecd6b4e84d0f67aabbee372 SOURCES/Python-3.11.10.tar.xz
 fb28243ffeb9725b14b60586a9a123682a89604c025b7a9d4bcdeb67078203c6 SOURCES/pgp_keys.asc
diff --git a/SOURCES/00415-cve-2023-27043-gh-102988-reject-malformed-addresses-in-email-parseaddr-111116.patch b/SOURCES/00415-cve-2023-27043-gh-102988-reject-malformed-addresses-in-email-parseaddr-111116.patch
index b29388f..cc94f1e 100644
--- a/SOURCES/00415-cve-2023-27043-gh-102988-reject-malformed-addresses-in-email-parseaddr-111116.patch
+++ b/SOURCES/00415-cve-2023-27043-gh-102988-reject-malformed-addresses-in-email-parseaddr-111116.patch
@@ -1,513 +1,16 @@
-From 642f28679e04c7b4ec7731f0c8872103f21a76f8 Mon Sep 17 00:00:00 2001
-From: Victor Stinner <vstinner@python.org>
-Date: Fri, 15 Dec 2023 16:10:40 +0100
-Subject: [PATCH 1/2] 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 <github@tomd.tel>
----
- Doc/library/email.utils.rst                   |  19 +-
- Lib/email/utils.py                            | 150 ++++++++++++-
- Lib/test/test_email/test_email.py             | 204 +++++++++++++++++-
- ...-10-20-15-28-08.gh-issue-102988.dStNO7.rst |   8 +
- 4 files changed, 360 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 0e266b6..6723dc4 100644
---- a/Doc/library/email.utils.rst
-+++ b/Doc/library/email.utils.rst
-@@ -60,13 +60,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')
- 
-@@ -84,12 +89,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 <email.message.Message.get_all>`.  Here's a simple
--   example that gets all the recipients of a message::
-+   :meth:`Message.get_all <email.message.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
- 
-@@ -99,6 +107,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 8993858..41bb3c9 100644
---- a/Lib/email/utils.py
-+++ b/Lib/email/utils.py
-@@ -106,12 +106,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 _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.
- 
--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
-+    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 <bob@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 +320,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 785696e..ad60ed3 100644
---- a/Lib/test/test_email/test_email.py
-+++ b/Lib/test/test_email/test_email.py
-@@ -17,6 +17,7 @@ from unittest.mock import patch
- 
- import email
- import email.policy
-+import email.utils
- 
- from email.charset import Charset
- from email.generator import Generator, DecodedGenerator, BytesGenerator
-@@ -3336,15 +3337,154 @@ Foo
-            [('Al Person', 'aperson@dom.ain'),
-             ('Bud Person', 'bperson@dom.ain')])
- 
-+    def test_getaddresses_comma_in_name(self):
-+        """GH-106669 regression test."""
-+        self.assertEqual(
-+            utils.getaddresses(
-+                [
-+                    '"Bud, Person" <bperson@dom.ain>',
-+                    'aperson@dom.ain (Al Person)',
-+                    '"Mariusz Felisiak" <to@example.com>',
-+                ]
-+            ),
-+            [
-+                ('Bud, Person', 'bperson@dom.ain'),
-+                ('Al Person', 'aperson@dom.ain'),
-+                ('Mariusz Felisiak', 'to@example.com'),
-+            ],
-+        )
-+
-+    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" <bob@example.com>'
-+        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" <jane@example.net>, "John Doe" <john@example.net>'
-+        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@dom.ain>']),
--           [('', ''), ('Jason R. Mastaler', 'jason@dom.ain')])
-+        for addresses, expected in (
-+            (['"Sürname, Firstname" <to@example.com>'],
-+             [('Sürname, Firstname', 'to@example.com')]),
-+
-+            (['foo: ;'],
-+             [('', '')]),
-+
-+            (['foo: ;', '"Jason R. Mastaler" <jason@dom.ain>'],
-+             [('', ''), ('Jason R. Mastaler', 'jason@dom.ain')]),
-+
-+            ([r'Pete(A nice \) chap) <pete(his account)@silly.test(his host)>'],
-+             [('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 <jdoe@machine(comment).  example>'],
-+             [('John Doe (comment)', 'jdoe@machine.example')]),
-+
-+            (['"Mary Smith: Personal Account" <smith@home.example>'],
-+             [('Mary Smith: Personal Account', 'smith@home.example')]),
-+
-+            (['Undisclosed recipients:;'],
-+             [('', '')]),
-+
-+            ([r'<boss@nil.test>, "Giant; \"Big\" Box" <bob@example.net>'],
-+             [('', '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"""
-@@ -3535,6 +3675,54 @@ multipart/report
-                 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" <jane@example.net>, "John Doe" <john@example.net>',
-+              ' <jane@example.net>,  <john@example.net>')
-+        check(r'"Jane \"Doe\"." <jane@example.net>',
-+              ' <jane@example.net>')
-+
-+        # 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 <jane@example.net>, John Doe <john@example.net>',
-+            '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 0000000..3d0e9e4
---- /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.
--- 
-2.44.0
-
-
-From d371679e7c485551c10380ac11e5039a9fb4515b Mon Sep 17 00:00:00 2001
+From 3f01ced0b5051798516fc65f5fac10ffd15dbce6 Mon Sep 17 00:00:00 2001
 From: Lumir Balhar <lbalhar@redhat.com>
 Date: Wed, 10 Jan 2024 08:53:53 +0100
-Subject: [PATCH 2/2] Make it possible to disable strict parsing in email
- module
+Subject: [PATCH] Make it possible to disable strict parsing in email module
 
 ---
  Doc/library/email.utils.rst       | 26 +++++++++++
- Lib/email/utils.py                | 55 ++++++++++++++++++++++-
+ Lib/email/utils.py                | 54 +++++++++++++++++++++-
  Lib/test/test_email/test_email.py | 74 ++++++++++++++++++++++++++++++-
- 3 files changed, 151 insertions(+), 4 deletions(-)
+ 3 files changed, 150 insertions(+), 4 deletions(-)
 
 diff --git a/Doc/library/email.utils.rst b/Doc/library/email.utils.rst
-index 6723dc4..c89602d 100644
+index 97ddf49..0c9bf53 100644
 --- a/Doc/library/email.utils.rst
 +++ b/Doc/library/email.utils.rst
 @@ -69,6 +69,19 @@ of the new API.
@@ -527,7 +30,7 @@ index 6723dc4..c89602d 100644
 +      [email_addr_parsing]
 +      PYTHON_EMAIL_DISABLE_STRICT_ADDR_PARSING = true
 +
-    .. versionchanged:: 3.13
+    .. versionchanged:: 3.11.10
        Add *strict* optional parameter and reject malformed inputs by default.
  
 @@ -97,6 +110,19 @@ of the new API.
@@ -551,10 +54,10 @@ index 6723dc4..c89602d 100644
  
        from email.utils import getaddresses
 diff --git a/Lib/email/utils.py b/Lib/email/utils.py
-index 41bb3c9..09a414c 100644
+index 94ead0e..09a414c 100644
 --- a/Lib/email/utils.py
 +++ b/Lib/email/utils.py
-@@ -48,6 +48,47 @@ TICK = "'"
+@@ -48,6 +48,46 @@ TICK = "'"
  specialsre = re.compile(r'[][\\()<>@,:;".]')
  escapesre = re.compile(r'[\\"]')
  
@@ -598,11 +101,10 @@ index 41bb3c9..09a414c 100644
 +
 +    return True
 +
-+
+ 
  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
-@@ -148,7 +189,7 @@ def _strip_quoted_realnames(addr):
+@@ -149,7 +189,7 @@ def _strip_quoted_realnames(addr):
  
  supports_strict_parsing = True
  
@@ -611,7 +113,7 @@ index 41bb3c9..09a414c 100644
      """Return a list of (REALNAME, EMAIL) or ('','') for each fieldvalue.
  
      When parsing fails for a fieldvalue, a 2-tuple of ('', '') is returned in
-@@ -157,6 +198,11 @@ def getaddresses(fieldvalues, *, strict=True):
+@@ -158,6 +198,11 @@ def getaddresses(fieldvalues, *, strict=True):
      If strict is true, use a strict parser which rejects malformed inputs.
      """
  
@@ -623,7 +125,7 @@ index 41bb3c9..09a414c 100644
      # 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 [('',
-@@ -320,7 +366,7 @@ def parsedate_to_datetime(data):
+@@ -321,7 +366,7 @@ def parsedate_to_datetime(data):
              tzinfo=datetime.timezone(datetime.timedelta(seconds=tz)))
  
  
@@ -632,7 +134,7 @@ index 41bb3c9..09a414c 100644
      """
      Parse addr into its constituent realname and email address parts.
  
-@@ -329,6 +375,11 @@ def parseaddr(addr, *, strict=True):
+@@ -330,6 +375,11 @@ def parseaddr(addr, *, strict=True):
  
      If strict is True, use a strict parser which rejects malformed inputs.
      """
@@ -744,5 +246,5 @@ index ad60ed3..f85da56 100644
          for addresses, expected in (
              (['"Sürname, Firstname" <to@example.com>'],
 -- 
-2.44.0
+2.46.0
 
diff --git a/SOURCES/Python-3.11.10.tar.xz.asc b/SOURCES/Python-3.11.10.tar.xz.asc
new file mode 100644
index 0000000..518e50d
--- /dev/null
+++ b/SOURCES/Python-3.11.10.tar.xz.asc
@@ -0,0 +1,16 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQIzBAABCAAdFiEEz9yiRbEEPPKl+Xhl/+h0BBaL2EcFAmbbrO0ACgkQ/+h0BBaL
+2Ec+YBAAnQJLKYPjj7Yr7xkFU655Sv86JxeRAdWjnIapbiIuWg3Up8Pd8FTRgHGf
+3XdTHw7b03lSjtzJwavzdnDklqAlBIGn9dVieljUIN7NYyNxoYOr/AiatimgSwv7
+dI5mfun5fLKV6ZcdNdQN5PJ3RZtF3I7VfkN2mlfZJHtxl1agdU/TfW2L+qJ7+JPY
+cayjq2xKTLRNXOf2iV29GRRovLiqA+Dx0+cAwsScwreHMp3U4k3GkeHVoR6fldV4
+bVAM8GRl3CYVFePiqAbamKP1BSys44JOINWbWyd94JxzEAwXWz//Es0h73AzeRfK
+ueORqzdoOGrVc74+HGlAHhqO1Gg7jMMmtkzCEuav+cGHYnMRMOngGR3q47aTJTVb
+5UdP0oD4OlADPFVa6q0LCqN/IFlebWMh9pXYw7Wpek63oNuZHTfNPq4S1AUM2HJm
+C3yzaOG9VAdYfLneJC4ldY4CVt1FKckfaXp5OAaMr71DI74e4CcEswlUupZJLZKV
+TJRjQD15bnXGhHDqU4w3RmzpCWMh2mf4m4VMYQyObl3TtlX+gVvzIhDS5+mXqutB
+F1pdXwaHHkTb2PLLxpwOGrnsp8XoW74tsylcYirQg8jSFMbgxfwgIjEIuRGXeDkT
+B4QzmQ4SxsbLiH7etV6Fznl1h569Z4DO9OOs4i0ZzIjdhPDQtAs=
+=TatG
+-----END PGP SIGNATURE-----
diff --git a/SPECS/python3.11.spec b/SPECS/python3.11.spec
index eeac073..6818714 100644
--- a/SPECS/python3.11.spec
+++ b/SPECS/python3.11.spec
@@ -16,11 +16,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}.9
+%global general_version %{pybasever}.10
 #global prerel ...
 %global upstream_version %{general_version}%{?prerel}
 Version: %{general_version}%{?prerel:~%{prerel}}
-Release: 7%{?dist}
+Release: 1%{?dist}
 License: Python
 
 
@@ -388,7 +388,7 @@ Patch397: 00397-tarfile-filter.patch
 #
 # Upstream PR: https://github.com/python/cpython/pull/111116
 #
-# Second patch implmenets the possibility to restore the old behavior via
+# The patch implements the possibility to restore the old behavior via
 # config file or environment variable.
 Patch415: 00415-cve-2023-27043-gh-102988-reject-malformed-addresses-in-email-parseaddr-111116.patch
 
@@ -398,35 +398,6 @@ Patch415: 00415-cve-2023-27043-gh-102988-reject-malformed-addresses-in-email-par
 # Downstream only.
 Patch422: 00422-fix-expat-tests.patch
 
-# 00431 #
-# Security fix for CVE-2024-4032: incorrect IPv4 and IPv6 private ranges
-# Resolved upstream: https://github.com/python/cpython/issues/113171
-# Tracking bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2292921
-Patch431: 00431-CVE-2024-4032.patch
-
-# 00435 # d33a3c90daa3d5d2d7e67f6e9264e5438d9608a0
-# gh-121650: Encode newlines in headers, and verify headers are sound (GH-122233)
-#
-# Per RFC 2047:
-#
-# > [...] these encoding schemes allow the
-# > encoding of arbitrary octet values, mail readers that implement this
-# > decoding should also ensure that display of the decoded data on the
-# > recipient's terminal will not cause unwanted side-effects
-#
-# It seems that the "quoted-word" scheme is a valid way to include
-# a newline character in a header value, just like we already allow
-# undecodable bytes or control characters.
-# They do need to be properly quoted when serialized to text, though.
-#
-# This should fail for custom fold() implementations that aren't careful
-# about newlines.
-Patch435: 00435-gh-121650-encode-newlines-in-headers-and-verify-headers-are-sound-gh-122233.patch
-
-# 00436 # 1acd6db660ad1124ab7ae449a841608dd9d9062d
-# [CVE-2024-8088] gh-122905: Sanitize names in zipfile.Path.
-Patch436: 00436-cve-2024-8088-gh-122905-sanitize-names-in-zipfile-path.patch
-
 # (New patches go here ^^^)
 #
 # When adding new patches to "python" and "python3" in Fedora, EL, etc.,
@@ -1884,6 +1855,10 @@ fi
 # ======================================================
 
 %changelog
+* Mon Sep 09 2024 Tomáš Hrnčiar <thrnciar@redhat.com> - 3.11.10-1
+- Update to 3.11.10
+Resolves: RHEL-57400
+
 * Fri Aug 23 2024 Charalampos Stratakis <cstratak@redhat.com> - 3.11.9-7
 - Security fix for CVE-2024-8088
 Resolves: RHEL-55934
-- 
GitLab