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 2024-12-05 17:05:16
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-python-multipart (Old)
and /work/SRC/openSUSE:Factory/.python-python-multipart.new.28523 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-python-multipart"
Thu Dec 5 17:05:16 2024 rev:10 rq:1228255 version:0.0.19
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-python-multipart/python-python-multipart.changes
2024-11-08 11:58:40.971718077 +0100
+++
/work/SRC/openSUSE:Factory/.python-python-multipart.new.28523/python-python-multipart.changes
2024-12-05 17:05:44.566311739 +0100
@@ -1,0 +2,8 @@
+Wed Dec 4 10:08:03 UTC 2024 - Daniel Garcia <[email protected]>
+
+- Update to 0.0.19 (bsc#1234115, CVE-2024-53981):
+ * Don't warn when CRLF is found after last boundary #193
+- 0.0.18:
+ * Hard break if found data after last boundary on MultipartParser #189
+
+-------------------------------------------------------------------
Old:
----
python_multipart-0.0.17.tar.gz
New:
----
python_multipart-0.0.19.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-python-multipart.spec ++++++
--- /var/tmp/diff_new_pack.uybWe6/_old 2024-12-05 17:05:45.218339044 +0100
+++ /var/tmp/diff_new_pack.uybWe6/_new 2024-12-05 17:05:45.218339044 +0100
@@ -18,11 +18,11 @@
%{?sle15_python_module_pythons}
Name: python-python-multipart
-Version: 0.0.17
+Version: 0.0.19
Release: 0
License: Apache-2.0
Summary: Python streaming multipart parser
-URL: http://github.com/andrew-d/python-multipart
+URL: http://github.com/Kludex/python-multipart
Source:
https://files.pythonhosted.org/packages/source/p/python-multipart/python_multipart-%{version}.tar.gz
BuildRequires: %{python_module hatchling}
BuildRequires: %{python_module pip}
++++++ python_multipart-0.0.17.tar.gz -> python_multipart-0.0.19.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python_multipart-0.0.17/CHANGELOG.md
new/python_multipart-0.0.19/CHANGELOG.md
--- old/python_multipart-0.0.17/CHANGELOG.md 2020-02-02 01:00:00.000000000
+0100
+++ new/python_multipart-0.0.19/CHANGELOG.md 2020-02-02 01:00:00.000000000
+0100
@@ -1,5 +1,13 @@
# Changelog
+## 0.0.19 (2024-11-30)
+
+* Don't warn when CRLF is found after last boundary on `MultipartParser`
[#193](https://github.com/Kludex/python-multipart/pull/193).
+
+## 0.0.18 (2024-11-28)
+
+* Hard break if found data after last boundary on `MultipartParser`
[#189](https://github.com/Kludex/python-multipart/pull/189).
+
## 0.0.17 (2024-10-31)
* Handle PermissionError in fallback code for old import name
[#182](https://github.com/Kludex/python-multipart/pull/182).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python_multipart-0.0.17/PKG-INFO
new/python_multipart-0.0.19/PKG-INFO
--- old/python_multipart-0.0.17/PKG-INFO 2020-02-02 01:00:00.000000000
+0100
+++ new/python_multipart-0.0.19/PKG-INFO 2020-02-02 01:00:00.000000000
+0100
@@ -1,14 +1,13 @@
Metadata-Version: 2.3
Name: python-multipart
-Version: 0.0.17
+Version: 0.0.19
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/
Project-URL: Changelog,
https://github.com/Kludex/python-multipart/blob/master/CHANGELOG.md
Project-URL: Source, https://github.com/Kludex/python-multipart
Author-email: Andrew Dunham <[email protected]>, Marcelo Trylesinski
<[email protected]>
-License-Expression: Apache-2.0
-License-File: LICENSE.txt
+License: Apache-2.0
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python_multipart-0.0.17/pyproject.toml
new/python_multipart-0.0.19/pyproject.toml
--- old/python_multipart-0.0.17/pyproject.toml 2020-02-02 01:00:00.000000000
+0100
+++ new/python_multipart-0.0.19/pyproject.toml 2020-02-02 01:00:00.000000000
+0100
@@ -44,7 +44,7 @@
"PyYAML==6.0.1",
"invoke==2.2.0",
"pytest-timeout==2.3.1",
- "ruff==0.3.4",
+ "ruff==0.8.0",
"mypy",
"types-PyYAML",
"atheris==2.3.0; python_version != '3.12'",
@@ -122,4 +122,4 @@
]
[tool.check-sdist]
-git-only = ["docs", "fuzz", "scripts", "mkdocs.yml", "uv.lock"]
+git-only = ["docs", "fuzz", "scripts", "mkdocs.yml", "uv.lock", "SECURITY.md"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python_multipart-0.0.17/python_multipart/__init__.py
new/python_multipart-0.0.19/python_multipart/__init__.py
--- old/python_multipart-0.0.17/python_multipart/__init__.py 2020-02-02
01:00:00.000000000 +0100
+++ new/python_multipart-0.0.19/python_multipart/__init__.py 2020-02-02
01:00:00.000000000 +0100
@@ -2,7 +2,7 @@
__author__ = "Andrew Dunham"
__license__ = "Apache"
__copyright__ = "Copyright (c) 2012-2013, Andrew Dunham"
-__version__ = "0.0.17"
+__version__ = "0.0.19"
from .multipart import (
BaseParser,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python_multipart-0.0.17/python_multipart/multipart.py
new/python_multipart-0.0.19/python_multipart/multipart.py
--- old/python_multipart-0.0.17/python_multipart/multipart.py 2020-02-02
01:00:00.000000000 +0100
+++ new/python_multipart-0.0.19/python_multipart/multipart.py 2020-02-02
01:00:00.000000000 +0100
@@ -1105,7 +1105,6 @@
# Skip leading newlines
if c == CR or c == LF:
i += 1
- self.logger.debug("Skipping leading CR/LF at %d", i)
continue
# index is used as in index into our boundary. Set to 0.
@@ -1398,9 +1397,14 @@
i -= 1
elif state == MultipartState.END:
- # Do nothing and just consume a byte in the end state.
- if c not in (CR, LF):
- self.logger.warning("Consuming a byte '0x%x' in the end
state", c) # pragma: no cover
+ # Don't do anything if chunk ends with CRLF.
+ if c == CR and i + 1 < length and data[i + 1] == LF:
+ i += 2
+ continue
+ # Skip data after the last boundary.
+ self.logger.warning("Skipping data after last boundary")
+ i = length
+ break
else: # pragma: no cover (error case)
# We got into a strange state somehow! Just stop processing.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python_multipart-0.0.17/tests/test_multipart.py
new/python_multipart-0.0.19/tests/test_multipart.py
--- old/python_multipart-0.0.17/tests/test_multipart.py 2020-02-02
01:00:00.000000000 +0100
+++ new/python_multipart-0.0.19/tests/test_multipart.py 2020-02-02
01:00:00.000000000 +0100
@@ -1,5 +1,6 @@
from __future__ import annotations
+import logging
import os
import random
import sys
@@ -9,6 +10,7 @@
from typing import TYPE_CHECKING, cast
from unittest.mock import Mock
+import pytest
import yaml
from python_multipart.decoders import Base64Decoder, QuotedPrintableDecoder
@@ -825,7 +827,7 @@
return
# No error!
- self.assertEqual(processed, len(param["test"]))
+ self.assertEqual(processed, len(param["test"]), param["name"])
# Assert that the parser gave us the appropriate fields/files.
for e in param["result"]["expected"]:
@@ -1210,6 +1212,68 @@
self.assertEqual(fields[2].field_name, b"baz")
self.assertEqual(fields[2].value, b"asdf")
+ def test_multipart_parser_newlines_before_first_boundary(self) -> None:
+ """This test makes sure that the parser does not handle when there is
junk data after the last boundary."""
+ num = 5_000_000
+ data = (
+ "\r\n" * num + "--boundary\r\n"
+ 'Content-Disposition: form-data; name="file";
filename="filename.txt"\r\n'
+ "Content-Type: text/plain\r\n\r\n"
+ "hello\r\n"
+ "--boundary--"
+ )
+
+ files: list[File] = []
+
+ def on_file(f: FileProtocol) -> None:
+ files.append(cast(File, f))
+
+ f = FormParser("multipart/form-data", on_field=Mock(),
on_file=on_file, boundary="boundary")
+ f.write(data.encode("latin-1"))
+
+ def test_multipart_parser_data_after_last_boundary(self) -> None:
+ """This test makes sure that the parser does not handle when there is
junk data after the last boundary."""
+ num = 50_000_000
+ data = (
+ "--boundary\r\n"
+ 'Content-Disposition: form-data; name="file";
filename="filename.txt"\r\n'
+ "Content-Type: text/plain\r\n\r\n"
+ "hello\r\n"
+ "--boundary--" + "-" * num + "\r\n"
+ )
+
+ files: list[File] = []
+
+ def on_file(f: FileProtocol) -> None:
+ files.append(cast(File, f))
+
+ f = FormParser("multipart/form-data", on_field=Mock(),
on_file=on_file, boundary="boundary")
+ f.write(data.encode("latin-1"))
+
+ @pytest.fixture(autouse=True)
+ def inject_fixtures(self, caplog: pytest.LogCaptureFixture) -> None:
+ self._caplog = caplog
+
+ def test_multipart_parser_data_end_with_crlf_without_warnings(self) ->
None:
+ """This test makes sure that the parser does not handle when the data
ends with a CRLF."""
+ data = (
+ "--boundary\r\n"
+ 'Content-Disposition: form-data; name="file";
filename="filename.txt"\r\n'
+ "Content-Type: text/plain\r\n\r\n"
+ "hello\r\n"
+ "--boundary--\r\n"
+ )
+
+ files: list[File] = []
+
+ def on_file(f: FileProtocol) -> None:
+ files.append(cast(File, f))
+
+ f = FormParser("multipart/form-data", on_field=Mock(),
on_file=on_file, boundary="boundary")
+ with self._caplog.at_level(logging.WARNING):
+ f.write(data.encode("latin-1"))
+ assert len(self._caplog.records) == 0
+
def test_max_size_multipart(self) -> None:
# Load test data.
test_file = "single_field_single_file.http"