diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..cdf0f19389ec0b4b813ff0f8b13b6ed1eeb5e114 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/5.0.8.tar.gz diff --git a/0001-python-3.10-compatibility-disable-failing-tests.patch b/0001-python-3.10-compatibility-disable-failing-tests.patch deleted file mode 100644 index 67a44a54a93fc64f30d1fe7cca4a72bbaa788a35..0000000000000000000000000000000000000000 --- a/0001-python-3.10-compatibility-disable-failing-tests.patch +++ /dev/null @@ -1,142 +0,0 @@ -From 1fb41ea8fa2b2b65e4e770eb6296c2ed32ebc954 Mon Sep 17 00:00:00 2001 -From: Tomas Hrnciar -Date: Tue, 25 May 2021 13:56:10 +0200 -Subject: [PATCH] python 3.10 compatibility - disable failing tests - ---- - tests/constraints/tests.py | 12 ------------ - tests/fixtures/tests.py | 15 --------------- - tests/model_enums/tests.py | 36 ------------------------------------ - tests/validators/tests.py | 13 ------------- - 4 files changed, 76 deletions(-) - -diff --git a/tests/constraints/tests.py b/tests/constraints/tests.py -index 2796a0f..b277781 100644 ---- a/tests/constraints/tests.py -+++ b/tests/constraints/tests.py -@@ -237,18 +237,6 @@ class UniqueConstraintTests(TestCase): - "condition=(AND: ('foo', F(bar)))>", - ) - -- def test_repr_with_deferrable(self): -- constraint = models.UniqueConstraint( -- fields=['foo', 'bar'], -- name='unique_fields', -- deferrable=models.Deferrable.IMMEDIATE, -- ) -- self.assertEqual( -- repr(constraint), -- "", -- ) -- - def test_repr_with_include(self): - constraint = models.UniqueConstraint( - fields=['foo', 'bar'], -diff --git a/tests/fixtures/tests.py b/tests/fixtures/tests.py -index 06ae3d1..268f7e7 100644 ---- a/tests/fixtures/tests.py -+++ b/tests/fixtures/tests.py -@@ -606,21 +606,6 @@ class FixtureLoadingTests(DumpDataAssertMixin, TestCase): - with self.assertWarnsMessage(ProxyModelWarning, msg): - self._dumpdata_assert(['fixtures.ProxySpy'], '[]') - -- def test_dumpdata_proxy_with_concrete(self): -- """ -- A warning isn't displayed if a proxy model is dumped with its concrete -- parent. -- """ -- spy = ProxySpy.objects.create(name='Paul') -- -- with warnings.catch_warnings(record=True) as warning_list: -- warnings.simplefilter('always') -- self._dumpdata_assert( -- ['fixtures.ProxySpy', 'fixtures.Spy'], -- '[{"pk": %d, "model": "fixtures.spy", "fields": {"cover_blown": false}}]' % spy.pk -- ) -- self.assertEqual(len(warning_list), 0) -- - def test_compress_format_loading(self): - # Load fixture 4 (compressed), using format specification - management.call_command('loaddata', 'fixture4.json', verbosity=0) -diff --git a/tests/model_enums/tests.py b/tests/model_enums/tests.py -index ffc199c..046ef95 100644 ---- a/tests/model_enums/tests.py -+++ b/tests/model_enums/tests.py -@@ -42,23 +42,6 @@ class Gender(models.TextChoices): - - - class ChoicesTests(SimpleTestCase): -- def test_integerchoices(self): -- self.assertEqual(Suit.choices, [(1, 'Diamond'), (2, 'Spade'), (3, 'Heart'), (4, 'Club')]) -- self.assertEqual(Suit.labels, ['Diamond', 'Spade', 'Heart', 'Club']) -- self.assertEqual(Suit.values, [1, 2, 3, 4]) -- self.assertEqual(Suit.names, ['DIAMOND', 'SPADE', 'HEART', 'CLUB']) -- -- self.assertEqual(repr(Suit.DIAMOND), '') -- self.assertEqual(Suit.DIAMOND.label, 'Diamond') -- self.assertEqual(Suit.DIAMOND.value, 1) -- self.assertEqual(Suit['DIAMOND'], Suit.DIAMOND) -- self.assertEqual(Suit(1), Suit.DIAMOND) -- -- self.assertIsInstance(Suit, type(models.Choices)) -- self.assertIsInstance(Suit.DIAMOND, Suit) -- self.assertIsInstance(Suit.DIAMOND.label, Promise) -- self.assertIsInstance(Suit.DIAMOND.value, int) -- - def test_integerchoices_auto_label(self): - self.assertEqual(Vehicle.CAR.label, 'Carriage') - self.assertEqual(Vehicle.TRUCK.label, 'Truck') -@@ -81,25 +64,6 @@ class ChoicesTests(SimpleTestCase): - self.assertIn(1, Suit) - self.assertNotIn(0, Suit) - -- def test_textchoices(self): -- self.assertEqual(YearInSchool.choices, [ -- ('FR', 'Freshman'), ('SO', 'Sophomore'), ('JR', 'Junior'), ('SR', 'Senior'), ('GR', 'Graduate'), -- ]) -- self.assertEqual(YearInSchool.labels, ['Freshman', 'Sophomore', 'Junior', 'Senior', 'Graduate']) -- self.assertEqual(YearInSchool.values, ['FR', 'SO', 'JR', 'SR', 'GR']) -- self.assertEqual(YearInSchool.names, ['FRESHMAN', 'SOPHOMORE', 'JUNIOR', 'SENIOR', 'GRADUATE']) -- -- self.assertEqual(repr(YearInSchool.FRESHMAN), "") -- self.assertEqual(YearInSchool.FRESHMAN.label, 'Freshman') -- self.assertEqual(YearInSchool.FRESHMAN.value, 'FR') -- self.assertEqual(YearInSchool['FRESHMAN'], YearInSchool.FRESHMAN) -- self.assertEqual(YearInSchool('FR'), YearInSchool.FRESHMAN) -- -- self.assertIsInstance(YearInSchool, type(models.Choices)) -- self.assertIsInstance(YearInSchool.FRESHMAN, YearInSchool) -- self.assertIsInstance(YearInSchool.FRESHMAN.label, Promise) -- self.assertIsInstance(YearInSchool.FRESHMAN.value, str) -- - def test_textchoices_auto_label(self): - self.assertEqual(Gender.MALE.label, 'Male') - self.assertEqual(Gender.FEMALE.label, 'Female') -diff --git a/tests/validators/tests.py b/tests/validators/tests.py -index d6d013c..7e7b185 100644 ---- a/tests/validators/tests.py -+++ b/tests/validators/tests.py -@@ -316,19 +316,6 @@ with open(create_path('invalid_urls.txt'), encoding='utf8') as f: - - class TestValidators(SimpleTestCase): - -- def test_validators(self): -- for validator, value, expected in TEST_DATA: -- name = validator.__name__ if isinstance(validator, types.FunctionType) else validator.__class__.__name__ -- exception_expected = expected is not None and issubclass(expected, Exception) -- with self.subTest(name, value=value): -- if validator is validate_image_file_extension and not PILLOW_IS_INSTALLED: -- self.skipTest('Pillow is required to test validate_image_file_extension.') -- if exception_expected: -- with self.assertRaises(expected): -- validator(value) -- else: -- self.assertEqual(expected, validator(value)) -- - def test_single_message(self): - v = ValidationError('Not Valid') - self.assertEqual(str(v), "['Not Valid']") --- -2.31.1 - diff --git a/0002-Remove-failing-test.patch b/0002-Remove-failing-test.patch deleted file mode 100644 index 8cc3eac7990d65843eaace54d823a39938b38474..0000000000000000000000000000000000000000 --- a/0002-Remove-failing-test.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 83cbb38e1702381acceec472a0733cc3f22cd5ba Mon Sep 17 00:00:00 2001 -From: Joel Capitao -Date: Fri, 11 Mar 2022 17:52:15 +0100 -Subject: [PATCH] Remove failing test - ---- - tests/middleware_exceptions/tests.py | 14 -------------- - 1 file changed, 14 deletions(-) - -diff --git a/tests/middleware_exceptions/tests.py b/tests/middleware_exceptions/tests.py -index 2a389ce125..fcc60be7fd 100644 ---- a/tests/middleware_exceptions/tests.py -+++ b/tests/middleware_exceptions/tests.py -@@ -271,20 +271,6 @@ class MiddlewareSyncAsyncTests(SimpleTestCase): - 'Payment Required: /middleware_exceptions/view/', - ) - -- @override_settings( -- DEBUG=False, -- MIDDLEWARE=[ -- 'middleware_exceptions.middleware.AsyncNoTemplateResponseMiddleware', -- ], -- ) -- def test_async_process_template_response_returns_none_with_sync_client(self): -- msg = ( -- "AsyncNoTemplateResponseMiddleware.process_template_response " -- "didn't return an HttpResponse object." -- ) -- with self.assertRaisesMessage(ValueError, msg): -- self.client.get('/middleware_exceptions/template_response/') -- - @override_settings(MIDDLEWARE=[ - 'middleware_exceptions.middleware.SyncAndAsyncMiddleware', - ]) --- -2.35.1 - diff --git a/0003-3.2.24-oc-patch.patch b/0003-3.2.24-oc-patch.patch deleted file mode 100644 index 7ee96e7b750bd26daf0db4cdbec8c8b07ca53b14..0000000000000000000000000000000000000000 --- a/0003-3.2.24-oc-patch.patch +++ /dev/null @@ -1,97 +0,0 @@ -diff -Naur django-3.2.24/tests/file_uploads/tests.py django-3.2.24_oc/tests/file_uploads/tests.py ---- django-3.2.24/tests/file_uploads/tests.py 2024-02-06 21:32:27.000000000 +0800 -+++ django-3.2.24_oc/tests/file_uploads/tests.py 2024-04-09 09:22:57.500917063 +0800 -@@ -707,14 +707,6 @@ - def setUp(self): - self.obj = FileModel() - -- @unittest.skipIf(sys.platform == 'win32', "Python on Windows doesn't have working os.chmod().") -- def test_readonly_root(self): -- """Permission errors are not swallowed""" -- os.chmod(MEDIA_ROOT, 0o500) -- self.addCleanup(os.chmod, MEDIA_ROOT, 0o700) -- with self.assertRaises(PermissionError): -- self.obj.testfile.save('foo.txt', SimpleUploadedFile('foo.txt', b'x'), save=False) -- - def test_not_a_directory(self): - # Create a file with the upload directory name - open(UPLOAD_TO, 'wb').close() -diff -Naur django-3.2.24/tests/forms_tests/tests/test_validators.py django-3.2.24_oc/tests/forms_tests/tests/test_validators.py ---- django-3.2.24/tests/forms_tests/tests/test_validators.py 2024-02-06 21:32:27.000000000 +0800 -+++ django-3.2.24_oc/tests/forms_tests/tests/test_validators.py 2024-04-07 17:54:27.705229016 +0800 -@@ -84,7 +84,6 @@ - (validators.MinLengthValidator(10), 9 * 'x', 'min_length'), - (validators.URLValidator(), 'no_scheme', 'invalid'), - (validators.URLValidator(), 'http://test[.com', 'invalid'), -- (validators.URLValidator(), 'http://[::1:2::3]/', 'invalid'), - ( - validators.URLValidator(), - 'http://' + '.'.join(['a' * 35 for _ in range(9)]), -diff -Naur django-3.2.24/tests/template_tests/test_loaders.py django-3.2.24_oc/tests/template_tests/test_loaders.py ---- django-3.2.24/tests/template_tests/test_loaders.py 2024-02-06 21:32:27.000000000 +0800 -+++ django-3.2.24_oc/tests/template_tests/test_loaders.py 2024-04-09 09:24:35.150105014 +0800 -@@ -185,19 +185,6 @@ - with self.assertRaises(TemplateDoesNotExist): - self.engine.get_template('doesnotexist.html') - -- @unittest.skipIf( -- sys.platform == 'win32', -- "Python on Windows doesn't have working os.chmod().", -- ) -- def test_permissions_error(self): -- with tempfile.NamedTemporaryFile() as tmpfile: -- tmpdir = os.path.dirname(tmpfile.name) -- tmppath = os.path.join(tmpdir, tmpfile.name) -- os.chmod(tmppath, 0o0222) -- with self.set_dirs([tmpdir]): -- with self.assertRaisesMessage(PermissionError, 'Permission denied'): -- self.engine.get_template(tmpfile.name) -- - def test_notafile_error(self): - # Windows raises PermissionError when trying to open a directory. - with self.assertRaises(PermissionError if sys.platform == 'win32' else IsADirectoryError): -diff -Naur django-3.2.24/tests/test_runner/test_debug_sql.py django-3.2.24_oc/tests/test_runner/test_debug_sql.py ---- django-3.2.24/tests/test_runner/test_debug_sql.py 2024-02-06 21:32:27.000000000 +0800 -+++ django-3.2.24_oc/tests/test_runner/test_debug_sql.py 2024-04-09 10:08:59.375345278 +0800 -@@ -82,8 +82,6 @@ - full_output = self._test_output(2) - for output in self.expected_outputs: - self.assertIn(output, full_output) -- for output in self.verbose_expected_outputs: -- self.assertIn(output, full_output) - - expected_outputs = [ - ('''SELECT COUNT(*) AS "__count" ''' -diff -Naur django-3.2.24/tests/test_utils/tests.py django-3.2.24_oc/tests/test_utils/tests.py ---- django-3.2.24/tests/test_utils/tests.py 2024-02-06 21:32:27.000000000 +0800 -+++ django-3.2.24_oc/tests/test_utils/tests.py 2024-04-09 09:23:53.184022606 +0800 -@@ -74,14 +74,6 @@ - def test_foo(self): - pass - -- self._assert_skipping( -- SkipTestCase('test_foo').test_foo, -- ValueError, -- "skipUnlessDBFeature cannot be used on test_foo (test_utils.tests." -- "SkippingTestCase.test_skip_unless_db_feature..SkipTestCase) " -- "as SkippingTestCase.test_skip_unless_db_feature..SkipTestCase " -- "doesn't allow queries against the 'default' database." -- ) - - def test_skip_if_db_feature(self): - """ -@@ -118,14 +110,6 @@ - def test_foo(self): - pass - -- self._assert_skipping( -- SkipTestCase('test_foo').test_foo, -- ValueError, -- "skipIfDBFeature cannot be used on test_foo (test_utils.tests." -- "SkippingTestCase.test_skip_if_db_feature..SkipTestCase) " -- "as SkippingTestCase.test_skip_if_db_feature..SkipTestCase " -- "doesn't allow queries against the 'default' database." -- ) - - - class SkippingClassTestCase(TestCase): diff --git a/python-django-3.2.24-CVE-2024-27351.patch b/python-django-3.2.24-CVE-2024-27351.patch deleted file mode 100644 index aedc085eb8e78ea417cfc5442a2412306dbf110c..0000000000000000000000000000000000000000 --- a/python-django-3.2.24-CVE-2024-27351.patch +++ /dev/null @@ -1,120 +0,0 @@ -From 072963e4c4d0b3a7a8c5412bc0c7d27d1a9c3521 Mon Sep 17 00:00:00 2001 -From: Shai Berger -Date: Mon, 19 Feb 2024 13:56:37 +0100 -Subject: [PATCH] [3.2.x] Fixed CVE-2024-27351 -- Prevented potential ReDoS in - Truncator.words(). - -Thanks Seokchan Yoon for the report. - -Co-Authored-By: Mariusz Felisiak ---- - django/utils/text.py | 57 ++++++++++++++++++++++++++++++++-- - tests/utils_tests/test_text.py | 26 ++++++++++++++++ - 2 files changed, 82 insertions(+), 2 deletions(-) - -diff --git a/django/utils/text.py b/django/utils/text.py -index 83e258fa81c..88da9a2c2c6 100644 ---- a/django/utils/text.py -+++ b/django/utils/text.py -@@ -18,8 +18,61 @@ def capfirst(x): - return x and str(x)[0].upper() + str(x)[1:] - - --# Set up regular expressions --re_words = _lazy_re_compile(r'<[^>]+?>|([^<>\s]+)', re.S) -+# ----- Begin security-related performance workaround ----- -+ -+# We used to have, below -+# -+# re_words = _lazy_re_compile(r"<[^>]+?>|([^<>\s]+)", re.S) -+# -+# But it was shown that this regex, in the way we use it here, has some -+# catastrophic edge-case performance features. Namely, when it is applied to -+# text with only open brackets "<<<...". The class below provides the services -+# and correct answers for the use cases, but in these edge cases does it much -+# faster. -+re_notag = _lazy_re_compile(r"([^<>\s]+)", re.S) -+re_prt = _lazy_re_compile(r"<|([^<>\s]+)", re.S) -+ -+ -+class WordsRegex: -+ @staticmethod -+ def search(text, pos): -+ # Look for "<" or a non-tag word. -+ partial = re_prt.search(text, pos) -+ if partial is None or partial[1] is not None: -+ return partial -+ -+ # "<" was found, look for a closing ">". -+ end = text.find(">", partial.end(0)) -+ if end < 0: -+ # ">" cannot be found, look for a word. -+ return re_notag.search(text, pos + 1) -+ else: -+ # "<" followed by a ">" was found -- fake a match. -+ end += 1 -+ return FakeMatch(text[partial.start(0): end], end) -+ -+ -+class FakeMatch: -+ __slots__ = ["_text", "_end"] -+ -+ def end(self, group=0): -+ assert group == 0, "This specific object takes only group=0" -+ return self._end -+ -+ def __getitem__(self, group): -+ if group == 1: -+ return None -+ assert group == 0, "This specific object takes only group in {0,1}" -+ return self._text -+ -+ def __init__(self, text, end): -+ self._text, self._end = text, end -+ -+ -+# ----- End security-related performance workaround ----- -+ -+# Set up regular expressions. -+re_words = WordsRegex - re_chars = _lazy_re_compile(r'<[^>]+?>|(.)', re.S) - re_tag = _lazy_re_compile(r'<(/)?(\S+?)(?:(\s*/)|\s.*?)?>', re.S) - re_newlines = _lazy_re_compile(r'\r\n|\r') # Used in normalize_newlines - -diff --git a/tests/utils_tests/test_text.py b/tests/utils_tests/test_text.py -index 0a6f0bc3f26..758919c66e8 100644 ---- a/tests/utils_tests/test_text.py -+++ b/tests/utils_tests/test_text.py -@@ -159,6 +159,32 @@ def test_truncate_html_words(self): - truncator = text.Truncator('

I <3 python, what about you?

') - self.assertEqual('

I <3 python,…

', truncator.words(3, html=True)) - -+ # Only open brackets. -+ test = "<" * 60_000 -+ truncator = text.Truncator(test) -+ self.assertEqual(truncator.words(1, html=True), test) -+ -+ # Tags with special chars in attrs. -+ truncator = text.Truncator( -+ """Hello, my dear lady!""" -+ ) -+ self.assertEqual( -+ """Hello, my dear…""", -+ truncator.words(3, html=True), -+ ) -+ -+ # Tags with special non-latin chars in attrs. -+ truncator = text.Truncator("""

Hello, my dear lady!

""") -+ self.assertEqual( -+ """

Hello, my dear…

""", -+ truncator.words(3, html=True), -+ ) -+ -+ # Misplaced brackets. -+ truncator = text.Truncator("hello >< world") -+ self.assertEqual(truncator.words(1, html=True), "hello…") -+ self.assertEqual(truncator.words(2, html=True), "hello >< world") -+ - @patch("django.utils.text.Truncator.MAX_LENGTH_HTML", 10_000) - def test_truncate_words_html_size_limit(self): - max_len = text.Truncator.MAX_LENGTH_HTML diff --git a/python-django.spec b/python-django.spec index a377533d7780d713981bdbab20675517490011b4..9ca61055388e6bf7ed5a97e9cc84654f50966a90 100644 --- a/python-django.spec +++ b/python-django.spec @@ -3,16 +3,11 @@ Summary: A high-level Python Web framework Name: python-django -Version: 3.2.24 -Release: 3%{?dist} +Version: 5.0.8 +Release: 1%{?dist} License: BSD URL: https://www.djangoproject.com/ -Source0: https://github.com/django/django/archive/refs/tags/django-%{version}.tar.gz - -Patch001: 0001-python-3.10-compatibility-disable-failing-tests.patch -Patch002: 0002-Remove-failing-test.patch -Patch003: 0003-3.2.24-oc-patch.patch -Patch004: python-django-3.2.24-CVE-2024-27351.patch +Source0: https://github.com/django/django/archive/refs/tags/%{version}.tar.gz BuildArch: noarch @@ -96,14 +91,12 @@ ln -s ./django-admin %{buildroot}%{_bindir}/python3-django-admin find %{buildroot} -name "*.po" -delete - %check cd %{_builddir}/django-%{version} export PYTHONPATH="$(pwd):%{?with_python_bootstrap:$PYTHONPATH}" cd tests python3 runtests.py --settings=test_sqlite --verbosity=2 --parallel 1 - %files bash-completion %{_datadir}/bash-completion @@ -119,12 +112,15 @@ python3 runtests.py --settings=test_sqlite --verbosity=2 --parallel 1 %{_bindir}/django-admin-3 %{_bindir}/django-admin-%{python3_version} %{_bindir}/python3-django-admin -%{_bindir}/django-admin.py %{python3_sitelib}/* %{_mandir}/man1/django-admin.1* %changelog +* Tue Aug 20 2024 Shop You - 5.0.8-1 +- [Type] security +- [DESC] Resolves: CVE-2024-41989 CVE-2024-41990 CVE-2024-41991 CVE-2024-42005 + * Fri Aug 16 2024 OpenCloudOS Release Engineering - 3.2.24-3 - Rebuilt for loongarch release diff --git a/sources b/sources index 343e6f5687bc2fe7033642ad97d09711e056dd99..d29b767b6ba4617e8c1fe1b213271a79bb359e28 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (django-3.2.24.tar.gz) = 93da1861c74c42548fefd9bb2a435d8a638e81e09be0cb1a79657d9fc66b7deee713ffc4dc4a2757d48ef8aede85edca0c8c74e9bb3fc4e33e0489bdce6a3025 +SHA512 (5.0.8.tar.gz) = 8f029108311cc96044fa160232551203d2dea2a9cab8673277fde6ad7c279061570b2dd46b4ba77f432bbda63074e5a413e07cd4c3d12a5c38d4b199b03198cf