Skip to content

Commit 74a146d

Browse files
committed
Merge python#18013: Fix cgi.FieldStorage to parse the W3C sample form.
2 parents 4603487 + 331c3fd commit 74a146d

File tree

3 files changed

+49
-1
lines changed

3 files changed

+49
-1
lines changed

Lib/cgi.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -699,7 +699,7 @@ def read_multi(self, environ, keep_blank_values, strict_parsing):
699699
self.encoding, self.errors)
700700
self.bytes_read += part.bytes_read
701701
self.list.append(part)
702-
if self.bytes_read >= self.length:
702+
if part.done or self.bytes_read >= self.length > 0:
703703
break
704704
self.skip_lines()
705705

Lib/test/test_cgi.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,27 @@ def check(content):
279279
check('x' * (maxline - 1) + '\r')
280280
check('x' * (maxline - 1) + '\r' + 'y' * (maxline - 1))
281281

282+
def test_fieldstorage_multipart_w3c(self):
283+
# Test basic FieldStorage multipart parsing (W3C sample)
284+
env = {
285+
'REQUEST_METHOD': 'POST',
286+
'CONTENT_TYPE': 'multipart/form-data; boundary={}'.format(BOUNDARY_W3),
287+
'CONTENT_LENGTH': str(len(POSTDATA_W3))}
288+
fp = BytesIO(POSTDATA_W3.encode('latin-1'))
289+
fs = cgi.FieldStorage(fp, environ=env, encoding="latin-1")
290+
self.assertEqual(len(fs.list), 2)
291+
self.assertEqual(fs.list[0].name, 'submit-name')
292+
self.assertEqual(fs.list[0].value, 'Larry')
293+
self.assertEqual(fs.list[1].name, 'files')
294+
files = fs.list[1].value
295+
self.assertEqual(len(files), 2)
296+
expect = [{'name': None, 'filename': 'file1.txt', 'value': b'... contents of file1.txt ...'},
297+
{'name': None, 'filename': 'file2.gif', 'value': b'...contents of file2.gif...'}]
298+
for x in range(len(files)):
299+
for k, exp in expect[x].items():
300+
got = getattr(files[x], k)
301+
self.assertEqual(got, exp)
302+
282303
_qs_result = {
283304
'key1': 'value1',
284305
'key2': ['value2x', 'value2y'],
@@ -428,6 +449,31 @@ def test_parse_header(self):
428449
-----------------------------721837373350705526688164684
429450
"""
430451

452+
# http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4
453+
BOUNDARY_W3 = "AaB03x"
454+
POSTDATA_W3 = """--AaB03x
455+
Content-Disposition: form-data; name="submit-name"
456+
457+
Larry
458+
--AaB03x
459+
Content-Disposition: form-data; name="files"
460+
Content-Type: multipart/mixed; boundary=BbC04y
461+
462+
--BbC04y
463+
Content-Disposition: file; filename="file1.txt"
464+
Content-Type: text/plain
465+
466+
... contents of file1.txt ...
467+
--BbC04y
468+
Content-Disposition: file; filename="file2.gif"
469+
Content-Type: image/gif
470+
Content-Transfer-Encoding: binary
471+
472+
...contents of file2.gif...
473+
--BbC04y--
474+
--AaB03x--
475+
"""
476+
431477

432478
def test_main():
433479
run_unittest(CgiTests)

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ Core and Builtins
142142
Library
143143
-------
144144

145+
- Issue #18013: Fix cgi.FieldStorage to parse the W3C sample form.
146+
145147
- Issue #18020: improve html.escape speed by an order of magnitude.
146148
Patch by Matt Bryant.
147149

0 commit comments

Comments
 (0)