pimoroni / phew

MIT License
204 stars 44 forks source link

Phew._handle_request does not ensure content-length of data read #56

Open ccrighton opened 1 year ago

ccrighton commented 1 year ago

When content-type is application/x-www-form-urlencoded, the current implementation makes a single call to read:

 if request.headers["content-type"].startswith("application/x-www-form-urlencoded"):
        form_data = await reader.read(int(request.headers["content-length"]))
        request.form = _parse_query_string(form_data.decode())

Unfortunately, this doesn't always read all content-length bytes. It's necessary to loop until all bytes are read e.g.

  if request.headers["content-type"].startswith("application/x-www-form-urlencoded"):
    form_data = b""
    content_length = int(request.headers["content-length"])
    while content_length > 0:
        data = await reader.read(content_length)
        if len(data) == 0:
          break
        content_length -= len(data)
        form_data += data
    request.form = _parse_query_string(form_data.decode())

I was posting a textarea with about 1400 bytes. It was only reading about 250.

Other parts of the implementation may need to be checked to ensure that no other similar issue is present.

jimkoke commented 9 months ago

I ran into this problem, too, but with a form with email addresses. I fixed it in a similar manner. In that case, the parser did not have a complete name=value pair, but only sometimes as the email addresses I entered changed length.