Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python311 for openSUSE:Factory 
checked in at 2026-04-01 19:50:23
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python311 (Old)
 and      /work/SRC/openSUSE:Factory/.python311.new.21863 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python311"

Wed Apr  1 19:50:23 2026 rev:67 rq:1343944 version:3.11.15

Changes:
--------
--- /work/SRC/openSUSE:Factory/python311/python311.changes      2026-03-20 
21:19:33.900900611 +0100
+++ /work/SRC/openSUSE:Factory/.python311.new.21863/python311.changes   
2026-04-01 19:50:29.612777499 +0200
@@ -1,0 +2,28 @@
+Fri Mar 27 17:51:07 UTC 2026 - Matej Cepl <[email protected]>
+
+- Add CVE-2026-4519-webbrowser-open-dashes.patch to reject
+  leading dashes in webbrowser URLs (bsc#1260026, CVE-2026-4519,
+  gh#python/cpython#143930).
+
+-------------------------------------------------------------------
+Wed Mar 25 16:40:18 UTC 2026 - Matej Cepl <[email protected]>
+
+- Add CVE-2025-13462-tarinfo-header-parse.patch which skips
+  TarInfo DIRTYPE normalization during GNU long name handling
+  (bsc#1259611, CVE-2025-13462).
+
+-------------------------------------------------------------------
+Mon Mar 23 22:16:01 UTC 2026 - Matej Cepl <[email protected]>
+
+- Add CVE-2026-4224-expat-unbound-C-recursion.patch avoiding
+  unbound C recursion in conv_content_model in pyexpat.c
+  (bsc#1259735, CVE-2026-4224).
+
+-------------------------------------------------------------------
+Mon Mar 23 17:15:50 UTC 2026 - Matej Cepl <[email protected]>
+
+- Add CVE-2026-3644-cookies-Morsel-update-II.patch to reject
+  control characters in http.cookies.Morsel.update() and
+  http.cookies.BaseCookie.js_output (bsc#1259734, CVE-2026-3644).
+
+-------------------------------------------------------------------

New:
----
  CVE-2025-13462-tarinfo-header-parse.patch
  CVE-2026-3644-cookies-Morsel-update-II.patch
  CVE-2026-4224-expat-unbound-C-recursion.patch
  CVE-2026-4519-webbrowser-open-dashes.patch

----------(New B)----------
  New:
- Add CVE-2025-13462-tarinfo-header-parse.patch which skips
  TarInfo DIRTYPE normalization during GNU long name handling
  New:
- Add CVE-2026-3644-cookies-Morsel-update-II.patch to reject
  control characters in http.cookies.Morsel.update() and
  New:
- Add CVE-2026-4224-expat-unbound-C-recursion.patch avoiding
  unbound C recursion in conv_content_model in pyexpat.c
  New:
- Add CVE-2026-4519-webbrowser-open-dashes.patch to reject
  leading dashes in webbrowser URLs (bsc#1260026, CVE-2026-4519,
----------(New E)----------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python311.spec ++++++
--- /var/tmp/diff_new_pack.0GgIVB/_old  2026-04-01 19:50:34.492980842 +0200
+++ /var/tmp/diff_new_pack.0GgIVB/_new  2026-04-01 19:50:34.524982176 +0200
@@ -200,6 +200,18 @@
 # PATCH-FIX-UPSTREAM CVE-2026-2297-SourcelessFileLoader-io_open_code.patch 
bsc#1259240 [email protected]
 # Ensure SourcelessFileLoader uses io.open_code
 Patch37:        CVE-2026-2297-SourcelessFileLoader-io_open_code.patch
+# PATCH-FIX-UPSTREAM CVE-2026-3644-cookies-Morsel-update-II.patch bsc#1259734 
[email protected]
+# Reject control characters in http.cookies.Morsel.update() and 
http.cookies.BaseCookie.js_output
+Patch38:        CVE-2026-3644-cookies-Morsel-update-II.patch
+# PATCH-FIX-UPSTREAM CVE-2026-4224-expat-unbound-C-recursion.patch bsc#1259735 
[email protected]
+# Avoid unbound C recursion in conv_content_model
+Patch39:        CVE-2026-4224-expat-unbound-C-recursion.patch
+# PATCH-FIX-UPSTREAM CVE-2025-13462-tarinfo-header-parse.patch bsc#1259611 
[email protected]
+# Skip TarInfo DIRTYPE normalization during GNU long name handling
+Patch40:        CVE-2025-13462-tarinfo-header-parse.patch
+# PATCH-FIX-UPSTREAM CVE-2026-4519-webbrowser-open-dashes.patch bsc#1260026 
[email protected]
+# reject leading dashes in webbrowser URLs
+Patch41:        CVE-2026-4519-webbrowser-open-dashes.patch
 ### END OF PATCHES
 BuildRequires:  autoconf-archive
 BuildRequires:  automake

++++++ CVE-2025-13462-tarinfo-header-parse.patch ++++++
>From 4c5d0c79bb55104df59f0f9f9a0ed7fcc073bed9 Mon Sep 17 00:00:00 2001
From: Seth Michael Larson <[email protected]>
Date: Wed, 11 Mar 2026 08:47:55 -0500
Subject: [PATCH] gh-141707: Skip TarInfo DIRTYPE normalization during GNU long
 name handling (cherry picked from commit
 42d754e34c06e57ad6b8e7f92f32af679912d8ab)

Co-authored-by: Seth Michael Larson <[email protected]>
Co-authored-by: Eashwar Ranganathan <[email protected]>
---
 Lib/tarfile.py                                | 29 ++++++++++++++++---
 Lib/test/test_tarfile.py                      | 19 ++++++++++++
 Misc/ACKS                                     |  1 +
 ...-11-18-06-35-53.gh-issue-141707.DBmQIy.rst |  2 ++
 4 files changed, 47 insertions(+), 4 deletions(-)
 create mode 100644 
Misc/NEWS.d/next/Library/2025-11-18-06-35-53.gh-issue-141707.DBmQIy.rst

diff --git a/Lib/tarfile.py b/Lib/tarfile.py
index c04c576ea22d2d..e2d9f9e6c61b31 100755
--- a/Lib/tarfile.py
+++ b/Lib/tarfile.py
@@ -1245,6 +1245,20 @@ def _create_pax_generic_header(cls, pax_headers, type, 
encoding):
     @classmethod
     def frombuf(cls, buf, encoding, errors):
         """Construct a TarInfo object from a 512 byte bytes object.
+
+        To support the old v7 tar format AREGTYPE headers are
+        transformed to DIRTYPE headers if their name ends in '/'.
+        """
+        return cls._frombuf(buf, encoding, errors)
+
+    @classmethod
+    def _frombuf(cls, buf, encoding, errors, *, dircheck=True):
+        """Construct a TarInfo object from a 512 byte bytes object.
+
+        If ``dircheck`` is set to ``True`` then ``AREGTYPE`` headers will
+        be normalized to ``DIRTYPE`` if the name ends in a trailing slash.
+        ``dircheck`` must be set to ``False`` if this function is called
+        on a follow-up header such as ``GNUTYPE_LONGNAME``.
         """
         if len(buf) == 0:
             raise EmptyHeaderError("empty header")
@@ -1275,7 +1289,7 @@ def frombuf(cls, buf, encoding, errors):
 
         # Old V7 tar format represents a directory as a regular
         # file with a trailing slash.
-        if obj.type == AREGTYPE and obj.name.endswith("/"):
+        if dircheck and obj.type == AREGTYPE and obj.name.endswith("/"):
             obj.type = DIRTYPE
 
         # The old GNU sparse format occupies some of the unused
@@ -1310,8 +1324,15 @@ def fromtarfile(cls, tarfile):
         """Return the next TarInfo object from TarFile object
            tarfile.
         """
+        return cls._fromtarfile(tarfile)
+
+    @classmethod
+    def _fromtarfile(cls, tarfile, *, dircheck=True):
+        """
+        See dircheck documentation in _frombuf().
+        """
         buf = tarfile.fileobj.read(BLOCKSIZE)
-        obj = cls.frombuf(buf, tarfile.encoding, tarfile.errors)
+        obj = cls._frombuf(buf, tarfile.encoding, tarfile.errors, 
dircheck=dircheck)
         obj.offset = tarfile.fileobj.tell() - BLOCKSIZE
         return obj._proc_member(tarfile)
 
@@ -1369,7 +1390,7 @@ def _proc_gnulong(self, tarfile):
 
         # Fetch the next header and process it.
         try:
-            next = self.fromtarfile(tarfile)
+            next = self._fromtarfile(tarfile, dircheck=False)
         except HeaderError as e:
             raise SubsequentHeaderError(str(e)) from None
 
@@ -1504,7 +1525,7 @@ def _proc_pax(self, tarfile):
 
         # Fetch the next header.
         try:
-            next = self.fromtarfile(tarfile)
+            next = self._fromtarfile(tarfile, dircheck=False)
         except HeaderError as e:
             raise SubsequentHeaderError(str(e)) from None
 
diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py
index 366aac781df1e7..11066c005629c2 100644
--- a/Lib/test/test_tarfile.py
+++ b/Lib/test/test_tarfile.py
@@ -1105,6 +1105,25 @@ def test_longname_directory(self):
                 self.assertIsNotNone(tar.getmember(longdir))
                 self.assertIsNotNone(tar.getmember(longdir.removesuffix('/')))
 
+    def test_longname_file_not_directory(self):
+        # Test reading a longname file and ensure it is not handled as a 
directory
+        # Issue #141707
+        buf = io.BytesIO()
+        with tarfile.open(mode='w', fileobj=buf, format=self.format) as tar:
+            ti = tarfile.TarInfo()
+            ti.type = tarfile.AREGTYPE
+            ti.name = ('a' * 99) + '/' + ('b' * 3)
+            tar.addfile(ti)
+
+            expected = {t.name: t.type for t in tar.getmembers()}
+
+        buf.seek(0)
+        with tarfile.open(mode='r', fileobj=buf) as tar:
+            actual = {t.name: t.type for t in tar.getmembers()}
+
+        self.assertEqual(expected, actual)
+
+
 class GNUReadTest(LongnameTest, ReadTest, unittest.TestCase):
 
     subdir = "gnu"
diff --git a/Misc/ACKS b/Misc/ACKS
index 89474408a6bbd4..1c0f5d7f782fd3 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -1462,6 +1462,7 @@ Dhushyanth Ramasamy
 Ashwin Ramaswami
 Jeff Ramnani
 Bayard Randel
+Eashwar Ranganathan
 Varpu Rantala
 Brodie Rao
 Rémi Rampin
diff --git 
a/Misc/NEWS.d/next/Library/2025-11-18-06-35-53.gh-issue-141707.DBmQIy.rst 
b/Misc/NEWS.d/next/Library/2025-11-18-06-35-53.gh-issue-141707.DBmQIy.rst
new file mode 100644
index 00000000000000..1f5b8ed90b8a90
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-11-18-06-35-53.gh-issue-141707.DBmQIy.rst
@@ -0,0 +1,2 @@
+Don't change :class:`tarfile.TarInfo` type from ``AREGTYPE`` to ``DIRTYPE`` 
when parsing
+GNU long name or link headers.

++++++ CVE-2026-3644-cookies-Morsel-update-II.patch ++++++
>From 37b75af7264fcffb95135618bef0937dd0ae61b8 Mon Sep 17 00:00:00 2001
From: Stan Ulbrych <[email protected]>
Date: Mon, 16 Mar 2026 13:43:43 +0000
Subject: [PATCH 1/2] gh-145599, CVE 2026-3644: Reject control characters in
 `http.cookies.Morsel.update()` (GH-145600)

Reject control characters in `http.cookies.Morsel.update()` and 
`http.cookies.BaseCookie.js_output`.
(cherry picked from commit 57e88c1cf95e1481b94ae57abe1010469d47a6b4)

Co-authored-by: Stan Ulbrych <[email protected]>
Co-authored-by: Victor Stinner <[email protected]>
Co-authored-by: Victor Stinner <[email protected]>
---
 Lib/http/cookies.py                                                      |   
24 +++++-
 Lib/test/test_http_cookies.py                                            |   
38 ++++++++++
 Misc/NEWS.d/next/Security/2026-03-06-17-03-38.gh-issue-145599.kchwZV.rst |    
4 +
 3 files changed, 62 insertions(+), 4 deletions(-)
 create mode 100644 
Misc/NEWS.d/next/Security/2026-03-06-17-03-38.gh-issue-145599.kchwZV.rst

Index: Python-3.11.15/Lib/http/cookies.py
===================================================================
--- Python-3.11.15.orig/Lib/http/cookies.py     2026-03-23 18:34:54.391763127 
+0100
+++ Python-3.11.15/Lib/http/cookies.py  2026-03-23 18:35:00.009964463 +0100
@@ -335,9 +335,16 @@
             key = key.lower()
             if key not in self._reserved:
                 raise CookieError("Invalid attribute %r" % (key,))
+            if _has_control_character(key, val):
+                raise CookieError("Control characters are not allowed in "
+                                  f"cookies {key!r} {val!r}")
             data[key] = val
         dict.update(self, data)
 
+    def __ior__(self, values):
+        self.update(values)
+        return self
+
     def isReservedKey(self, K):
         return K.lower() in self._reserved
 
@@ -363,9 +370,15 @@
         }
 
     def __setstate__(self, state):
-        self._key = state['key']
-        self._value = state['value']
-        self._coded_value = state['coded_value']
+        key = state['key']
+        value = state['value']
+        coded_value = state['coded_value']
+        if _has_control_character(key, value, coded_value):
+            raise CookieError("Control characters are not allowed in cookies "
+                              f"{key!r} {value!r} {coded_value!r}")
+        self._key = key
+        self._value = value
+        self._coded_value = coded_value
 
     def output(self, attrs=None, header="Set-Cookie:"):
         return "%s %s" % (header, self.OutputString(attrs))
@@ -377,13 +390,16 @@
 
     def js_output(self, attrs=None):
         # Print javascript
+        output_string = self.OutputString(attrs)
+        if _has_control_character(output_string):
+            raise CookieError("Control characters are not allowed in cookies")
         return """
         <script type="text/javascript">
         <!-- begin hiding
         document.cookie = \"%s\";
         // end hiding -->
         </script>
-        """ % (self.OutputString(attrs).replace('"', r'\"'))
+        """ % (output_string.replace('"', r'\"'))
 
     def OutputString(self, attrs=None):
         # Build up our result
Index: Python-3.11.15/Lib/test/test_http_cookies.py
===================================================================
--- Python-3.11.15.orig/Lib/test/test_http_cookies.py   2026-03-23 
18:34:56.166172183 +0100
+++ Python-3.11.15/Lib/test/test_http_cookies.py        2026-03-23 
18:35:00.010236807 +0100
@@ -527,6 +527,14 @@
             with self.assertRaises(cookies.CookieError):
                 morsel["path"] = c0
 
+            # .__setstate__()
+            with self.assertRaises(cookies.CookieError):
+                morsel.__setstate__({'key': c0, 'value': 'val', 'coded_value': 
'coded'})
+            with self.assertRaises(cookies.CookieError):
+                morsel.__setstate__({'key': 'key', 'value': c0, 'coded_value': 
'coded'})
+            with self.assertRaises(cookies.CookieError):
+                morsel.__setstate__({'key': 'key', 'value': 'val', 
'coded_value': c0})
+
             # .setdefault()
             with self.assertRaises(cookies.CookieError):
                 morsel.setdefault("path", c0)
@@ -541,6 +549,18 @@
             with self.assertRaises(cookies.CookieError):
                 morsel.set("path", "val", c0)
 
+            # .update()
+            with self.assertRaises(cookies.CookieError):
+                morsel.update({"path": c0})
+            with self.assertRaises(cookies.CookieError):
+                morsel.update({c0: "val"})
+
+            # .__ior__()
+            with self.assertRaises(cookies.CookieError):
+                morsel |= {"path": c0}
+            with self.assertRaises(cookies.CookieError):
+                morsel |= {c0: "val"}
+
     def test_control_characters_output(self):
         # Tests that even if the internals of Morsel are modified
         # that a call to .output() has control character safeguards.
@@ -561,6 +581,24 @@
             with self.assertRaises(cookies.CookieError):
                 cookie.output()
 
+        # Tests that .js_output() also has control character safeguards.
+        for c0 in support.control_characters_c0():
+            morsel = cookies.Morsel()
+            morsel.set("key", "value", "coded-value")
+            morsel._key = c0  # Override private variable.
+            cookie = cookies.SimpleCookie()
+            cookie["cookie"] = morsel
+            with self.assertRaises(cookies.CookieError):
+                cookie.js_output()
+
+            morsel = cookies.Morsel()
+            morsel.set("key", "value", "coded-value")
+            morsel._coded_value = c0  # Override private variable.
+            cookie = cookies.SimpleCookie()
+            cookie["cookie"] = morsel
+            with self.assertRaises(cookies.CookieError):
+                cookie.js_output()
+
 
 def load_tests(loader, tests, pattern):
     tests.addTest(doctest.DocTestSuite(cookies))
Index: 
Python-3.11.15/Misc/NEWS.d/next/Security/2026-03-06-17-03-38.gh-issue-145599.kchwZV.rst
===================================================================
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
+++ 
Python-3.11.15/Misc/NEWS.d/next/Security/2026-03-06-17-03-38.gh-issue-145599.kchwZV.rst
     2026-03-23 18:35:00.010783538 +0100
@@ -0,0 +1,4 @@
+Reject control characters in :class:`http.cookies.Morsel`
+:meth:`~http.cookies.Morsel.update` and
+:meth:`~http.cookies.BaseCookie.js_output`.
+This addresses `CVE-2026-3644 
<https://www.cve.org/CVERecord?id=CVE-2026-3644>`_.

++++++ CVE-2026-4224-expat-unbound-C-recursion.patch ++++++
>From 4197762fbfb64bca345d9632709678ad7ebf9698 Mon Sep 17 00:00:00 2001
From: Stan Ulbrych <[email protected]>
Date: Sun, 15 Mar 2026 21:46:06 +0000
Subject: [PATCH 1/2] [3.11] gh-145986: Avoid unbound C recursion in
 `conv_content_model` in `pyexpat.c` (CVE 2026-4224) (GH-145987)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Fix C stack overflow (CVE-2026-4224) when an Expat parser
with a registered `ElementDeclHandler` parses inline DTD
containing deeply nested content model.

---------
(cherry picked from commit eb0e8be3a7e11b87d198a2c3af1ed0eccf532768)
(cherry picked from commit e5caf45faac)

Co-authored-by: Stan Ulbrych <[email protected]>
Co-authored-by: Bénédikt Tran <[email protected]>
---
 Lib/test/test_pyexpat.py                                                 |   
18 ++++++++++
 Misc/NEWS.d/next/Security/2026-03-14-17-31-39.gh-issue-145986.ifSSr8.rst |    
4 ++
 Modules/pyexpat.c                                                        |    
9 ++++-
 3 files changed, 30 insertions(+), 1 deletion(-)
 create mode 100644 
Misc/NEWS.d/next/Security/2026-03-14-17-31-39.gh-issue-145986.ifSSr8.rst

Index: Python-3.11.15/Lib/test/test_pyexpat.py
===================================================================
--- Python-3.11.15.orig/Lib/test/test_pyexpat.py        2026-03-24 
09:42:47.659807191 +0100
+++ Python-3.11.15/Lib/test/test_pyexpat.py     2026-03-24 09:42:47.810843451 
+0100
@@ -674,6 +674,24 @@
         parser.Parse(xml2, True)
         self.assertEqual(self.n, 4)
 
+class ElementDeclHandlerTest(unittest.TestCase):
+    def test_deeply_nested_content_model(self):
+        # This should raise a RecursionError and not crash.
+        # See https://github.com/python/cpython/issues/145986.
+        N = 500_000
+        data = (
+            b'<!DOCTYPE root [\n<!ELEMENT root '
+            + b'(a, ' * N + b'a' + b')' * N
+            + b'>\n]>\n<root/>\n'
+        )
+
+        parser = expat.ParserCreate()
+        parser.ElementDeclHandler = lambda _1, _2: None
+        with support.infinite_recursion():
+            with self.assertRaises(RecursionError):
+                parser.Parse(data)
+
+
 class MalformedInputTest(unittest.TestCase):
     def test1(self):
         xml = b"\0\r\n"
Index: 
Python-3.11.15/Misc/NEWS.d/next/Security/2026-03-14-17-31-39.gh-issue-145986.ifSSr8.rst
===================================================================
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
+++ 
Python-3.11.15/Misc/NEWS.d/next/Security/2026-03-14-17-31-39.gh-issue-145986.ifSSr8.rst
     2026-03-24 09:42:47.811748658 +0100
@@ -0,0 +1,4 @@
+:mod:`xml.parsers.expat`: Fixed a crash caused by unbounded C recursion when
+converting deeply nested XML content models with
+:meth:`~xml.parsers.expat.xmlparser.ElementDeclHandler`.
+This addresses `CVE-2026-4224 
<https://www.cve.org/CVERecord?id=CVE-2026-4224>`_.
Index: Python-3.11.15/Modules/pyexpat.c
===================================================================
--- Python-3.11.15.orig/Modules/pyexpat.c       2026-03-03 01:52:57.000000000 
+0100
+++ Python-3.11.15/Modules/pyexpat.c    2026-03-24 09:42:47.811475262 +0100
@@ -3,6 +3,7 @@
 #endif
 
 #include "Python.h"
+#include "pycore_ceval.h"           // _Py_EnterRecursiveCall()
 #include "pycore_runtime.h"         // _Py_ID()
 #include <ctype.h>
 
@@ -578,6 +579,10 @@
 conv_content_model(XML_Content * const model,
                    PyObject *(*conv_string)(const XML_Char *))
 {
+    if (_Py_EnterRecursiveCall(" in conv_content_model")) {
+        return NULL;
+    }
+
     PyObject *result = NULL;
     PyObject *children = PyTuple_New(model->numchildren);
     int i;
@@ -589,7 +594,7 @@
                                                  conv_string);
             if (child == NULL) {
                 Py_XDECREF(children);
-                return NULL;
+                goto done;
             }
             PyTuple_SET_ITEM(children, i, child);
         }
@@ -597,6 +602,8 @@
                                model->type, model->quant,
                                conv_string,model->name, children);
     }
+done:
+    _Py_LeaveRecursiveCall();
     return result;
 }
 

++++++ CVE-2026-4519-webbrowser-open-dashes.patch ++++++
>From 44f1cc679123978895a21b424ab9678bf86b4c78 Mon Sep 17 00:00:00 2001
From: Seth Michael Larson <[email protected]>
Date: Fri, 20 Mar 2026 09:47:13 -0500
Subject: [PATCH] gh-143930: Reject leading dashes in webbrowser URLs

(cherry picked from commit 82a24a4442312bdcfc4c799885e8b3e00990f02b)
---
 Lib/test/test_webbrowser.py                                              |    
5 +++
 Lib/webbrowser.py                                                        |   
14 ++++++++++
 Misc/NEWS.d/next/Security/2026-01-16-12-04-49.gh-issue-143930.zYC5x3.rst |    
1 
 3 files changed, 20 insertions(+)
 create mode 100644 
Misc/NEWS.d/next/Security/2026-01-16-12-04-49.gh-issue-143930.zYC5x3.rst

Index: Python-3.11.15/Lib/test/test_webbrowser.py
===================================================================
--- Python-3.11.15.orig/Lib/test/test_webbrowser.py     2026-03-27 
20:08:53.792496478 +0100
+++ Python-3.11.15/Lib/test/test_webbrowser.py  2026-03-27 20:08:56.539400295 
+0100
@@ -59,6 +59,11 @@
                    options=[],
                    arguments=[URL])
 
+    def test_reject_dash_prefixes(self):
+        browser = self.browser_class(name=CMD_NAME)
+        with self.assertRaises(ValueError):
+            browser.open(f"--key=val {URL}")
+
 
 class BackgroundBrowserCommandTest(CommandTestMixin, unittest.TestCase):
 
Index: Python-3.11.15/Lib/webbrowser.py
===================================================================
--- Python-3.11.15.orig/Lib/webbrowser.py       2026-03-27 20:08:54.301026314 
+0100
+++ Python-3.11.15/Lib/webbrowser.py    2026-03-27 20:08:56.539584483 +0100
@@ -154,6 +154,12 @@
     def open_new_tab(self, url):
         return self.open(url, 2)
 
+    @staticmethod
+    def _check_url(url):
+        """Ensures that the URL is safe to pass to subprocesses as a 
parameter"""
+        if url and url.lstrip().startswith("-"):
+            raise ValueError(f"Invalid URL: {url}")
+
 
 class GenericBrowser(BaseBrowser):
     """Class for all browsers started with a command
@@ -171,6 +177,7 @@
 
     def open(self, url, new=0, autoraise=True):
         sys.audit("webbrowser.open", url)
+        self._check_url(url)
         cmdline = [self.name] + [arg.replace("%s", url)
                                  for arg in self.args]
         try:
@@ -191,6 +198,7 @@
         cmdline = [self.name] + [arg.replace("%s", url)
                                  for arg in self.args]
         sys.audit("webbrowser.open", url)
+        self._check_url(url)
         try:
             if sys.platform[:3] == 'win':
                 p = subprocess.Popen(cmdline)
@@ -256,6 +264,7 @@
 
     def open(self, url, new=0, autoraise=True):
         sys.audit("webbrowser.open", url)
+        self._check_url(url)
         if new == 0:
             action = self.remote_action
         elif new == 1:
@@ -357,6 +366,7 @@
 
     def open(self, url, new=0, autoraise=True):
         sys.audit("webbrowser.open", url)
+        self._check_url(url)
         # XXX Currently I know no way to prevent KFM from opening a new win.
         if new == 2:
             action = "newTab"
@@ -441,6 +451,7 @@
 
     def open(self, url, new=0, autoraise=True):
         sys.audit("webbrowser.open", url)
+        self._check_url(url)
         if new:
             ok = self._remote("LOADNEW " + url)
         else:
@@ -604,6 +615,7 @@
     class WindowsDefault(BaseBrowser):
         def open(self, url, new=0, autoraise=True):
             sys.audit("webbrowser.open", url)
+            self._check_url(url)
             try:
                 os.startfile(url)
             except OSError:
@@ -636,6 +648,7 @@
 
         def open(self, url, new=0, autoraise=True):
             sys.audit("webbrowser.open", url)
+            self._check_url(url)
             assert "'" not in url
             # hack for local urls
             if not ':' in url:
@@ -688,6 +701,7 @@
 
         def open(self, url, new=0, autoraise=True):
             sys.audit("webbrowser.open", url)
+            self._check_url(url)
             if self.name == 'default':
                 script = 'open location "%s"' % url.replace('"', '%22') # 
opens in default browser
             else:
Index: 
Python-3.11.15/Misc/NEWS.d/next/Security/2026-01-16-12-04-49.gh-issue-143930.zYC5x3.rst
===================================================================
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
+++ 
Python-3.11.15/Misc/NEWS.d/next/Security/2026-01-16-12-04-49.gh-issue-143930.zYC5x3.rst
     2026-03-27 20:08:56.539850985 +0100
@@ -0,0 +1 @@
+Reject leading dashes in URLs passed to :func:`webbrowser.open`

++++++ _scmsync.obsinfo ++++++
--- /var/tmp/diff_new_pack.0GgIVB/_old  2026-04-01 19:50:36.197051846 +0200
+++ /var/tmp/diff_new_pack.0GgIVB/_new  2026-04-01 19:50:36.229053179 +0200
@@ -1,6 +1,6 @@
-mtime: 1773825800
-commit: d39b47c9b4695f39c8a586b072290c6604fe446eeda0b8d88bb17bb0e320f1b8
+mtime: 1774638546
+commit: 7ed16c509b9850281cbce11cfd1c8edab9d2058b22c13955d08fa58960874da2
 url: https://src.opensuse.org/python-interpreters/python311.git
-revision: d39b47c9b4695f39c8a586b072290c6604fe446eeda0b8d88bb17bb0e320f1b8
+revision: 7ed16c509b9850281cbce11cfd1c8edab9d2058b22c13955d08fa58960874da2
 projectscmsync: https://src.opensuse.org/python-interpreters/_ObsPrj
 

++++++ build.specials.obscpio ++++++
--- old/.gitignore      2026-03-18 10:24:04.000000000 +0100
+++ new/.gitignore      2026-03-27 20:09:24.000000000 +0100
@@ -1,8 +1,7 @@
-.osc
+_build.*
 *.obscpio
 *.osc
-_build.*
+.osc
 .pbuild
-*.orig
-*.rej
 python311-*-build/
+*.rej

++++++ build.specials.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/.gitignore new/.gitignore
--- old/.gitignore      1970-01-01 01:00:00.000000000 +0100
+++ new/.gitignore      2026-03-27 20:09:24.000000000 +0100
@@ -0,0 +1,7 @@
+_build.*
+*.obscpio
+*.osc
+.osc
+.pbuild
+python311-*-build/
+*.rej

Reply via email to