summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2013-06-17 16:33:48 +0300
committerSerhiy Storchaka <storchaka@gmail.com>2013-06-17 16:33:48 +0300
commite2cc341ffab9bcbc430d2d6b2ea1d5775db66eff (patch)
tree77ae07818497d2137ee46f720c2f85a55e68c791
parenta49dcc51b8fcdcdf06f1e5b136b5835d754a0d05 (diff)
downloadcpython-git-e2cc341ffab9bcbc430d2d6b2ea1d5775db66eff.tar.gz
Issue #18167: cgi.FieldStorage no more fails to handle multipart/form-data
when \r\n appears at end of 65535 bytes without other newlines.
-rwxr-xr-xLib/cgi.py9
-rw-r--r--Lib/test/test_cgi.py23
-rw-r--r--Misc/NEWS3
3 files changed, 35 insertions, 0 deletions
diff --git a/Lib/cgi.py b/Lib/cgi.py
index 67079db0d8..64ba6d16ca 100755
--- a/Lib/cgi.py
+++ b/Lib/cgi.py
@@ -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
diff --git a/Lib/test/test_cgi.py b/Lib/test/test_cgi.py
index f6abe976cf..7fdd482b94 100644
--- a/Lib/test/test_cgi.py
+++ b/Lib/test/test_cgi.py
@@ -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'],
diff --git a/Misc/NEWS b/Misc/NEWS
index efcd20a390..2bbcd7059f 100644
--- 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.