From 3b2637d9b4461c431d09f3f004eec46513a17aa6 Mon Sep 17 00:00:00 2001 From: Pierre Quentel Date: Wed, 21 Nov 2018 17:52:40 +0100 Subject: [PATCH 1/4] bpo-20504 : in cgi.py, fix bug when a multipart/form-data request has no content-length header --- Lib/cgi.py | 8 +++++--- Lib/test/test_cgi.py | 17 +++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/Lib/cgi.py b/Lib/cgi.py index b96bd1f0fe39ac..c22c71b3878516 100755 --- a/Lib/cgi.py +++ b/Lib/cgi.py @@ -461,7 +461,7 @@ def __init__(self, fp=None, headers=None, outerboundary=b'', if maxlen and clen > maxlen: raise ValueError('Maximum content length exceeded') self.length = clen - if self.limit is None and clen: + if self.limit is None and clen >= 0: self.limit = clen self.list = self.file = None @@ -642,8 +642,10 @@ def read_multi(self, environ, keep_blank_values, strict_parsing): if 'content-length' in headers: del headers['content-length'] + limit = None if self.limit is None \ + else self.limit - self.bytes_read part = klass(self.fp, headers, ib, environ, keep_blank_values, - strict_parsing,self.limit-self.bytes_read, + strict_parsing, limit, self.encoding, self.errors, max_num_fields) if max_num_fields is not None: @@ -734,7 +736,7 @@ def read_lines_to_outerboundary(self): last_line_lfend = True _read = 0 while 1: - if _read >= self.limit: + if self.limit is not None and _read >= self.limit: break line = self.fp.readline(1<<16) # bytes self.bytes_read += len(line) diff --git a/Lib/test/test_cgi.py b/Lib/test/test_cgi.py index b86638e1c283af..47243be27f14e1 100644 --- a/Lib/test/test_cgi.py +++ b/Lib/test/test_cgi.py @@ -353,6 +353,23 @@ def test_fieldstorage_part_content_length(self): self.assertEqual(fs.list[0].name, 'submit-name') self.assertEqual(fs.list[0].value, 'Larry') + def test_field_storage_multipart_no_content_length(self): + fp = BytesIO(b"""--MyBoundary +Content-Disposition: form-data; name="my-arg"; filename="foo" + +Test + +--MyBoundary-- +""") + env = { + "REQUEST_METHOD": "POST", + "CONTENT_TYPE": "multipart/form-data; boundary=MyBoundary", + "wsgi.input": fp, + } + fields = cgi.FieldStorage(fp, environ=env) + + assert len(fields["my-arg"].file.read()) == 5 + def test_fieldstorage_as_context_manager(self): fp = BytesIO(b'x' * 10) env = {'REQUEST_METHOD': 'PUT'} From 3fe582193ef83716044c8aa8156ca35b859c7a15 Mon Sep 17 00:00:00 2001 From: Pierre Quentel Date: Wed, 21 Nov 2018 18:06:22 +0100 Subject: [PATCH 2/4] Add Misc/NEWS.d/next file. --- .../next/Library/2018-11-21-18-05-50.bpo-20504.kG0ub5.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2018-11-21-18-05-50.bpo-20504.kG0ub5.rst diff --git a/Misc/NEWS.d/next/Library/2018-11-21-18-05-50.bpo-20504.kG0ub5.rst b/Misc/NEWS.d/next/Library/2018-11-21-18-05-50.bpo-20504.kG0ub5.rst new file mode 100644 index 00000000000000..bb16df5eef9dc5 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-11-21-18-05-50.bpo-20504.kG0ub5.rst @@ -0,0 +1,2 @@ +Fixes a bug in cgi.py when a multipart/form-data request has no +Content-Length header. From 20dbfda8691245461e2693d9b1391a09c2aa0c72 Mon Sep 17 00:00:00 2001 From: Pierre Quentel Date: Thu, 22 Nov 2018 14:59:10 +0100 Subject: [PATCH 3/4] Add rst formatting for NEWS.d/next file --- .../next/Library/2018-11-21-18-05-50.bpo-20504.kG0ub5.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Misc/NEWS.d/next/Library/2018-11-21-18-05-50.bpo-20504.kG0ub5.rst b/Misc/NEWS.d/next/Library/2018-11-21-18-05-50.bpo-20504.kG0ub5.rst index bb16df5eef9dc5..726329ad0d65ad 100644 --- a/Misc/NEWS.d/next/Library/2018-11-21-18-05-50.bpo-20504.kG0ub5.rst +++ b/Misc/NEWS.d/next/Library/2018-11-21-18-05-50.bpo-20504.kG0ub5.rst @@ -1,2 +1,2 @@ -Fixes a bug in cgi.py when a multipart/form-data request has no -Content-Length header. +Fixes a bug in :mod:`cgi` module when a multipart/form-data request has no +`Content-Length` header. From d67919b11e9cf0f6f98419938123ad6a38bfd5da Mon Sep 17 00:00:00 2001 From: Pierre Quentel Date: Thu, 3 Jan 2019 10:32:59 +0100 Subject: [PATCH 4/4] Reaplce assert by self.assertEqual --- Lib/test/test_cgi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_cgi.py b/Lib/test/test_cgi.py index 47243be27f14e1..6ab3572436fc51 100644 --- a/Lib/test/test_cgi.py +++ b/Lib/test/test_cgi.py @@ -368,7 +368,7 @@ def test_field_storage_multipart_no_content_length(self): } fields = cgi.FieldStorage(fp, environ=env) - assert len(fields["my-arg"].file.read()) == 5 + self.assertEqual(len(fields["my-arg"].file.read()), 5) def test_fieldstorage_as_context_manager(self): fp = BytesIO(b'x' * 10)