| Message ID | 20251022061803.887676-2-ankur.tyagi85@gmail.com |
|---|---|
| State | New |
| Headers | show |
| Series | [meta-python,scarthgap,1/8] python3-django: upgrade 4.2.18 -> 4.2.20 | expand |
The patch looks correct and necessary to me, but I find the commit subject and the CVE tag in the patch somewhat misleading. The CVE is patched in 4.2.20, this patch is a fix for a regression that was caused by the fix, but otherwise not related to the CVE. I think the patch should just come as it is, with and explanation of what is it, but without referring to it as a CVE fix. On 10/22/25 08:17, Ankur Tyagi via lists.openembedded.org wrote: > This fixes a regression in Django 4.2.20, introduced when fixing CVE-2025-26699 > > Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com> > --- > .../CVE-2025-26699.patch | 102 ++++++++++++++++++ > .../python/python3-django_4.2.20.bb | 4 + > 2 files changed, 106 insertions(+) > create mode 100644 meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-26699.patch > > diff --git a/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-26699.patch b/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-26699.patch > new file mode 100644 > index 0000000000..54a43b123d > --- /dev/null > +++ b/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-26699.patch > @@ -0,0 +1,102 @@ > +From 3407ea136bd619591d259221d8712b72b3f3b9a0 Mon Sep 17 00:00:00 2001 > +From: Matti Pohjanvirta <matti.pohjanvirta@iki.fi> > +Date: Sun, 20 Apr 2025 18:22:51 +0300 > +Subject: [PATCH] [4.2.x] Fixed #36341 -- Preserved whitespaces in wordwrap > + template filter. > + > +Regression in 55d89e25f4115c5674cdd9b9bcba2bb2bb6d820b. > + > +This work improves the django.utils.text.wrap() function to ensure that > +empty lines and lines with whitespace only are kept instead of being > +dropped. > + > +Thanks Matti Pohjanvirta for the report and fix. > + > +Co-authored-by: Natalia <124304+nessita@users.noreply.github.com> > + > +Backport of 1e9db35836d42a3c72f3d1015c2f302eb6fee046 from main. > + > +CVE: CVE-2025-26699 > +Upstream-Status: Backport [https://github.com/django/django/commit/e61e3daaf037507211028494d61f24382be31e5a] > +(cherry picked from commit e61e3daaf037507211028494d61f24382be31e5a) > +Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com> > +--- > + django/utils/text.py | 13 +++++- > + .../filter_tests/test_wordwrap.py | 41 +++++++++++++++++++ > + 2 files changed, 52 insertions(+), 2 deletions(-) > + > +diff --git a/django/utils/text.py b/django/utils/text.py > +index 81ae88dc76..b018f2601f 100644 > +--- a/django/utils/text.py > ++++ b/django/utils/text.py > +@@ -102,10 +102,19 @@ def wrap(text, width): > + width=width, > + break_long_words=False, > + break_on_hyphens=False, > ++ replace_whitespace=False, > + ) > + result = [] > +- for line in text.splitlines(True): > +- result.extend(wrapper.wrap(line)) > ++ for line in text.splitlines(): > ++ wrapped = wrapper.wrap(line) > ++ if not wrapped: > ++ # If `line` contains only whitespaces that are dropped, restore it. > ++ result.append(line) > ++ else: > ++ result.extend(wrapped) > ++ if text.endswith("\n"): > ++ # If `text` ends with a newline, preserve it. > ++ result.append("") > + return "\n".join(result) > + > + > +diff --git a/tests/template_tests/filter_tests/test_wordwrap.py b/tests/template_tests/filter_tests/test_wordwrap.py > +index 4afa1dd234..1692332e1e 100644 > +--- a/tests/template_tests/filter_tests/test_wordwrap.py > ++++ b/tests/template_tests/filter_tests/test_wordwrap.py > +@@ -89,3 +89,44 @@ class FunctionTests(SimpleTestCase): > + "I'm afraid", > + wordwrap(long_text, 10), > + ) > ++ > ++ def test_wrap_preserve_newlines(self): > ++ cases = [ > ++ ( > ++ "this is a long paragraph of text that really needs to be wrapped\n\n" > ++ "that is followed by another paragraph separated by an empty line\n", > ++ "this is a long paragraph of\ntext that really needs to be\nwrapped\n\n" > ++ "that is followed by another\nparagraph separated by an\nempty line\n", > ++ 30, > ++ ), > ++ ("\n\n\n", "\n\n\n", 5), > ++ ("\n\n\n\n\n\n", "\n\n\n\n\n\n", 5), > ++ ] > ++ for text, expected, width in cases: > ++ with self.subTest(text=text): > ++ self.assertEqual(wordwrap(text, width), expected) > ++ > ++ def test_wrap_preserve_whitespace(self): > ++ width = 5 > ++ width_spaces = " " * width > ++ cases = [ > ++ ( > ++ f"first line\n{width_spaces}\nsecond line", > ++ f"first\nline\n{width_spaces}\nsecond\nline", > ++ ), > ++ ( > ++ "first line\n \t\t\t \nsecond line", > ++ "first\nline\n \t\t\t \nsecond\nline", > ++ ), > ++ ( > ++ f"first line\n{width_spaces}\nsecond line\n\nthird{width_spaces}\n", > ++ f"first\nline\n{width_spaces}\nsecond\nline\n\nthird\n", > ++ ), > ++ ( > ++ f"first line\n{width_spaces}{width_spaces}\nsecond line", > ++ f"first\nline\n{width_spaces}{width_spaces}\nsecond\nline", > ++ ), > ++ ] > ++ for text, expected in cases: > ++ with self.subTest(text=text): > ++ self.assertEqual(wordwrap(text, width), expected) > diff --git a/meta-python/recipes-devtools/python/python3-django_4.2.20.bb b/meta-python/recipes-devtools/python/python3-django_4.2.20.bb > index 3fb8b03224..0b9ff1b8c0 100644 > --- a/meta-python/recipes-devtools/python/python3-django_4.2.20.bb > +++ b/meta-python/recipes-devtools/python/python3-django_4.2.20.bb > @@ -1,6 +1,10 @@ > require python-django.inc > inherit setuptools3 > > +SRC_URI += " \ > + file://CVE-2025-26699.patch \ > +" > + > SRC_URI[sha256sum] = "92bac5b4432a64532abb73b2ac27203f485e40225d2640a7fbef2b62b876e789" > > RDEPENDS:${PN} += "\ > > -=-=-=-=-=-=-=-=-=-=-=- > Links: You receive all messages sent to this group. > View/Reply Online (#120885): https://lists.openembedded.org/g/openembedded-devel/message/120885 > Mute This Topic: https://lists.openembedded.org/mt/115888203/6084445 > Group Owner: openembedded-devel+owner@lists.openembedded.org > Unsubscribe: https://lists.openembedded.org/g/openembedded-devel/unsub [skandigraun@gmail.com] > -=-=-=-=-=-=-=-=-=-=-=- >
On Wed, Oct 22, 2025 at 10:48 PM Gyorgy Sarvari <skandigraun@gmail.com> wrote: > > The patch looks correct and necessary to me, but I find the commit > subject and the CVE tag in the patch somewhat misleading. The CVE is > patched in 4.2.20, this patch is a fix for a regression that was caused > by the fix, but otherwise not related to the CVE. > > I think the patch should just come as it is, with and explanation of > what is it, but without referring to it as a CVE fix. > Good point, I'll submit v2 soon. Should I do similar for the following patches from [patch 4/8] as well? - CVE-2025-48432-1.patch - CVE-2025-48432-2.patch - CVE-2025-48432-4.patch Because they are not the CVE fix but needed to apply CVE fix cleanly. cheers Ankur > On 10/22/25 08:17, Ankur Tyagi via lists.openembedded.org wrote: > > This fixes a regression in Django 4.2.20, introduced when fixing CVE-2025-26699 > > > > Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com> > > --- > > .../CVE-2025-26699.patch | 102 ++++++++++++++++++ > > .../python/python3-django_4.2.20.bb | 4 + > > 2 files changed, 106 insertions(+) > > create mode 100644 meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-26699.patch > > > > diff --git a/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-26699.patch b/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-26699.patch > > new file mode 100644 > > index 0000000000..54a43b123d > > --- /dev/null > > +++ b/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-26699.patch > > @@ -0,0 +1,102 @@ > > +From 3407ea136bd619591d259221d8712b72b3f3b9a0 Mon Sep 17 00:00:00 2001 > > +From: Matti Pohjanvirta <matti.pohjanvirta@iki.fi> > > +Date: Sun, 20 Apr 2025 18:22:51 +0300 > > +Subject: [PATCH] [4.2.x] Fixed #36341 -- Preserved whitespaces in wordwrap > > + template filter. > > + > > +Regression in 55d89e25f4115c5674cdd9b9bcba2bb2bb6d820b. > > + > > +This work improves the django.utils.text.wrap() function to ensure that > > +empty lines and lines with whitespace only are kept instead of being > > +dropped. > > + > > +Thanks Matti Pohjanvirta for the report and fix. > > + > > +Co-authored-by: Natalia <124304+nessita@users.noreply.github.com> > > + > > +Backport of 1e9db35836d42a3c72f3d1015c2f302eb6fee046 from main. > > + > > +CVE: CVE-2025-26699 > > +Upstream-Status: Backport [https://github.com/django/django/commit/e61e3daaf037507211028494d61f24382be31e5a] > > +(cherry picked from commit e61e3daaf037507211028494d61f24382be31e5a) > > +Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com> > > +--- > > + django/utils/text.py | 13 +++++- > > + .../filter_tests/test_wordwrap.py | 41 +++++++++++++++++++ > > + 2 files changed, 52 insertions(+), 2 deletions(-) > > + > > +diff --git a/django/utils/text.py b/django/utils/text.py > > +index 81ae88dc76..b018f2601f 100644 > > +--- a/django/utils/text.py > > ++++ b/django/utils/text.py > > +@@ -102,10 +102,19 @@ def wrap(text, width): > > + width=width, > > + break_long_words=False, > > + break_on_hyphens=False, > > ++ replace_whitespace=False, > > + ) > > + result = [] > > +- for line in text.splitlines(True): > > +- result.extend(wrapper.wrap(line)) > > ++ for line in text.splitlines(): > > ++ wrapped = wrapper.wrap(line) > > ++ if not wrapped: > > ++ # If `line` contains only whitespaces that are dropped, restore it. > > ++ result.append(line) > > ++ else: > > ++ result.extend(wrapped) > > ++ if text.endswith("\n"): > > ++ # If `text` ends with a newline, preserve it. > > ++ result.append("") > > + return "\n".join(result) > > + > > + > > +diff --git a/tests/template_tests/filter_tests/test_wordwrap.py b/tests/template_tests/filter_tests/test_wordwrap.py > > +index 4afa1dd234..1692332e1e 100644 > > +--- a/tests/template_tests/filter_tests/test_wordwrap.py > > ++++ b/tests/template_tests/filter_tests/test_wordwrap.py > > +@@ -89,3 +89,44 @@ class FunctionTests(SimpleTestCase): > > + "I'm afraid", > > + wordwrap(long_text, 10), > > + ) > > ++ > > ++ def test_wrap_preserve_newlines(self): > > ++ cases = [ > > ++ ( > > ++ "this is a long paragraph of text that really needs to be wrapped\n\n" > > ++ "that is followed by another paragraph separated by an empty line\n", > > ++ "this is a long paragraph of\ntext that really needs to be\nwrapped\n\n" > > ++ "that is followed by another\nparagraph separated by an\nempty line\n", > > ++ 30, > > ++ ), > > ++ ("\n\n\n", "\n\n\n", 5), > > ++ ("\n\n\n\n\n\n", "\n\n\n\n\n\n", 5), > > ++ ] > > ++ for text, expected, width in cases: > > ++ with self.subTest(text=text): > > ++ self.assertEqual(wordwrap(text, width), expected) > > ++ > > ++ def test_wrap_preserve_whitespace(self): > > ++ width = 5 > > ++ width_spaces = " " * width > > ++ cases = [ > > ++ ( > > ++ f"first line\n{width_spaces}\nsecond line", > > ++ f"first\nline\n{width_spaces}\nsecond\nline", > > ++ ), > > ++ ( > > ++ "first line\n \t\t\t \nsecond line", > > ++ "first\nline\n \t\t\t \nsecond\nline", > > ++ ), > > ++ ( > > ++ f"first line\n{width_spaces}\nsecond line\n\nthird{width_spaces}\n", > > ++ f"first\nline\n{width_spaces}\nsecond\nline\n\nthird\n", > > ++ ), > > ++ ( > > ++ f"first line\n{width_spaces}{width_spaces}\nsecond line", > > ++ f"first\nline\n{width_spaces}{width_spaces}\nsecond\nline", > > ++ ), > > ++ ] > > ++ for text, expected in cases: > > ++ with self.subTest(text=text): > > ++ self.assertEqual(wordwrap(text, width), expected) > > diff --git a/meta-python/recipes-devtools/python/python3-django_4.2.20.bb b/meta-python/recipes-devtools/python/python3-django_4.2.20.bb > > index 3fb8b03224..0b9ff1b8c0 100644 > > --- a/meta-python/recipes-devtools/python/python3-django_4.2.20.bb > > +++ b/meta-python/recipes-devtools/python/python3-django_4.2.20.bb > > @@ -1,6 +1,10 @@ > > require python-django.inc > > inherit setuptools3 > > > > +SRC_URI += " \ > > + file://CVE-2025-26699.patch \ > > +" > > + > > SRC_URI[sha256sum] = "92bac5b4432a64532abb73b2ac27203f485e40225d2640a7fbef2b62b876e789" > > > > RDEPENDS:${PN} += "\ > > > > -=-=-=-=-=-=-=-=-=-=-=- > > Links: You receive all messages sent to this group. > > View/Reply Online (#120885): https://lists.openembedded.org/g/openembedded-devel/message/120885 > > Mute This Topic: https://lists.openembedded.org/mt/115888203/6084445 > > Group Owner: openembedded-devel+owner@lists.openembedded.org > > Unsubscribe: https://lists.openembedded.org/g/openembedded-devel/unsub [skandigraun@gmail.com] > > -=-=-=-=-=-=-=-=-=-=-=- > > >
On 10/22/25 21:53, Ankur Tyagi wrote: > On Wed, Oct 22, 2025 at 10:48 PM Gyorgy Sarvari <skandigraun@gmail.com> wrote: >> The patch looks correct and necessary to me, but I find the commit >> subject and the CVE tag in the patch somewhat misleading. The CVE is >> patched in 4.2.20, this patch is a fix for a regression that was caused >> by the fix, but otherwise not related to the CVE. >> >> I think the patch should just come as it is, with and explanation of >> what is it, but without referring to it as a CVE fix. >> > Good point, I'll submit v2 soon. > > Should I do similar for the following patches from [patch 4/8] as well? > - CVE-2025-48432-1.patch > - CVE-2025-48432-2.patch > - CVE-2025-48432-4.patch > Because they are not the CVE fix but needed to apply CVE fix cleanly. Personally I wouldn't bother with that - if you want to be pedantic, then you can do the same, but since they are pre-reqs for the actual fix, I can also argue for keeping the CVE tag in all. > > cheers > Ankur > >> On 10/22/25 08:17, Ankur Tyagi via lists.openembedded.org wrote: >>> This fixes a regression in Django 4.2.20, introduced when fixing CVE-2025-26699 >>> >>> Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com> >>> --- >>> .../CVE-2025-26699.patch | 102 ++++++++++++++++++ >>> .../python/python3-django_4.2.20.bb | 4 + >>> 2 files changed, 106 insertions(+) >>> create mode 100644 meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-26699.patch >>> >>> diff --git a/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-26699.patch b/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-26699.patch >>> new file mode 100644 >>> index 0000000000..54a43b123d >>> --- /dev/null >>> +++ b/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-26699.patch >>> @@ -0,0 +1,102 @@ >>> +From 3407ea136bd619591d259221d8712b72b3f3b9a0 Mon Sep 17 00:00:00 2001 >>> +From: Matti Pohjanvirta <matti.pohjanvirta@iki.fi> >>> +Date: Sun, 20 Apr 2025 18:22:51 +0300 >>> +Subject: [PATCH] [4.2.x] Fixed #36341 -- Preserved whitespaces in wordwrap >>> + template filter. >>> + >>> +Regression in 55d89e25f4115c5674cdd9b9bcba2bb2bb6d820b. >>> + >>> +This work improves the django.utils.text.wrap() function to ensure that >>> +empty lines and lines with whitespace only are kept instead of being >>> +dropped. >>> + >>> +Thanks Matti Pohjanvirta for the report and fix. >>> + >>> +Co-authored-by: Natalia <124304+nessita@users.noreply.github.com> >>> + >>> +Backport of 1e9db35836d42a3c72f3d1015c2f302eb6fee046 from main. >>> + >>> +CVE: CVE-2025-26699 >>> +Upstream-Status: Backport [https://github.com/django/django/commit/e61e3daaf037507211028494d61f24382be31e5a] >>> +(cherry picked from commit e61e3daaf037507211028494d61f24382be31e5a) >>> +Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com> >>> +--- >>> + django/utils/text.py | 13 +++++- >>> + .../filter_tests/test_wordwrap.py | 41 +++++++++++++++++++ >>> + 2 files changed, 52 insertions(+), 2 deletions(-) >>> + >>> +diff --git a/django/utils/text.py b/django/utils/text.py >>> +index 81ae88dc76..b018f2601f 100644 >>> +--- a/django/utils/text.py >>> ++++ b/django/utils/text.py >>> +@@ -102,10 +102,19 @@ def wrap(text, width): >>> + width=width, >>> + break_long_words=False, >>> + break_on_hyphens=False, >>> ++ replace_whitespace=False, >>> + ) >>> + result = [] >>> +- for line in text.splitlines(True): >>> +- result.extend(wrapper.wrap(line)) >>> ++ for line in text.splitlines(): >>> ++ wrapped = wrapper.wrap(line) >>> ++ if not wrapped: >>> ++ # If `line` contains only whitespaces that are dropped, restore it. >>> ++ result.append(line) >>> ++ else: >>> ++ result.extend(wrapped) >>> ++ if text.endswith("\n"): >>> ++ # If `text` ends with a newline, preserve it. >>> ++ result.append("") >>> + return "\n".join(result) >>> + >>> + >>> +diff --git a/tests/template_tests/filter_tests/test_wordwrap.py b/tests/template_tests/filter_tests/test_wordwrap.py >>> +index 4afa1dd234..1692332e1e 100644 >>> +--- a/tests/template_tests/filter_tests/test_wordwrap.py >>> ++++ b/tests/template_tests/filter_tests/test_wordwrap.py >>> +@@ -89,3 +89,44 @@ class FunctionTests(SimpleTestCase): >>> + "I'm afraid", >>> + wordwrap(long_text, 10), >>> + ) >>> ++ >>> ++ def test_wrap_preserve_newlines(self): >>> ++ cases = [ >>> ++ ( >>> ++ "this is a long paragraph of text that really needs to be wrapped\n\n" >>> ++ "that is followed by another paragraph separated by an empty line\n", >>> ++ "this is a long paragraph of\ntext that really needs to be\nwrapped\n\n" >>> ++ "that is followed by another\nparagraph separated by an\nempty line\n", >>> ++ 30, >>> ++ ), >>> ++ ("\n\n\n", "\n\n\n", 5), >>> ++ ("\n\n\n\n\n\n", "\n\n\n\n\n\n", 5), >>> ++ ] >>> ++ for text, expected, width in cases: >>> ++ with self.subTest(text=text): >>> ++ self.assertEqual(wordwrap(text, width), expected) >>> ++ >>> ++ def test_wrap_preserve_whitespace(self): >>> ++ width = 5 >>> ++ width_spaces = " " * width >>> ++ cases = [ >>> ++ ( >>> ++ f"first line\n{width_spaces}\nsecond line", >>> ++ f"first\nline\n{width_spaces}\nsecond\nline", >>> ++ ), >>> ++ ( >>> ++ "first line\n \t\t\t \nsecond line", >>> ++ "first\nline\n \t\t\t \nsecond\nline", >>> ++ ), >>> ++ ( >>> ++ f"first line\n{width_spaces}\nsecond line\n\nthird{width_spaces}\n", >>> ++ f"first\nline\n{width_spaces}\nsecond\nline\n\nthird\n", >>> ++ ), >>> ++ ( >>> ++ f"first line\n{width_spaces}{width_spaces}\nsecond line", >>> ++ f"first\nline\n{width_spaces}{width_spaces}\nsecond\nline", >>> ++ ), >>> ++ ] >>> ++ for text, expected in cases: >>> ++ with self.subTest(text=text): >>> ++ self.assertEqual(wordwrap(text, width), expected) >>> diff --git a/meta-python/recipes-devtools/python/python3-django_4.2.20.bb b/meta-python/recipes-devtools/python/python3-django_4.2.20.bb >>> index 3fb8b03224..0b9ff1b8c0 100644 >>> --- a/meta-python/recipes-devtools/python/python3-django_4.2.20.bb >>> +++ b/meta-python/recipes-devtools/python/python3-django_4.2.20.bb >>> @@ -1,6 +1,10 @@ >>> require python-django.inc >>> inherit setuptools3 >>> >>> +SRC_URI += " \ >>> + file://CVE-2025-26699.patch \ >>> +" >>> + >>> SRC_URI[sha256sum] = "92bac5b4432a64532abb73b2ac27203f485e40225d2640a7fbef2b62b876e789" >>> >>> RDEPENDS:${PN} += "\ >>> >>> -=-=-=-=-=-=-=-=-=-=-=- >>> Links: You receive all messages sent to this group. >>> View/Reply Online (#120885): https://lists.openembedded.org/g/openembedded-devel/message/120885 >>> Mute This Topic: https://lists.openembedded.org/mt/115888203/6084445 >>> Group Owner: openembedded-devel+owner@lists.openembedded.org >>> Unsubscribe: https://lists.openembedded.org/g/openembedded-devel/unsub [skandigraun@gmail.com] >>> -=-=-=-=-=-=-=-=-=-=-=- >>>
diff --git a/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-26699.patch b/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-26699.patch new file mode 100644 index 0000000000..54a43b123d --- /dev/null +++ b/meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-26699.patch @@ -0,0 +1,102 @@ +From 3407ea136bd619591d259221d8712b72b3f3b9a0 Mon Sep 17 00:00:00 2001 +From: Matti Pohjanvirta <matti.pohjanvirta@iki.fi> +Date: Sun, 20 Apr 2025 18:22:51 +0300 +Subject: [PATCH] [4.2.x] Fixed #36341 -- Preserved whitespaces in wordwrap + template filter. + +Regression in 55d89e25f4115c5674cdd9b9bcba2bb2bb6d820b. + +This work improves the django.utils.text.wrap() function to ensure that +empty lines and lines with whitespace only are kept instead of being +dropped. + +Thanks Matti Pohjanvirta for the report and fix. + +Co-authored-by: Natalia <124304+nessita@users.noreply.github.com> + +Backport of 1e9db35836d42a3c72f3d1015c2f302eb6fee046 from main. + +CVE: CVE-2025-26699 +Upstream-Status: Backport [https://github.com/django/django/commit/e61e3daaf037507211028494d61f24382be31e5a] +(cherry picked from commit e61e3daaf037507211028494d61f24382be31e5a) +Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com> +--- + django/utils/text.py | 13 +++++- + .../filter_tests/test_wordwrap.py | 41 +++++++++++++++++++ + 2 files changed, 52 insertions(+), 2 deletions(-) + +diff --git a/django/utils/text.py b/django/utils/text.py +index 81ae88dc76..b018f2601f 100644 +--- a/django/utils/text.py ++++ b/django/utils/text.py +@@ -102,10 +102,19 @@ def wrap(text, width): + width=width, + break_long_words=False, + break_on_hyphens=False, ++ replace_whitespace=False, + ) + result = [] +- for line in text.splitlines(True): +- result.extend(wrapper.wrap(line)) ++ for line in text.splitlines(): ++ wrapped = wrapper.wrap(line) ++ if not wrapped: ++ # If `line` contains only whitespaces that are dropped, restore it. ++ result.append(line) ++ else: ++ result.extend(wrapped) ++ if text.endswith("\n"): ++ # If `text` ends with a newline, preserve it. ++ result.append("") + return "\n".join(result) + + +diff --git a/tests/template_tests/filter_tests/test_wordwrap.py b/tests/template_tests/filter_tests/test_wordwrap.py +index 4afa1dd234..1692332e1e 100644 +--- a/tests/template_tests/filter_tests/test_wordwrap.py ++++ b/tests/template_tests/filter_tests/test_wordwrap.py +@@ -89,3 +89,44 @@ class FunctionTests(SimpleTestCase): + "I'm afraid", + wordwrap(long_text, 10), + ) ++ ++ def test_wrap_preserve_newlines(self): ++ cases = [ ++ ( ++ "this is a long paragraph of text that really needs to be wrapped\n\n" ++ "that is followed by another paragraph separated by an empty line\n", ++ "this is a long paragraph of\ntext that really needs to be\nwrapped\n\n" ++ "that is followed by another\nparagraph separated by an\nempty line\n", ++ 30, ++ ), ++ ("\n\n\n", "\n\n\n", 5), ++ ("\n\n\n\n\n\n", "\n\n\n\n\n\n", 5), ++ ] ++ for text, expected, width in cases: ++ with self.subTest(text=text): ++ self.assertEqual(wordwrap(text, width), expected) ++ ++ def test_wrap_preserve_whitespace(self): ++ width = 5 ++ width_spaces = " " * width ++ cases = [ ++ ( ++ f"first line\n{width_spaces}\nsecond line", ++ f"first\nline\n{width_spaces}\nsecond\nline", ++ ), ++ ( ++ "first line\n \t\t\t \nsecond line", ++ "first\nline\n \t\t\t \nsecond\nline", ++ ), ++ ( ++ f"first line\n{width_spaces}\nsecond line\n\nthird{width_spaces}\n", ++ f"first\nline\n{width_spaces}\nsecond\nline\n\nthird\n", ++ ), ++ ( ++ f"first line\n{width_spaces}{width_spaces}\nsecond line", ++ f"first\nline\n{width_spaces}{width_spaces}\nsecond\nline", ++ ), ++ ] ++ for text, expected in cases: ++ with self.subTest(text=text): ++ self.assertEqual(wordwrap(text, width), expected) diff --git a/meta-python/recipes-devtools/python/python3-django_4.2.20.bb b/meta-python/recipes-devtools/python/python3-django_4.2.20.bb index 3fb8b03224..0b9ff1b8c0 100644 --- a/meta-python/recipes-devtools/python/python3-django_4.2.20.bb +++ b/meta-python/recipes-devtools/python/python3-django_4.2.20.bb @@ -1,6 +1,10 @@ require python-django.inc inherit setuptools3 +SRC_URI += " \ + file://CVE-2025-26699.patch \ +" + SRC_URI[sha256sum] = "92bac5b4432a64532abb73b2ac27203f485e40225d2640a7fbef2b62b876e789" RDEPENDS:${PN} += "\
This fixes a regression in Django 4.2.20, introduced when fixing CVE-2025-26699 Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com> --- .../CVE-2025-26699.patch | 102 ++++++++++++++++++ .../python/python3-django_4.2.20.bb | 4 + 2 files changed, 106 insertions(+) create mode 100644 meta-python/recipes-devtools/python/python3-django-4.2.20/CVE-2025-26699.patch