bpo-34226: fix cgi.parse_multipart without content_length (GH-8530)
In Python 3.7 the behavior of parse_multipart changed requiring CONTENT-LENGTH header, this fix remove this header as required and fix FieldStorage read_lines_to_outerboundary, by not using limit when it's negative, since by default it's -1 if not content-length and keeps substracting what was read from the file object. Also added a test case for this problem.
This commit is contained in:
parent
e2d47a0568
commit
d8cf3514dd
|
@ -200,7 +200,10 @@ def parse_multipart(fp, pdict, encoding="utf-8", errors="replace"):
|
||||||
ctype = "multipart/form-data; boundary={}".format(boundary)
|
ctype = "multipart/form-data; boundary={}".format(boundary)
|
||||||
headers = Message()
|
headers = Message()
|
||||||
headers.set_type(ctype)
|
headers.set_type(ctype)
|
||||||
headers['Content-Length'] = pdict['CONTENT-LENGTH']
|
try:
|
||||||
|
headers['Content-Length'] = pdict['CONTENT-LENGTH']
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
fs = FieldStorage(fp, headers=headers, encoding=encoding, errors=errors,
|
fs = FieldStorage(fp, headers=headers, encoding=encoding, errors=errors,
|
||||||
environ={'REQUEST_METHOD': 'POST'})
|
environ={'REQUEST_METHOD': 'POST'})
|
||||||
return {k: fs.getlist(k) for k in fs}
|
return {k: fs.getlist(k) for k in fs}
|
||||||
|
@ -736,7 +739,8 @@ class FieldStorage:
|
||||||
last_line_lfend = True
|
last_line_lfend = True
|
||||||
_read = 0
|
_read = 0
|
||||||
while 1:
|
while 1:
|
||||||
if self.limit is not None and _read >= self.limit:
|
|
||||||
|
if self.limit is not None and 0 <= self.limit <= _read:
|
||||||
break
|
break
|
||||||
line = self.fp.readline(1<<16) # bytes
|
line = self.fp.readline(1<<16) # bytes
|
||||||
self.bytes_read += len(line)
|
self.bytes_read += len(line)
|
||||||
|
|
|
@ -128,6 +128,20 @@ class CgiTests(unittest.TestCase):
|
||||||
'file': [b'Testing 123.\n'], 'title': ['']}
|
'file': [b'Testing 123.\n'], 'title': ['']}
|
||||||
self.assertEqual(result, expected)
|
self.assertEqual(result, expected)
|
||||||
|
|
||||||
|
def test_parse_multipart_without_content_length(self):
|
||||||
|
POSTDATA = '''--JfISa01
|
||||||
|
Content-Disposition: form-data; name="submit-name"
|
||||||
|
|
||||||
|
just a string
|
||||||
|
|
||||||
|
--JfISa01--
|
||||||
|
'''
|
||||||
|
fp = BytesIO(POSTDATA.encode('latin1'))
|
||||||
|
env = {'boundary': 'JfISa01'.encode('latin1')}
|
||||||
|
result = cgi.parse_multipart(fp, env)
|
||||||
|
expected = {'submit-name': ['just a string\n']}
|
||||||
|
self.assertEqual(result, expected)
|
||||||
|
|
||||||
def test_parse_multipart_invalid_encoding(self):
|
def test_parse_multipart_invalid_encoding(self):
|
||||||
BOUNDARY = "JfISa01"
|
BOUNDARY = "JfISa01"
|
||||||
POSTDATA = """--JfISa01
|
POSTDATA = """--JfISa01
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Fix `cgi.parse_multipart` without content_length. Patch by Roger Duran
|
Loading…
Reference in New Issue