Skip to content

Base64Decoder raises DecodeError on line-wrapped (MIME-style) base64 #340

Open

Description

@prudhvi1709

Base64Decoder.write() slices the input to a multiple of 4 bytes before decoding, but it counts line breaks and spaces as base64 characters. Standard base64 as used in MIME (RFC 2045) is wrapped with CRLF or LF, so any quartet that straddles a line break is miscounted and decoding fails. The result also depends on how the stream is chunked.

Reproduction

from io import BytesIO
from python_multipart.decoders import Base64Decoder

out = BytesIO()
d = Base64Decoder(out)
d.write(b"Zm9v\r\nYmFy")   # DecodeError
d.finalize()

Expected: b"foobar", which is what base64.b64decode(b"Zm9v\r\nYmFy") returns.

Split writes fail the same way:

d.write(b"Zm9v\r")
d.write(b"\nYmFy")         # DecodeError

base64.encodebytes(bytes(range(200))) (76-character lines) written in chunks of 10, 7 or 1 bytes also raises DecodeError.

Cause

write() computes decode_len = (len(data) // 4) * 4 on data that still contains \r, \n, space and tab. b64decode() then discards those bytes (it is not called with validate=True), leaving a slice that is not a multiple of 4, and raises "Incorrect padding".

Version: python-multipart 0.0.32, main at 51ff1a4, Python 3.13.

Fix

A fix with a regression test is submitted in #341.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions