]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-34226: fix cgi.parse_multipart without content_length (GH-8530)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Mon, 15 Jun 2020 15:51:35 +0000 (08:51 -0700)
committerGitHub <noreply@github.com>
Mon, 15 Jun 2020 15:51:35 +0000 (08:51 -0700)
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.
(cherry picked from commit d8cf3514dd4682419a66f6e834bb384ee34afc95)

Co-authored-by: roger <rogerduran@gmail.com>
Lib/cgi.py
Lib/test/test_cgi.py
Misc/NEWS.d/next/Library/2018-07-29-12-14-54.bpo-34226.BE7zbu.rst [new file with mode: 0644]

index c22c71b3878516508f63ce5dfcfa99ad1beef554..77ab703cc036004a980e5e014d69120fa8e5e072 100755 (executable)
@@ -200,7 +200,10 @@ def parse_multipart(fp, pdict, encoding="utf-8", errors="replace"):
     ctype = "multipart/form-data; boundary={}".format(boundary)
     headers = Message()
     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,
         environ={'REQUEST_METHOD': 'POST'})
     return {k: fs.getlist(k) for k in fs}
@@ -736,7 +739,8 @@ class FieldStorage:
         last_line_lfend = True
         _read = 0
         while 1:
-            if self.limit is not None and _read >= self.limit:
+
+            if self.limit is not None and 0 <= self.limit <= _read:
                 break
             line = self.fp.readline(1<<16) # bytes
             self.bytes_read += len(line)
index ab8677199f32e79cf5a602df51bc70bcb0d066d1..101942de947fb461220cce6376828f43d3d19cdc 100644 (file)
@@ -128,6 +128,20 @@ class CgiTests(unittest.TestCase):
                     'file': [b'Testing 123.\n'], 'title': ['']}
         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):
         BOUNDARY = "JfISa01"
         POSTDATA = """--JfISa01
diff --git a/Misc/NEWS.d/next/Library/2018-07-29-12-14-54.bpo-34226.BE7zbu.rst b/Misc/NEWS.d/next/Library/2018-07-29-12-14-54.bpo-34226.BE7zbu.rst
new file mode 100644 (file)
index 0000000..2656b4b
--- /dev/null
@@ -0,0 +1 @@
+Fix `cgi.parse_multipart` without content_length. Patch by Roger Duran