]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Issue #18167: cgi.FieldStorage no more fails to handle multipart/form-data
authorSerhiy Storchaka <storchaka@gmail.com>
Mon, 17 Jun 2013 13:33:48 +0000 (16:33 +0300)
committerSerhiy Storchaka <storchaka@gmail.com>
Mon, 17 Jun 2013 13:33:48 +0000 (16:33 +0300)
when \r\n appears at end of 65535 bytes without other newlines.

Lib/cgi.py
Lib/test/test_cgi.py
Misc/NEWS

index 67079db0d81a7cdb9d130f1a0c316b6468d453a0..64ba6d16cafba9602dc9268d45fcd270a7d9e446 100755 (executable)
@@ -697,6 +697,9 @@ class FieldStorage:
             if not line:
                 self.done = -1
                 break
+            if delim == "\r":
+                line = delim + line
+                delim = ""
             if line[:2] == "--" and last_line_lfend:
                 strippedline = line.strip()
                 if strippedline == next:
@@ -713,6 +716,12 @@ class FieldStorage:
                 delim = "\n"
                 line = line[:-1]
                 last_line_lfend = True
+            elif line[-1] == "\r":
+                # We may interrupt \r\n sequences if they span the 2**16
+                # byte boundary
+                delim = "\r"
+                line = line[:-1]
+                last_line_lfend = False
             else:
                 delim = ""
                 last_line_lfend = False
index f6abe976cf7bf3cba7a8184409078e2798f68525..7fdd482b9424e48e2628c80f238d8cdec849ce72 100644 (file)
@@ -266,6 +266,29 @@ Content-Disposition: form-data; name="submit"
                 got = getattr(fs.list[x], k)
                 self.assertEqual(got, exp)
 
+    def test_fieldstorage_multipart_maxline(self):
+        # Issue #18167
+        maxline = 1 << 16
+        self.maxDiff = None
+        def check(content):
+            data = """
+---123
+Content-Disposition: form-data; name="upload"; filename="fake.txt"
+Content-Type: text/plain
+
+%s
+---123--
+""".replace('\n', '\r\n') % content
+            environ = {
+                'CONTENT_LENGTH':   str(len(data)),
+                'CONTENT_TYPE':     'multipart/form-data; boundary=-123',
+                'REQUEST_METHOD':   'POST',
+            }
+            self.assertEqual(gen_result(data, environ), {'upload': content})
+        check('x' * (maxline - 1))
+        check('x' * (maxline - 1) + '\r')
+        check('x' * (maxline - 1) + '\r' + 'y' * (maxline - 1))
+
     _qs_result = {
         'key1': 'value1',
         'key2': ['value2x', 'value2y'],
index efcd20a3900e5d83f16835a148ec137a9eb9cb53..2bbcd7059f8fbf2e5500c88db6a757d5b81b910c 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -18,6 +18,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #18167: cgi.FieldStorage no more fails to handle multipart/form-data
+  when \r\n appears at end of 65535 bytes without other newlines.
+
 - Issue #17403: urllib.parse.robotparser normalizes the urls before adding to
   ruleline. This helps in handling certain types invalid urls in a conservative
   manner. Patch contributed by Mher Movsisyan.