File CVE-2024-53981.patch of Package python-python-multipart.36679

From c4fe4d3cebc08c660e57dd709af1ffa7059b3177 Mon Sep 17 00:00:00 2001
From: Marcelo Trylesinski <marcelotryle@gmail.com>
Date: Sun, 1 Dec 2024 07:59:34 +0100
Subject: [PATCH] Don't warn when CRLF is found after last boundary (#193)

---
 CHANGELOG.md                  |  4 ++++
 python_multipart/__init__.py  |  2 +-
 python_multipart/multipart.py |  4 ++++
 scripts/check                 |  2 +-
 tests/test_multipart.py       | 26 ++++++++++++++++++++++++++
 5 files changed, 36 insertions(+), 2 deletions(-)

Index: python_multipart-0.0.9/tests/test_multipart.py
===================================================================
--- python_multipart-0.0.9.orig/tests/test_multipart.py
+++ python_multipart-0.0.9/tests/test_multipart.py
@@ -1,3 +1,4 @@
+import logging
 import os
 import random
 import sys
@@ -6,6 +7,7 @@ import unittest
 from io import BytesIO
 from unittest.mock import Mock
 
+import pytest
 import yaml
 
 from multipart.decoders import Base64Decoder, QuotedPrintableDecoder
@@ -1161,6 +1163,30 @@ class TestFormParser(unittest.TestCase):
         self.assertEqual(fields[2].field_name, b"baz")
         self.assertEqual(fields[2].value, b"asdf")
 
+    @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):
+            files.append(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):
         # Load test data.
         test_file = "single_field_single_file.http"
Index: python_multipart-0.0.9/multipart/multipart.py
===================================================================
--- python_multipart-0.0.9.orig/multipart/multipart.py
+++ python_multipart-0.0.9/multipart/multipart.py
@@ -1457,6 +1457,11 @@ class MultipartParser(BaseParser):
                     i -= 1
 
             elif state == MultipartState.END:
+                # Don't do anything if chunk ends with CRLF.
+                if c == CR and i + 1 < length and data[i + 1] == LF:
+                    i += 2
+                    continue
+
                 # 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)
openSUSE Build Service is sponsored by