Ignore any data after the final multipart boundary.

Closes #489.
This commit is contained in:
Ben Darnell 2012-05-20 23:03:53 -07:00
parent 57a3f83fc6
commit e101397b36
2 changed files with 23 additions and 5 deletions

View File

@ -215,11 +215,11 @@ def parse_multipart_form_data(boundary, data, arguments, files):
# in the wild.
if boundary.startswith(b('"')) and boundary.endswith(b('"')):
boundary = boundary[1:-1]
if data.endswith(b("\r\n")):
footer_length = len(boundary) + 6
else:
footer_length = len(boundary) + 4
parts = data[:-footer_length].split(b("--") + boundary + b("\r\n"))
final_boundary_index = data.rfind(b("--") + boundary + b("--"))
if final_boundary_index == -1:
logging.warning("Invalid multipart/form-data: no final boundary")
return
parts = data[:final_boundary_index].split(b("--") + boundary + b("\r\n"))
for part in parts:
if not part:
continue

View File

@ -177,6 +177,24 @@ Foo
parse_multipart_form_data(b("1234"), data, args, files)
self.assertEqual(files, {})
def test_data_after_final_boundary(self):
# The spec requires that data after the final boundary be ignored.
# http://www.w3.org/Protocols/rfc1341/7_2_Multipart.html
# In practice, some libraries include an extra CRLF after the boundary.
data = b("""\
--1234
Content-Disposition: form-data; name="files"; filename="ab.txt"
Foo
--1234--
""").replace(b("\n"), b("\r\n"))
args = {}
files = {}
parse_multipart_form_data(b("1234"), data, args, files)
file = files["files"][0]
self.assertEqual(file["filename"], "ab.txt")
self.assertEqual(file["body"], b("Foo"))
class HTTPHeadersTest(unittest.TestCase):
def test_multi_line(self):