Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MultipartParseError when parsing empty message #38

Open
connection-reset opened this issue Jul 14, 2021 · 3 comments
Open

MultipartParseError when parsing empty message #38

connection-reset opened this issue Jul 14, 2021 · 3 comments

Comments

@connection-reset
Copy link

connection-reset commented Jul 14, 2021

Parsing an empty message, i.e. a message with only the final boundary, raises MultipartParseError in MultipartParser._internal_write:

Traceback (most recent call last):
  File "/tmp/repro.py", line 5, in <module>
    parser.write(b"--" + boundary + b"--\r\n")
  File "/tmp/python-multipart/multipart/multipart.py", line 1076, in write
    l = self._internal_write(data, data_len)
  File "/tmp/python-multipart/multipart/multipart.py", line 1154, in _internal_write
    raise e
multipart.exceptions.MultipartParseError: Did not find CR at end of boundary (3)

How to reproduce (ed8c47a):

import multipart

boundary = b"-"
parser = multipart.MultipartParser(boundary)
parser.write(b"--" + boundary + b"--\r\n")

Firefox and Chrome produce empty messages like this, e.g. when POSTing a HTML form with only a unchecked checkbox.

@alex-pobeditel-2004
Copy link

Confirming it. Reproduced during parsing of form with all optional fields (useful for PATCH).
Is this behaviour expected?

@mrharpo
Copy link

mrharpo commented Sep 18, 2023

I'm getting this same error from a starlette-admin webapp: jowilf/starlette-admin#262

Sample code:

class ArticleView(ModelView):
    actions = ['test', 'delete']

    @action(
        name='test',
        text='Test',
        confirmation='Are you sure?',
        form="""
        <form>
            <input type="checkbox" id="check" name="check">
            <label for="check">Breaks unless you check it</label>
        </form>
        """,
    )
    async def make_published_action(self, request: Request, pks: List[Any]) -> str:
        data: FormData = await request.form()
        print(data)

When the form has an <input> with no value, it throws: MultipartParseError: Did not find CR at end of boundary.

This also happens with type="radio" when submitted with options unselected.

@mrharpo
Copy link

mrharpo commented Oct 4, 2023

I finally found a workaround: include a hidden value in the form.

        <form>
            <input type="checkbox" id="check" name="check">
            <label for="check">Doesn't break, thanks to hidden value!</label>
            <input type="hidden" name="_" value="">
        </form>

Works even when value is "", as above.

I'm assuming it's something about parsing a completely empty form, since check is only passed if it is "on".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
3 participants