diff options
author | Amber Brown <hawkowl@atleastfornow.net> | 2018-05-14 22:11:55 (GMT) |
---|---|---|
committer | Ned Deily <nad@python.org> | 2018-05-14 22:11:55 (GMT) |
commit | 545c955be997efd6b3827b981024e6b9945d82d1 (patch) | |
tree | 7e66dc411f94029250b67465c474dfde19695cde | |
parent | 3059042410dce69806b94be72d5c8055d616f3a3 (diff) | |
download | cpython-545c955be997efd6b3827b981024e6b9945d82d1.zip cpython-545c955be997efd6b3827b981024e6b9945d82d1.tar.gz cpython-545c955be997efd6b3827b981024e6b9945d82d1.tar.bz2 |
bpo-33497: Add errors param to cgi.parse_multipart and make an encoding in FieldStorage use the given errors (GH-6804)
-rw-r--r-- | Doc/library/cgi.rst | 6 | ||||
-rwxr-xr-x | Lib/cgi.py | 10 | ||||
-rw-r--r-- | Lib/test/test_cgi.py | 18 |
3 files changed, 27 insertions, 7 deletions
diff --git a/Doc/library/cgi.rst b/Doc/library/cgi.rst index 17386b8..0b1aead 100644 --- a/Doc/library/cgi.rst +++ b/Doc/library/cgi.rst @@ -296,7 +296,7 @@ algorithms implemented in this module in other circumstances. instead. It is maintained here only for backward compatibility. -.. function:: parse_multipart(fp, pdict, encoding="utf-8") +.. function:: parse_multipart(fp, pdict, encoding="utf-8", errors="replace") Parse input of type :mimetype:`multipart/form-data` (for file uploads). Arguments are *fp* for the input file, *pdict* for a dictionary containing @@ -312,8 +312,8 @@ algorithms implemented in this module in other circumstances. which is much more flexible. .. versionchanged:: 3.7 - Added the *encoding* parameter. For non-file fields, the value is now - a list of strings, not bytes. + Added the *encoding* and *errors* parameters. For non-file fields, the + value is now a list of strings, not bytes. .. function:: parse_header(string) @@ -198,13 +198,14 @@ def parse_qsl(qs, keep_blank_values=0, strict_parsing=0): DeprecationWarning, 2) return urllib.parse.parse_qsl(qs, keep_blank_values, strict_parsing) -def parse_multipart(fp, pdict, encoding="utf-8"): +def parse_multipart(fp, pdict, encoding="utf-8", errors="replace"): """Parse multipart input. Arguments: fp : input file pdict: dictionary containing other parameters of content-type header - encoding: request encoding + encoding, errors: request encoding and error handler, passed to + FieldStorage Returns a dictionary just like parse_qs(): keys are the field names, each value is a list of values for that field. For non-file fields, the value @@ -217,7 +218,7 @@ def parse_multipart(fp, pdict, encoding="utf-8"): headers = Message() headers.set_type(ctype) headers['Content-Length'] = pdict['CONTENT-LENGTH'] - fs = FieldStorage(fp, headers=headers, encoding=encoding, + fs = FieldStorage(fp, headers=headers, encoding=encoding, errors=errors, environ={'REQUEST_METHOD': 'POST'}) return {k: fs.getlist(k) for k in fs} @@ -458,7 +459,8 @@ class FieldStorage: self.type = ctype self.type_options = pdict if 'boundary' in pdict: - self.innerboundary = pdict['boundary'].encode(self.encoding) + self.innerboundary = pdict['boundary'].encode(self.encoding, + self.errors) else: self.innerboundary = b"" diff --git a/Lib/test/test_cgi.py b/Lib/test/test_cgi.py index 903d073..4f2bba1 100644 --- a/Lib/test/test_cgi.py +++ b/Lib/test/test_cgi.py @@ -130,6 +130,24 @@ class CgiTests(unittest.TestCase): 'file': [b'Testing 123.\n'], 'title': ['']} self.assertEqual(result, expected) + def test_parse_multipart_invalid_encoding(self): + BOUNDARY = "JfISa01" + POSTDATA = """--JfISa01 +Content-Disposition: form-data; name="submit-name" +Content-Length: 3 + +\u2603 +--JfISa01""" + fp = BytesIO(POSTDATA.encode('utf8')) + env = {'boundary': BOUNDARY.encode('latin1'), + 'CONTENT-LENGTH': str(len(POSTDATA.encode('utf8')))} + result = cgi.parse_multipart(fp, env, encoding="ascii", + errors="surrogateescape") + expected = {'submit-name': ["\udce2\udc98\udc83"]} + self.assertEqual(result, expected) + self.assertEqual("\u2603".encode('utf8'), + result["submit-name"][0].encode('utf8', 'surrogateescape')) + def test_fieldstorage_properties(self): fs = cgi.FieldStorage() self.assertFalse(fs) |