Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6b102f2

Browse files
committed
Issue #12411: Fix to cgi.parse_multipart to correctly use bytes boundaries and
bytes data. Patch by Jonas Wagner.
1 parent 3d9e972 commit 6b102f2

3 files changed

Lines changed: 32 additions & 10 deletions

File tree

Lib/cgi.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -214,17 +214,17 @@ def parse_multipart(fp, pdict):
214214
"""
215215
import http.client
216216

217-
boundary = ""
217+
boundary = b""
218218
if 'boundary' in pdict:
219219
boundary = pdict['boundary']
220220
if not valid_boundary(boundary):
221221
raise ValueError('Invalid boundary in multipart form: %r'
222222
% (boundary,))
223223

224-
nextpart = "--" + boundary
225-
lastpart = "--" + boundary + "--"
224+
nextpart = b"--" + boundary
225+
lastpart = b"--" + boundary + b"--"
226226
partdict = {}
227-
terminator = ""
227+
terminator = b""
228228

229229
while terminator != lastpart:
230230
bytes = -1
@@ -243,15 +243,15 @@ def parse_multipart(fp, pdict):
243243
raise ValueError('Maximum content length exceeded')
244244
data = fp.read(bytes)
245245
else:
246-
data = ""
246+
data = b""
247247
# Read lines until end of part.
248248
lines = []
249249
while 1:
250250
line = fp.readline()
251251
if not line:
252252
terminator = lastpart # End outer loop
253253
break
254-
if line.startswith("--"):
254+
if line.startswith(b"--"):
255255
terminator = line.rstrip()
256256
if terminator in (nextpart, lastpart):
257257
break
@@ -263,12 +263,12 @@ def parse_multipart(fp, pdict):
263263
if lines:
264264
# Strip final line terminator
265265
line = lines[-1]
266-
if line[-2:] == "\r\n":
266+
if line[-2:] == b"\r\n":
267267
line = line[:-2]
268-
elif line[-1:] == "\n":
268+
elif line[-1:] == b"\n":
269269
line = line[:-1]
270270
lines[-1] = line
271-
data = "".join(lines)
271+
data = b"".join(lines)
272272
line = headers['content-disposition']
273273
if not line:
274274
continue

Lib/test/test_cgi.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import sys
55
import tempfile
66
import unittest
7+
from collections import namedtuple
78
from io import StringIO, BytesIO
89

910
class HackedSysModule:
@@ -118,6 +119,23 @@ def gen_result(data, environ):
118119

119120
class CgiTests(unittest.TestCase):
120121

122+
def test_parse_multipart(self):
123+
fp = BytesIO(POSTDATA.encode('latin1'))
124+
env = {'boundary': BOUNDARY.encode('latin1'),
125+
'CONTENT-LENGTH': '558'}
126+
result = cgi.parse_multipart(fp, env)
127+
expected = {'submit': [b' Add '], 'id': [b'1234'],
128+
'file': [b'Testing 123.\n'], 'title': [b'']}
129+
self.assertEqual(result, expected)
130+
131+
def test_fieldstorage_properties(self):
132+
fs = cgi.FieldStorage()
133+
self.assertFalse(fs)
134+
self.assertIn("FieldStorage", repr(fs))
135+
self.assertEqual(list(fs), list(fs.keys()))
136+
fs.list.append(namedtuple('MockFieldStorage', 'name')('fieldvalue'))
137+
self.assertTrue(fs)
138+
121139
def test_escape(self):
122140
self.assertEqual("test & string", cgi.escape("test & string"))
123141
self.assertEqual("&lt;test string&gt;", cgi.escape("<test string>"))
@@ -151,7 +169,8 @@ def test_strict(self):
151169

152170
def test_log(self):
153171
cgi.log("Testing")
154-
172+
cgi.logfile = "fail/"
173+
cgi.initlog("%s", "Testing initlog")
155174
cgi.logfp = StringIO()
156175
cgi.initlog("%s", "Testing initlog 1")
157176
cgi.log("%s", "Testing log 2")

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,9 @@ Core and Builtins
202202
Library
203203
-------
204204

205+
- Issue #12411: Fix to cgi.parse_multipart to correctly use bytes boundaries
206+
and bytes data. Patch by Jonas Wagner.
207+
205208
- Issue #1159051: GzipFile now raises EOFError when reading a corrupted file
206209
with truncated header or footer.
207210

0 commit comments

Comments
 (0)