diff options
author | Colin Watson <cjwatson@debian.org> | 2020-09-05 12:23:00 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2020-09-05 12:23:43 +0100 |
commit | 5ba7958fcbbfaa5313291fe09bd9b3967d388a8a (patch) | |
tree | deb7957b568552681f682cc7d9d470ab122d3fd0 | |
parent | c52ed1386b7d88d1dca5ce471bb8d23283c10837 (diff) | |
download | zope-publisher-5ba7958fcbbfaa5313291fe09bd9b3967d388a8a.tar.gz |
Fix handling of duplicate form-data field names
RFC 7578 section 5.2 says "Form parts with identical field names MUST
NOT be coalesced".
This was caught by the Launchpad test suite when testing an upgrade to
zope.publisher 6.0.0.
-rw-r--r-- | src/zope/publisher/browser.py | 4 | ||||
-rw-r--r-- | src/zope/publisher/tests/test_browserrequest.py | 21 |
2 files changed, 23 insertions, 2 deletions
diff --git a/src/zope/publisher/browser.py b/src/zope/publisher/browser.py index 28d8666..b8f38ac 100644 --- a/src/zope/publisher/browser.py +++ b/src/zope/publisher/browser.py @@ -321,8 +321,8 @@ class BrowserRequest(HTTPRequest): env['REQUEST_METHOD'] = 'POST' forms, files = multipart.parse_form_data( env, charset='ISO-8859-1', memfile_limit=0) - items.extend(six.iteritems(forms)) - for key, item in six.iteritems(files): + items.extend(forms.iterallitems()) + for key, item in files.iterallitems(): # multipart puts fields in 'files' even if no upload was # made. We only consider fields to be file uploads if a # filename was passed in and data was uploaded. diff --git a/src/zope/publisher/tests/test_browserrequest.py b/src/zope/publisher/tests/test_browserrequest.py index 1926bb3..dfcf7c6 100644 --- a/src/zope/publisher/tests/test_browserrequest.py +++ b/src/zope/publisher/tests/test_browserrequest.py @@ -601,6 +601,27 @@ class BrowserTests(HTTPTests): publish(request) self.assertEqual(request.form, {u"a": u"b +/=&b:int"}) + def testFormMultipartDuplicateFieldNames(self): + extra = { + 'REQUEST_METHOD': 'POST', + 'CONTENT_TYPE': 'multipart/form_data; boundary=-123', + } + body = b'\n'.join([ + b'---123', + b'Content-Disposition: form-data; name="a"', + b'', + b'first', + b'---123', + b'Content-Disposition: form-data; name="a"', + b'', + b'second', + b'---123--', + b'', + ]) + request = self._createRequest(extra, body) + request.processInputs() + self.assertEqual(['first', 'second'], request.form['a']) + def testInterface(self): request = self._createRequest() verifyObject(IBrowserRequest, request) |