Skip to content

Commit 9a1ecbd

Browse files
authored
Handle CTE values case-insensitively (#258)
1 parent ef2a0b9 commit 9a1ecbd

2 files changed

Lines changed: 22 additions & 1 deletion

File tree

python_multipart/multipart.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1665,7 +1665,9 @@ def on_headers_finished() -> None:
16651665
# Parse the given Content-Transfer-Encoding to determine what
16661666
# we need to do with the incoming data.
16671667
# TODO: check that we properly handle 8bit / 7bit encoding.
1668-
transfer_encoding = headers.get(b"content-transfer-encoding", b"7bit")
1668+
# RFC 2045 section 6.1: Content-Transfer-Encoding values are case-insensitive.
1669+
# https://www.rfc-editor.org/rfc/rfc2045#section-6.1
1670+
transfer_encoding = headers.get(b"content-transfer-encoding", b"7bit").lower()
16691671

16701672
if transfer_encoding in (b"binary", b"8bit", b"7bit"):
16711673
writer = f_multi

tests/test_multipart.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,25 @@ def split_all(val: bytes) -> Iterator[tuple[bytes, bytes]]:
746746
yield (val[:i], val[i:])
747747

748748

749+
@pytest.mark.parametrize("content_transfer_encoding", [b"base64", b"BASE64", b"Base64"])
750+
def test_content_transfer_encoding_is_case_insensitive(content_transfer_encoding: bytes) -> None:
751+
data = (
752+
b'----boundary\r\nContent-Disposition: form-data; name="file"; filename="test.txt"\r\n'
753+
b"Content-Type: text/plain\r\n"
754+
b"Content-Transfer-Encoding: " + content_transfer_encoding + b"\r\n\r\nVGVzdA==\r\n----boundary--\r\n"
755+
)
756+
files: list[File] = []
757+
758+
f = FormParser("multipart/form-data", None, files.append, boundary="--boundary")
759+
760+
f.write(data)
761+
f.finalize()
762+
763+
file = files[0]
764+
file.file_object.seek(0)
765+
assert file.file_object.read() == b"Test"
766+
767+
749768
@parametrize_class
750769
class TestFormParser(unittest.TestCase):
751770
def make(self, boundary: str | bytes, config: dict[str, Any] = {}) -> None:

0 commit comments

Comments
 (0)