Skip to content

Commit 2d7caca

Browse files
PierreQuentelbenjaminp
authored andcommitted
bpo-20504 : in cgi.py, fix bug when a multipart/form-data request has… (#10638)
* bpo-20504 : in cgi.py, fix bug when a multipart/form-data request has no content-length header * Add Misc/NEWS.d/next file. * Add rst formatting for NEWS.d/next file * Reaplce assert by self.assertEqual
1 parent 972cf5c commit 2d7caca

File tree

3 files changed

+24
-3
lines changed

3 files changed

+24
-3
lines changed

Lib/cgi.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ def __init__(self, fp=None, headers=None, outerboundary=b'',
461461
if maxlen and clen > maxlen:
462462
raise ValueError('Maximum content length exceeded')
463463
self.length = clen
464-
if self.limit is None and clen:
464+
if self.limit is None and clen >= 0:
465465
self.limit = clen
466466

467467
self.list = self.file = None
@@ -642,8 +642,10 @@ def read_multi(self, environ, keep_blank_values, strict_parsing):
642642
if 'content-length' in headers:
643643
del headers['content-length']
644644

645+
limit = None if self.limit is None \
646+
else self.limit - self.bytes_read
645647
part = klass(self.fp, headers, ib, environ, keep_blank_values,
646-
strict_parsing,self.limit-self.bytes_read,
648+
strict_parsing, limit,
647649
self.encoding, self.errors, max_num_fields)
648650

649651
if max_num_fields is not None:
@@ -734,7 +736,7 @@ def read_lines_to_outerboundary(self):
734736
last_line_lfend = True
735737
_read = 0
736738
while 1:
737-
if _read >= self.limit:
739+
if self.limit is not None and _read >= self.limit:
738740
break
739741
line = self.fp.readline(1<<16) # bytes
740742
self.bytes_read += len(line)

Lib/test/test_cgi.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,23 @@ def test_fieldstorage_part_content_length(self):
352352
self.assertEqual(fs.list[0].name, 'submit-name')
353353
self.assertEqual(fs.list[0].value, 'Larry')
354354

355+
def test_field_storage_multipart_no_content_length(self):
356+
fp = BytesIO(b"""--MyBoundary
357+
Content-Disposition: form-data; name="my-arg"; filename="foo"
358+
359+
Test
360+
361+
--MyBoundary--
362+
""")
363+
env = {
364+
"REQUEST_METHOD": "POST",
365+
"CONTENT_TYPE": "multipart/form-data; boundary=MyBoundary",
366+
"wsgi.input": fp,
367+
}
368+
fields = cgi.FieldStorage(fp, environ=env)
369+
370+
self.assertEqual(len(fields["my-arg"].file.read()), 5)
371+
355372
def test_fieldstorage_as_context_manager(self):
356373
fp = BytesIO(b'x' * 10)
357374
env = {'REQUEST_METHOD': 'PUT'}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fixes a bug in :mod:`cgi` module when a multipart/form-data request has no
2+
`Content-Length` header.

0 commit comments

Comments
 (0)