diff mbox series

[meta-python,scarthgap,2/8] python3-django: patch CVE-2025-26699

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

Commit Message

Ankur Tyagi Oct. 22, 2025, 6:17 a.m. UTC
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

Comments

Gyorgy Sarvari Oct. 22, 2025, 9:48 a.m. UTC | #1
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]
> -=-=-=-=-=-=-=-=-=-=-=-
>
Ankur Tyagi Oct. 22, 2025, 7:53 p.m. UTC | #2
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]
> > -=-=-=-=-=-=-=-=-=-=-=-
> >
>
Gyorgy Sarvari Oct. 22, 2025, 8:03 p.m. UTC | #3
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 mbox series

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} += "\