Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-python-multipart for
openSUSE:Factory checked in at 2026-05-28 23:07:32
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-python-multipart (Old)
and /work/SRC/openSUSE:Factory/.python-python-multipart.new.1937 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-python-multipart"
Thu May 28 23:07:32 2026 rev:16 rq:1355079 version:0.0.29
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-python-multipart/python-python-multipart.changes
2026-05-16 19:25:46.605112193 +0200
+++
/work/SRC/openSUSE:Factory/.python-python-multipart.new.1937/python-python-multipart.changes
2026-05-28 23:07:41.816931063 +0200
@@ -1,0 +2,7 @@
+Mon May 25 15:34:47 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 0.0.29:
+ * Handle malformed RFC 2231 continuations in
+ `parse_options_header` #270.
+
+-------------------------------------------------------------------
Old:
----
python_multipart-0.0.28.tar.gz
New:
----
python_multipart-0.0.29.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-python-multipart.spec ++++++
--- /var/tmp/diff_new_pack.GewHPr/_old 2026-05-28 23:07:43.404996446 +0200
+++ /var/tmp/diff_new_pack.GewHPr/_new 2026-05-28 23:07:43.404996446 +0200
@@ -18,7 +18,7 @@
%{?sle15_python_module_pythons}
Name: python-python-multipart
-Version: 0.0.28
+Version: 0.0.29
Release: 0
License: Apache-2.0
Summary: Python streaming multipart parser
++++++ python_multipart-0.0.28.tar.gz -> python_multipart-0.0.29.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python_multipart-0.0.28/CHANGELOG.md
new/python_multipart-0.0.29/CHANGELOG.md
--- old/python_multipart-0.0.28/CHANGELOG.md 2020-02-02 01:00:00.000000000
+0100
+++ new/python_multipart-0.0.29/CHANGELOG.md 2020-02-02 01:00:00.000000000
+0100
@@ -1,5 +1,9 @@
# Changelog
+## 0.0.29 (2026-05-17)
+
+* Handle malformed RFC 2231 continuations in `parse_options_header`
[#270](https://github.com/Kludex/python-multipart/pull/270).
+
## 0.0.28 (2026-05-10)
* Speed up partial-boundary tail scan via `bytes.find`
[#281](https://github.com/Kludex/python-multipart/pull/281).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python_multipart-0.0.28/PKG-INFO
new/python_multipart-0.0.29/PKG-INFO
--- old/python_multipart-0.0.28/PKG-INFO 2020-02-02 01:00:00.000000000
+0100
+++ new/python_multipart-0.0.29/PKG-INFO 2020-02-02 01:00:00.000000000
+0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.4
Name: python-multipart
-Version: 0.0.28
+Version: 0.0.29
Summary: A streaming multipart parser for Python
Project-URL: Homepage, https://github.com/Kludex/python-multipart
Project-URL: Documentation, https://kludex.github.io/python-multipart/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python_multipart-0.0.28/pyproject.toml
new/python_multipart-0.0.29/pyproject.toml
--- old/python_multipart-0.0.28/pyproject.toml 2020-02-02 01:00:00.000000000
+0100
+++ new/python_multipart-0.0.29/pyproject.toml 2020-02-02 01:00:00.000000000
+0100
@@ -59,6 +59,9 @@
"pymdown-extensions>=10.21.2",
]
+[tool.uv]
+exclude-newer = "7 days"
+
[tool.uv.pip]
reinstall-package = ["python-multipart"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python_multipart-0.0.28/python_multipart/__init__.py
new/python_multipart-0.0.29/python_multipart/__init__.py
--- old/python_multipart-0.0.28/python_multipart/__init__.py 2020-02-02
01:00:00.000000000 +0100
+++ new/python_multipart-0.0.29/python_multipart/__init__.py 2020-02-02
01:00:00.000000000 +0100
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-__version__ = "0.0.28"
+__version__ = "0.0.29"
from .multipart import (
BaseParser,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python_multipart-0.0.28/python_multipart/multipart.py
new/python_multipart-0.0.29/python_multipart/multipart.py
--- old/python_multipart-0.0.28/python_multipart/multipart.py 2020-02-02
01:00:00.000000000 +0100
+++ new/python_multipart-0.0.29/python_multipart/multipart.py 2020-02-02
01:00:00.000000000 +0100
@@ -179,7 +179,15 @@
# ctype, rest = value.split(b';', 1)
message = Message()
message["content-type"] = value
- params = message.get_params()
+ # `get_params()` can raise on malformed RFC 2231 headers found via fuzzing:
+ # - ValueError on oversized continuation indices (all supported versions).
+ # - TypeError on mixed `filename*` + `filename*0*` continuations (Python
3.12 only;
+ # 3.13+ silently picks a value).
+ # TODO: drop `TypeError` once Python 3.12 reaches EOL (October 2028).
+ try:
+ params = message.get_params()
+ except (TypeError, ValueError): # pragma: no cover
+ return (value.split(";", 1)[0].lower().strip().encode("latin-1"), {})
# If there were no parameters, this would have already returned above
assert params, "At least the content type value should be present"
ctype = params.pop(0)[0].encode("latin-1")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python_multipart-0.0.28/tests/test_multipart.py
new/python_multipart-0.0.29/tests/test_multipart.py
--- old/python_multipart-0.0.28/tests/test_multipart.py 2020-02-02
01:00:00.000000000 +0100
+++ new/python_multipart-0.0.29/tests/test_multipart.py 2020-02-02
01:00:00.000000000 +0100
@@ -304,6 +304,19 @@
self.assertEqual(p[b"param"], b"encoded message")
+ def test_rejects_oversized_rfc_2231_index(self) -> None:
+ t, p = parse_options_header("text/plain; filename*" + ("1" * 4301) +
"*=utf-8''x")
+
+ self.assertEqual(t, b"text/plain")
+ self.assertEqual(p, {})
+
+ @pytest.mark.skipif(sys.version_info >= (3, 13), reason="email parser only
raises TypeError on Python 3.12")
+ def test_rejects_mixed_rfc_2231_continuations(self) -> None:
+ t, p = parse_options_header("text/plain; filename*=utf-8''a;
filename*0*=utf-8''b")
+
+ self.assertEqual(t, b"text/plain")
+ self.assertEqual(p, {})
+
class TestBaseParser(unittest.TestCase):
def setUp(self) -> None: