SHA256
1
0
forked from pool/python38

Accepting request 1202275 from devel:languages:python:Factory

- Add sphinx-802.patch to overcome working both with the most
  recent and older Sphinx versions.
- Update CVE-2023-52425-libexpat-2.6.0-backport.patch
  so that it uses features sniffing, not just
  comparing version number. Include also
  support-expat-CVE-2022-25236-patched.patch.

OBS-URL: https://build.opensuse.org/request/show/1202275
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/python38?expand=0&rev=55
This commit is contained in:
Ana Guerrero 2024-09-22 09:06:19 +00:00 committed by Git OBS Bridge
commit 05835693e8
5 changed files with 357 additions and 74 deletions

View File

@ -0,0 +1,313 @@
From d7133c7e0f91b14c390aa30a5689c353ef754fb6 Mon Sep 17 00:00:00 2001
From: Sebastian Pipping <sebastian@pipping.org>
Date: Wed, 7 Feb 2024 15:32:45 +0100
Subject: [PATCH] Fix etree XMLPullParser tests for Expat >=2.6.0 with reparse
deferral
Combined with gh#python/cpython!31453
bpo-46811: Make test suite support Expat >=2.4.5 (GH-31453)
Curly brackets were never allowed in namespace URIs
according to RFC 3986, and so-called namespace-validating
XML parsers have the right to reject them a invalid URIs.
libexpat >=2.4.5 has become strcter in that regard due to
related security issues; with ET.XML instantiating a
namespace-aware parser under the hood, this test has no
future in CPython.
References:
- https://datatracker.ietf.org/doc/html/rfc3968
- https://www.w3.org/TR/xml-names/
Also, test_minidom.py: Support Expat >=2.4.5
(cherry picked from commit 2cae93832f46b245847bdc252456ddf7742ef45e)
Co-authored-by: Sebastian Pipping <sebastian@pipping.org>
Fixes: gh#python/cpython#115133
From-PR: gh#python/cpython!115138
Patch: CVE-2023-52425-libexpat-2.6.0-backport.patch
---
Lib/test/support/__init__.py | 15 ++
Lib/test/test_minidom.py | 22 +--
Lib/test/test_pyexpat.py | 61 +++++++++-
Lib/test/test_sax.py | 54 ++++++++
Lib/test/test_xml_etree.py | 13 +-
Misc/NEWS.d/next/Library/2022-02-20-21-03-31.bpo-46811.8BxgdQ.rst | 1
Misc/NEWS.d/next/Tests/2024-02-07-15-49-37.gh-issue-115133.WBajNr.rst | 1
7 files changed, 146 insertions(+), 21 deletions(-)
create mode 100644 Misc/NEWS.d/next/Library/2022-02-20-21-03-31.bpo-46811.8BxgdQ.rst
create mode 100644 Misc/NEWS.d/next/Tests/2024-02-07-15-49-37.gh-issue-115133.WBajNr.rst
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -23,6 +23,7 @@ import platform
import re
import shutil
import socket
+import pyexpat
import stat
import struct
import subprocess
@@ -119,9 +120,11 @@ __all__ = [
"run_with_locale", "swap_item",
"swap_attr", "Matcher", "set_memlimit", "SuppressCrashReport", "sortdict",
"run_with_tz", "PGO", "missing_compiler_executable", "fd_count",
- "ALWAYS_EQ", "LARGEST", "SMALLEST"
+ "ALWAYS_EQ", "LARGEST", "SMALLEST",
+ "fails_with_expat_2_6_0", "is_expat_2_6_0"
]
+
class Error(Exception):
"""Base class for regression test exceptions."""
@@ -3411,3 +3414,13 @@ def adjust_int_max_str_digits(max_digits
yield
finally:
sys.set_int_max_str_digits(current)
+
+
+@functools.lru_cache(maxsize=32)
+def _is_expat_2_6_0():
+ return hasattr(pyexpat.ParserCreate(), 'SetReparseDeferralEnabled')
+is_expat_2_6_0 = _is_expat_2_6_0()
+
+fails_with_expat_2_6_0 = (unittest.expectedFailure
+ if is_expat_2_6_0
+ else lambda test: test)
--- a/Lib/test/test_minidom.py
+++ b/Lib/test/test_minidom.py
@@ -1149,13 +1149,11 @@ class MinidomTest(unittest.TestCase):
# Verify that character decoding errors raise exceptions instead
# of crashing
- if pyexpat.version_info >= (2, 4, 5):
- self.assertRaises(ExpatError, parseString,
- b'<fran\xe7ais></fran\xe7ais>')
- self.assertRaises(ExpatError, parseString,
- b'<franais>Comment \xe7a va ? Tr\xe8s bien ?</franais>')
- else:
- self.assertRaises(UnicodeDecodeError, parseString,
+ # It doesnt make any sense to insist on the exact text of the
+ # error message, or even the exact Exception … it is enough that
+ # the error has been discovered.
+ with self.assertRaises((UnicodeDecodeError, ExpatError)):
+ parseString(
b'<fran\xe7ais>Comment \xe7a va ? Tr\xe8s bien ?</fran\xe7ais>')
doc.unlink()
@@ -1601,12 +1599,10 @@ class MinidomTest(unittest.TestCase):
self.confirm(doc2.namespaceURI == xml.dom.EMPTY_NAMESPACE)
def testExceptionOnSpacesInXMLNSValue(self):
- if pyexpat.version_info >= (2, 4, 5):
- context = self.assertRaisesRegex(ExpatError, 'syntax error')
- else:
- context = self.assertRaisesRegex(ValueError, 'Unsupported syntax')
-
- with context:
+ # It doesnt make any sense to insist on the exact text of the
+ # error message, or even the exact Exception … it is enough that
+ # the error has been discovered.
+ with self.assertRaises((ExpatError, ValueError)):
parseString('<element xmlns:abc="http:abc.com/de f g/hi/j k"><abc:foo /></element>')
def testDocRemoveChild(self):
--- a/Lib/test/test_pyexpat.py
+++ b/Lib/test/test_pyexpat.py
@@ -11,7 +11,7 @@ import traceback
from xml.parsers import expat
from xml.parsers.expat import errors
-from test.support import sortdict
+from test.support import sortdict, is_expat_2_6_0
class SetAttributeTest(unittest.TestCase):
@@ -778,6 +778,65 @@ class ReparseDeferralTest(unittest.TestC
for chunk in (b'<doc', b'/>'):
parser.Parse(chunk, False)
+
+ # The key test: Have handlers already fired? Expecting: yes.
+ self.assertEqual(started, ['doc'])
+
+
+class ReparseDeferralTest(unittest.TestCase):
+ def test_getter_setter_round_trip(self):
+ if not is_expat_2_6_0:
+ self.skipTest("Linked libexpat doesn't support reparse deferral")
+
+ parser = expat.ParserCreate()
+ enabled = (expat.version_info >= (2, 6, 0))
+
+ self.assertIs(parser.GetReparseDeferralEnabled(), enabled)
+ parser.SetReparseDeferralEnabled(False)
+ self.assertIs(parser.GetReparseDeferralEnabled(), False)
+ parser.SetReparseDeferralEnabled(True)
+ self.assertIs(parser.GetReparseDeferralEnabled(), enabled)
+
+ def test_reparse_deferral_enabled(self):
+ if not is_expat_2_6_0:
+ self.skipTest("Linked libexpat doesn't support reparse deferral")
+
+ started = []
+
+ def start_element(name, _):
+ started.append(name)
+
+ parser = expat.ParserCreate()
+ parser.StartElementHandler = start_element
+ self.assertTrue(parser.GetReparseDeferralEnabled())
+
+ for chunk in (b'<doc', b'/>'):
+ parser.Parse(chunk, False)
+
+ # The key test: Have handlers already fired? Expecting: no.
+ self.assertEqual(started, [])
+
+ parser.Parse(b'', True)
+
+ self.assertEqual(started, ['doc'])
+
+ def test_reparse_deferral_disabled(self):
+ if not is_expat_2_6_0:
+ self.skipTest("Linked libexpat doesn't support reparse deferral")
+
+ started = []
+
+ def start_element(name, _):
+ started.append(name)
+
+ parser = expat.ParserCreate()
+ parser.StartElementHandler = start_element
+ if is_expat_2_6_0:
+ parser.SetReparseDeferralEnabled(False)
+ self.assertFalse(parser.GetReparseDeferralEnabled())
+
+ for chunk in (b'<doc', b'/>'):
+ parser.Parse(chunk, False)
# The key test: Have handlers already fired? Expecting: yes.
self.assertEqual(started, ['doc'])
--- a/Lib/test/test_sax.py
+++ b/Lib/test/test_sax.py
@@ -22,7 +22,7 @@ import pyexpat
import shutil
from urllib.error import URLError
from test import support
-from test.support import findfile, run_unittest, FakePath, TESTFN
+from test.support import findfile, run_unittest, FakePath, TESTFN, is_expat_2_6_0
TEST_XMLFILE = findfile("test.xml", subdir="xmltestdata")
TEST_XMLFILE_OUT = findfile("test.xml.out", subdir="xmltestdata")
@@ -1247,6 +1247,58 @@ class ExpatReaderTest(XmlTestBase):
self.assertFalse(parser._parser.GetReparseDeferralEnabled())
+ parser.flush()
+
+ self.assertFalse(parser._parser.GetReparseDeferralEnabled())
+ self.assertEqual(result.getvalue(), start + b"<doc>")
+
+ parser.feed("</doc>")
+ parser.close()
+
+ self.assertEqual(result.getvalue(), start + b"<doc></doc>")
+
+ def test_flush_reparse_deferral_enabled(self):
+ if not is_expat_2_6_0:
+ self.skipTest("Linked libexpat doesn't support reparse deferral")
+
+ result = BytesIO()
+ xmlgen = XMLGenerator(result)
+ parser = create_parser()
+ parser.setContentHandler(xmlgen)
+
+ for chunk in ("<doc", ">"):
+ parser.feed(chunk)
+
+ self.assertEqual(result.getvalue(), start) # i.e. no elements started
+ self.assertTrue(parser._parser.GetReparseDeferralEnabled())
+
+ parser.flush()
+
+ self.assertTrue(parser._parser.GetReparseDeferralEnabled())
+ self.assertEqual(result.getvalue(), start + b"<doc>")
+
+ parser.feed("</doc>")
+ parser.close()
+
+ self.assertEqual(result.getvalue(), start + b"<doc></doc>")
+
+ def test_flush_reparse_deferral_disabled(self):
+ if not is_expat_2_6_0:
+ self.skipTest("Linked libexpat doesn't support reparse deferral")
+
+ result = BytesIO()
+ xmlgen = XMLGenerator(result)
+ parser = create_parser()
+ parser.setContentHandler(xmlgen)
+
+ for chunk in ("<doc", ">"):
+ parser.feed(chunk)
+
+ parser._parser.SetReparseDeferralEnabled(False)
+ self.assertEqual(result.getvalue(), start) # i.e. no elements started
+
+ self.assertFalse(parser._parser.GetReparseDeferralEnabled())
+
parser.flush()
self.assertFalse(parser._parser.GetReparseDeferralEnabled())
--- a/Lib/test/test_xml_etree.py
+++ b/Lib/test/test_xml_etree.py
@@ -25,7 +25,8 @@ import weakref
from functools import partial
from itertools import product, islice
from test import support
-from test.support import TESTFN, findfile, import_fresh_module, gc_collect, swap_attr
+from test.support import (TESTFN, findfile, import_fresh_module,
+ gc_collect, swap_attr, is_expat_2_6_0, fails_with_expat_2_6_0)
# pyET is the pure-Python implementation.
#
@@ -1271,6 +1272,7 @@ class XMLPullParserTest(unittest.TestCas
expected)
def test_simple_xml(self, chunk_size=None, flush=False):
+ expected_events = []
parser = ET.XMLPullParser()
self.assert_event_tags(parser, [])
self._feed(parser, "<!-- comment -->\n", chunk_size, flush)
@@ -1280,16 +1282,17 @@ class XMLPullParserTest(unittest.TestCas
chunk_size, flush)
self.assert_event_tags(parser, [])
self._feed(parser, ">\n", chunk_size, flush)
- self.assert_event_tags(parser, [('end', 'element')])
+ expected_events += [('end', 'element')]
self._feed(parser, "<element>text</element>tail\n", chunk_size, flush)
self._feed(parser, "<empty-element/>\n", chunk_size, flush)
- self.assert_event_tags(parser, [
+ expected_events += [
('end', 'element'),
('end', 'empty-element'),
- ])
+ ]
self._feed(parser, "</root>\n", chunk_size, flush)
- self.assert_event_tags(parser, [('end', 'root')])
+ expected_events += [('end', 'root')]
self.assertIsNone(parser.close())
+ self.assert_event_tags(parser, expected_events)
def test_simple_xml_chunk_1(self):
self.test_simple_xml(chunk_size=1, flush=True)
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2022-02-20-21-03-31.bpo-46811.8BxgdQ.rst
@@ -0,0 +1 @@
+Make test suite support Expat >=2.4.5
--- /dev/null
+++ b/Misc/NEWS.d/next/Tests/2024-02-07-15-49-37.gh-issue-115133.WBajNr.rst
@@ -0,0 +1 @@
+Fix etree XMLPullParser tests for Expat >=2.6.0 with reparse deferral

View File

@ -1,3 +1,17 @@
-------------------------------------------------------------------
Fri Sep 20 22:19:12 UTC 2024 - Matej Cepl <mcepl@cepl.eu>
- Add sphinx-802.patch to overcome working both with the most
recent and older Sphinx versions.
-------------------------------------------------------------------
Thu Sep 19 00:14:25 UTC 2024 - Matej Cepl <mcepl@cepl.eu>
- Update CVE-2023-52425-libexpat-2.6.0-backport.patch
so that it uses features sniffing, not just
comparing version number. Include also
support-expat-CVE-2022-25236-patched.patch.
-------------------------------------------------------------------
Mon Sep 9 20:27:46 UTC 2024 - Matej Cepl <mcepl@cepl.eu>

View File

@ -174,9 +174,11 @@ Patch33: bpo44426-complex-keyword-sphinx.patch
# PATCH-FIX-UPSTREAM bpo34990-2038-problem-compileall.patch gh#python/cpython#79171 mcepl@suse.com
# Make compileall.py compatible with year 2038
Patch34: bpo34990-2038-problem-compileall.patch
# PATCH-FIX-UPSTREAM gh#python/cpython#90967 gh#python/cpython#93900 mcepl@suse.com
# NOTE: SUSE version of expat 2.4.4 is patched in SUSE for CVE-2022-25236
Patch36: support-expat-CVE-2022-25236-patched.patch
# PATCH-FIX-OPENSUSE CVE-2023-52425-libexpat-2.6.0-backport.patch
# This problem on libexpat is patched on SLE without version
# update, this patch changes the tests to match the libexpat provided
# by SUSE
Patch36: CVE-2023-52425-libexpat-2.6.0-backport.patch
# PATCH-FIX-OPENSUSE platlibdir-in-sys.patch bsc#1204395
Patch37: platlibdir-in-sys.patch
# PATCH-FIX-UPSTREAM 98437-sphinx.locale._-as-gettext-in-pyspecific.patch gh#python/cpython#98366 mcepl@suse.com
@ -194,6 +196,9 @@ Patch48: CVE-2024-5642-OpenSSL-API-buf-overread-NPN.patch
# PATCH-FIX-UPSTREAM gh120226-fix-sendfile-test-kernel-610.patch gh#python/cpython#120226 mcepl@suse.com
# Fix test_sendfile_close_peer_in_the_middle_of_receiving on Linux >= 6.10 (GH-120227)
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
BuildRequires: autoconf-archive
BuildRequires: automake
@ -468,6 +473,7 @@ other applications.
%patch -p1 -P 46
%patch -p1 -P 48
%patch -p1 -P 50
%patch -p1 -P 51
# drop Autoconf version requirement
sed -i 's/^AC_PREREQ/dnl AC_PREREQ/' configure.ac

21
sphinx-802.patch Normal file
View File

@ -0,0 +1,21 @@
---
Doc/tools/extensions/pyspecific.py | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
--- a/Doc/tools/extensions/pyspecific.py
+++ b/Doc/tools/extensions/pyspecific.py
@@ -27,7 +27,13 @@ try:
except ImportError:
from sphinx.environment import NoUri
from sphinx.locale import _ as sphinx_gettext
-from sphinx.util import status_iterator, logging
+try:
+ from sphinx.util.display import status_iterator
+except ImportError:
+ # This method was moved into sphinx.util.display in Sphinx 6.1.0. Before
+ # that it resided in sphinx.util.
+ from sphinx.util import status_iterator
+from sphinx.util import logging
from sphinx.util.nodes import split_explicit_title
from sphinx.writers.text import TextWriter, TextTranslator
from sphinx.writers.latex import LaTeXTranslator

View File

@ -1,71 +0,0 @@
From 7da97f61816f3cadaa6788804b22a2434b40e8c5 Mon Sep 17 00:00:00 2001
From: "Miss Islington (bot)"
<31488909+miss-islington@users.noreply.github.com>
Date: Mon, 21 Feb 2022 08:16:09 -0800
Subject: [PATCH] bpo-46811: Make test suite support Expat >=2.4.5 (GH-31453)
(GH-31472)
Curly brackets were never allowed in namespace URIs
according to RFC 3986, and so-called namespace-validating
XML parsers have the right to reject them a invalid URIs.
libexpat >=2.4.5 has become strcter in that regard due to
related security issues; with ET.XML instantiating a
namespace-aware parser under the hood, this test has no
future in CPython.
References:
- https://datatracker.ietf.org/doc/html/rfc3968
- https://www.w3.org/TR/xml-names/
Also, test_minidom.py: Support Expat >=2.4.5
(cherry picked from commit 2cae93832f46b245847bdc252456ddf7742ef45e)
Co-authored-by: Sebastian Pipping <sebastian@pipping.org>
---
Lib/test/test_minidom.py | 25 +++++++++++--------------
1 file changed, 11 insertions(+), 14 deletions(-)
create mode 100644 Misc/NEWS.d/next/Library/2022-02-20-21-03-31.bpo-46811.8BxgdQ.rst
--- a/Lib/test/test_minidom.py
+++ b/Lib/test/test_minidom.py
@@ -1149,14 +1149,12 @@ class MinidomTest(unittest.TestCase):
# Verify that character decoding errors raise exceptions instead
# of crashing
- if pyexpat.version_info >= (2, 4, 5):
- self.assertRaises(ExpatError, parseString,
- b'<fran\xe7ais></fran\xe7ais>')
- self.assertRaises(ExpatError, parseString,
- b'<franais>Comment \xe7a va ? Tr\xe8s bien ?</franais>')
- else:
- self.assertRaises(UnicodeDecodeError, parseString,
- b'<fran\xe7ais>Comment \xe7a va ? Tr\xe8s bien ?</fran\xe7ais>')
+ # It doesnt make any sense to insist on the exact text of the
+ # error message, or even the exact Exception … it is enough that
+ # the error has been discovered.
+ with self.assertRaises((UnicodeDecodeError, ExpatError)):
+ parseString(
+ b'<fran\xe7ais>Comment \xe7a va ? Tr\xe8s bien ?</fran\xe7ais>')
doc.unlink()
@@ -1601,13 +1599,12 @@ class MinidomTest(unittest.TestCase):
self.confirm(doc2.namespaceURI == xml.dom.EMPTY_NAMESPACE)
def testExceptionOnSpacesInXMLNSValue(self):
- if pyexpat.version_info >= (2, 4, 5):
- context = self.assertRaisesRegex(ExpatError, 'syntax error')
- else:
- context = self.assertRaisesRegex(ValueError, 'Unsupported syntax')
+ # It doesnt make any sense to insist on the exact text of the
+ # error message, or even the exact Exception … it is enough that
+ # the error has been discovered.
+ with self.assertRaises((ExpatError, ValueError)):
+ parseString('<element xmlns:abc="http:abc.com/de f g/hi/j k"><abc:foo /></element>')
- with context:
- parseString('<element xmlns:abc="http:abc.com/de f g/hi/j k"><abc:foo /></element>')
def testDocRemoveChild(self):
doc = parse(tstfile)