Kaydet (Commit) 6b102f25 authored tarafından Senthil Kumaran's avatar Senthil Kumaran

Issue #12411: Fix to cgi.parse_multipart to correctly use bytes boundaries and

bytes data. Patch by Jonas Wagner.
üst 3d9e9722
...@@ -214,17 +214,17 @@ def parse_multipart(fp, pdict): ...@@ -214,17 +214,17 @@ def parse_multipart(fp, pdict):
""" """
import http.client import http.client
boundary = "" boundary = b""
if 'boundary' in pdict: if 'boundary' in pdict:
boundary = pdict['boundary'] boundary = pdict['boundary']
if not valid_boundary(boundary): if not valid_boundary(boundary):
raise ValueError('Invalid boundary in multipart form: %r' raise ValueError('Invalid boundary in multipart form: %r'
% (boundary,)) % (boundary,))
nextpart = "--" + boundary nextpart = b"--" + boundary
lastpart = "--" + boundary + "--" lastpart = b"--" + boundary + b"--"
partdict = {} partdict = {}
terminator = "" terminator = b""
while terminator != lastpart: while terminator != lastpart:
bytes = -1 bytes = -1
...@@ -243,7 +243,7 @@ def parse_multipart(fp, pdict): ...@@ -243,7 +243,7 @@ def parse_multipart(fp, pdict):
raise ValueError('Maximum content length exceeded') raise ValueError('Maximum content length exceeded')
data = fp.read(bytes) data = fp.read(bytes)
else: else:
data = "" data = b""
# Read lines until end of part. # Read lines until end of part.
lines = [] lines = []
while 1: while 1:
...@@ -251,7 +251,7 @@ def parse_multipart(fp, pdict): ...@@ -251,7 +251,7 @@ def parse_multipart(fp, pdict):
if not line: if not line:
terminator = lastpart # End outer loop terminator = lastpart # End outer loop
break break
if line.startswith("--"): if line.startswith(b"--"):
terminator = line.rstrip() terminator = line.rstrip()
if terminator in (nextpart, lastpart): if terminator in (nextpart, lastpart):
break break
...@@ -263,12 +263,12 @@ def parse_multipart(fp, pdict): ...@@ -263,12 +263,12 @@ def parse_multipart(fp, pdict):
if lines: if lines:
# Strip final line terminator # Strip final line terminator
line = lines[-1] line = lines[-1]
if line[-2:] == "\r\n": if line[-2:] == b"\r\n":
line = line[:-2] line = line[:-2]
elif line[-1:] == "\n": elif line[-1:] == b"\n":
line = line[:-1] line = line[:-1]
lines[-1] = line lines[-1] = line
data = "".join(lines) data = b"".join(lines)
line = headers['content-disposition'] line = headers['content-disposition']
if not line: if not line:
continue continue
......
...@@ -4,6 +4,7 @@ import os ...@@ -4,6 +4,7 @@ import os
import sys import sys
import tempfile import tempfile
import unittest import unittest
from collections import namedtuple
from io import StringIO, BytesIO from io import StringIO, BytesIO
class HackedSysModule: class HackedSysModule:
...@@ -118,6 +119,23 @@ def gen_result(data, environ): ...@@ -118,6 +119,23 @@ def gen_result(data, environ):
class CgiTests(unittest.TestCase): class CgiTests(unittest.TestCase):
def test_parse_multipart(self):
fp = BytesIO(POSTDATA.encode('latin1'))
env = {'boundary': BOUNDARY.encode('latin1'),
'CONTENT-LENGTH': '558'}
result = cgi.parse_multipart(fp, env)
expected = {'submit': [b' Add '], 'id': [b'1234'],
'file': [b'Testing 123.\n'], 'title': [b'']}
self.assertEqual(result, expected)
def test_fieldstorage_properties(self):
fs = cgi.FieldStorage()
self.assertFalse(fs)
self.assertIn("FieldStorage", repr(fs))
self.assertEqual(list(fs), list(fs.keys()))
fs.list.append(namedtuple('MockFieldStorage', 'name')('fieldvalue'))
self.assertTrue(fs)
def test_escape(self): def test_escape(self):
self.assertEqual("test & string", cgi.escape("test & string")) self.assertEqual("test & string", cgi.escape("test & string"))
self.assertEqual("&lt;test string&gt;", cgi.escape("<test string>")) self.assertEqual("&lt;test string&gt;", cgi.escape("<test string>"))
...@@ -151,7 +169,8 @@ class CgiTests(unittest.TestCase): ...@@ -151,7 +169,8 @@ class CgiTests(unittest.TestCase):
def test_log(self): def test_log(self):
cgi.log("Testing") cgi.log("Testing")
cgi.logfile = "fail/"
cgi.initlog("%s", "Testing initlog")
cgi.logfp = StringIO() cgi.logfp = StringIO()
cgi.initlog("%s", "Testing initlog 1") cgi.initlog("%s", "Testing initlog 1")
cgi.log("%s", "Testing log 2") cgi.log("%s", "Testing log 2")
......
...@@ -202,6 +202,9 @@ Core and Builtins ...@@ -202,6 +202,9 @@ Core and Builtins
Library Library
------- -------
- Issue #12411: Fix to cgi.parse_multipart to correctly use bytes boundaries
and bytes data. Patch by Jonas Wagner.
- Issue #1159051: GzipFile now raises EOFError when reading a corrupted file - Issue #1159051: GzipFile now raises EOFError when reading a corrupted file
with truncated header or footer. with truncated header or footer.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment