aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/test/test_cgi.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test/test_cgi.py')
-rw-r--r--Lib/test/test_cgi.py194
1 files changed, 98 insertions, 96 deletions
diff --git a/Lib/test/test_cgi.py b/Lib/test/test_cgi.py
index f6abe976cf7..3031fb38262 100644
--- a/Lib/test/test_cgi.py
+++ b/Lib/test/test_cgi.py
@@ -1,9 +1,10 @@
-from test.test_support import run_unittest, check_warnings
+from test.support import run_unittest, check_warnings
import cgi
import os
import sys
import tempfile
import unittest
+from io import StringIO, BytesIO
class HackedSysModule:
# The regression test will have real values in sys.argv, which
@@ -13,11 +14,6 @@ class HackedSysModule:
cgi.sys = HackedSysModule()
-try:
- from cStringIO import StringIO
-except ImportError:
- from StringIO import StringIO
-
class ComparableException:
def __init__(self, err):
self.err = err
@@ -25,13 +21,11 @@ class ComparableException:
def __str__(self):
return str(self.err)
- def __cmp__(self, anExc):
+ def __eq__(self, anExc):
if not isinstance(anExc, Exception):
- return -1
- x = cmp(self.err.__class__, anExc.__class__)
- if x != 0:
- return x
- return cmp(self.err.args, anExc.args)
+ return NotImplemented
+ return (self.err.__class__ == anExc.__class__ and
+ self.err.args == anExc.args)
def __getattr__(self, attr):
return getattr(self.err, attr)
@@ -43,15 +37,15 @@ def do_test(buf, method):
env['REQUEST_METHOD'] = 'GET'
env['QUERY_STRING'] = buf
elif method == "POST":
- fp = StringIO(buf)
+ fp = BytesIO(buf.encode('latin-1')) # FieldStorage expects bytes
env['REQUEST_METHOD'] = 'POST'
env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'
env['CONTENT_LENGTH'] = str(len(buf))
else:
- raise ValueError, "unknown method: %s" % method
+ raise ValueError("unknown method: %s" % method)
try:
return cgi.parse(fp, env, strict_parsing=1)
- except StandardError, err:
+ except Exception as err:
return ComparableException(err)
parse_strict_test_cases = [
@@ -101,16 +95,20 @@ parse_strict_test_cases = [
})
]
+def norm(seq):
+ return sorted(seq, key=repr)
+
def first_elts(list):
- return map(lambda x:x[0], list)
+ return [p[0] for p in list]
def first_second_elts(list):
- return map(lambda p:(p[0], p[1][0]), list)
+ return [(p[0], p[1][0]) for p in list]
def gen_result(data, environ):
- fake_stdin = StringIO(data)
+ encoding = 'latin-1'
+ fake_stdin = BytesIO(data.encode(encoding))
fake_stdin.seek(0)
- form = cgi.FieldStorage(fp=fake_stdin, environ=environ)
+ form = cgi.FieldStorage(fp=fake_stdin, environ=environ, encoding=encoding)
result = {}
for k, v in dict(form).items():
@@ -129,61 +127,27 @@ class CgiTests(unittest.TestCase):
for orig, expect in parse_strict_test_cases:
# Test basic parsing
d = do_test(orig, "GET")
- self.assertEqual(d, expect, "Error parsing %s" % repr(orig))
+ self.assertEqual(d, expect, "Error parsing %s method GET" % repr(orig))
d = do_test(orig, "POST")
- self.assertEqual(d, expect, "Error parsing %s" % repr(orig))
+ self.assertEqual(d, expect, "Error parsing %s method POST" % repr(orig))
env = {'QUERY_STRING': orig}
- fcd = cgi.FormContentDict(env)
- sd = cgi.SvFormContentDict(env)
fs = cgi.FieldStorage(environ=env)
if isinstance(expect, dict):
# test dict interface
- self.assertEqual(len(expect), len(fcd))
- self.assertItemsEqual(expect.keys(), fcd.keys())
- self.assertItemsEqual(expect.values(), fcd.values())
- self.assertItemsEqual(expect.items(), fcd.items())
- self.assertEqual(fcd.get("nonexistent field", "default"), "default")
- self.assertEqual(len(sd), len(fs))
- self.assertItemsEqual(sd.keys(), fs.keys())
+ self.assertEqual(len(expect), len(fs))
+ self.assertCountEqual(expect.keys(), fs.keys())
+ ##self.assertEqual(norm(expect.values()), norm(fs.values()))
+ ##self.assertEqual(norm(expect.items()), norm(fs.items()))
self.assertEqual(fs.getvalue("nonexistent field", "default"), "default")
# test individual fields
for key in expect.keys():
expect_val = expect[key]
- self.assertTrue(fcd.has_key(key))
- self.assertItemsEqual(fcd[key], expect[key])
- self.assertEqual(fcd.get(key, "default"), fcd[key])
- self.assertTrue(fs.has_key(key))
+ self.assertIn(key, fs)
if len(expect_val) > 1:
- single_value = 0
- else:
- single_value = 1
- try:
- val = sd[key]
- except IndexError:
- self.assertFalse(single_value)
self.assertEqual(fs.getvalue(key), expect_val)
else:
- self.assertTrue(single_value)
- self.assertEqual(val, expect_val[0])
self.assertEqual(fs.getvalue(key), expect_val[0])
- self.assertItemsEqual(sd.getlist(key), expect_val)
- if single_value:
- self.assertItemsEqual(sd.values(),
- first_elts(expect.values()))
- self.assertItemsEqual(sd.items(),
- first_second_elts(expect.items()))
-
- def test_weird_formcontentdict(self):
- # Test the weird FormContentDict classes
- env = {'QUERY_STRING': "x=1&y=2.0&z=2-3.%2b0&1=1abc"}
- expect = {'x': 1, 'y': 2.0, 'z': '2-3.+0', '1': '1abc'}
- d = cgi.InterpFormContentDict(env)
- for k, v in expect.items():
- self.assertEqual(d[k], v)
- for k, v in d.items():
- self.assertEqual(expect[k], v)
- self.assertItemsEqual(expect.values(), d.values())
def test_log(self):
cgi.log("Testing")
@@ -196,6 +160,13 @@ class CgiTests(unittest.TestCase):
cgi.logfp = None
cgi.logfile = "/dev/null"
cgi.initlog("%s", "Testing log 3")
+ def log_cleanup():
+ """Restore the global state of the log vars."""
+ cgi.logfile = ''
+ cgi.logfp.close()
+ cgi.logfp = None
+ cgi.log = cgi.initlog
+ self.addCleanup(log_cleanup)
cgi.log("Testing log 4")
def test_fieldstorage_readline(self):
@@ -222,50 +193,52 @@ class CgiTests(unittest.TestCase):
setattr(self, name, a)
return a
- f = TestReadlineFile(tempfile.TemporaryFile())
- f.write('x' * 256 * 1024)
+ f = TestReadlineFile(tempfile.TemporaryFile("wb+"))
+ self.addCleanup(f.close)
+ f.write(b'x' * 256 * 1024)
f.seek(0)
env = {'REQUEST_METHOD':'PUT'}
fs = cgi.FieldStorage(fp=f, environ=env)
+ self.addCleanup(fs.file.close)
# if we're not chunking properly, readline is only called twice
# (by read_binary); if we are chunking properly, it will be called 5 times
# as long as the chunksize is 1 << 16.
self.assertTrue(f.numcalls > 2)
+ f.close()
def test_fieldstorage_multipart(self):
#Test basic FieldStorage multipart parsing
- env = {'REQUEST_METHOD':'POST', 'CONTENT_TYPE':'multipart/form-data; boundary=---------------------------721837373350705526688164684', 'CONTENT_LENGTH':'558'}
- postdata = """-----------------------------721837373350705526688164684
-Content-Disposition: form-data; name="id"
-
-1234
------------------------------721837373350705526688164684
-Content-Disposition: form-data; name="title"
-
-
------------------------------721837373350705526688164684
-Content-Disposition: form-data; name="file"; filename="test.txt"
-Content-Type: text/plain
-
-Testing 123.
-
------------------------------721837373350705526688164684
-Content-Disposition: form-data; name="submit"
-
- Add\x20
------------------------------721837373350705526688164684--
-"""
- fs = cgi.FieldStorage(fp=StringIO(postdata), environ=env)
+ env = {
+ 'REQUEST_METHOD': 'POST',
+ 'CONTENT_TYPE': 'multipart/form-data; boundary={}'.format(BOUNDARY),
+ 'CONTENT_LENGTH': '558'}
+ fp = BytesIO(POSTDATA.encode('latin-1'))
+ fs = cgi.FieldStorage(fp, environ=env, encoding="latin-1")
self.assertEqual(len(fs.list), 4)
expect = [{'name':'id', 'filename':None, 'value':'1234'},
{'name':'title', 'filename':None, 'value':''},
- {'name':'file', 'filename':'test.txt','value':'Testing 123.\n'},
+ {'name':'file', 'filename':'test.txt', 'value':b'Testing 123.\n'},
{'name':'submit', 'filename':None, 'value':' Add '}]
for x in range(len(fs.list)):
for k, exp in expect[x].items():
got = getattr(fs.list[x], k)
self.assertEqual(got, exp)
+ def test_fieldstorage_multipart_non_ascii(self):
+ #Test basic FieldStorage multipart parsing
+ env = {'REQUEST_METHOD':'POST',
+ 'CONTENT_TYPE': 'multipart/form-data; boundary={}'.format(BOUNDARY),
+ 'CONTENT_LENGTH':'558'}
+ for encoding in ['iso-8859-1','utf-8']:
+ fp = BytesIO(POSTDATA_NON_ASCII.encode(encoding))
+ fs = cgi.FieldStorage(fp, environ=env,encoding=encoding)
+ self.assertEqual(len(fs.list), 1)
+ expect = [{'name':'id', 'filename':None, 'value':'\xe7\xf1\x80'}]
+ for x in range(len(fs.list)):
+ for k, exp in expect[x].items():
+ got = getattr(fs.list[x], k)
+ self.assertEqual(got, exp)
+
_qs_result = {
'key1': 'value1',
'key2': ['value2x', 'value2y'],
@@ -284,8 +257,7 @@ Content-Disposition: form-data; name="submit"
self.assertEqual(self._qs_result, v)
def testQSAndFormData(self):
- data = """
----123
+ data = """---123
Content-Disposition: form-data; name="key2"
value2y
@@ -309,8 +281,7 @@ value4
self.assertEqual(self._qs_result, v)
def testQSAndFormDataFile(self):
- data = """
----123
+ data = """---123
Content-Disposition: form-data; name="key2"
value2y
@@ -338,22 +309,22 @@ this is the content of the fake file
}
result = self._qs_result.copy()
result.update({
- 'upload': 'this is the content of the fake file\n'
+ 'upload': b'this is the content of the fake file\n'
})
v = gen_result(data, environ)
self.assertEqual(result, v)
def test_deprecated_parse_qs(self):
- # this func is moved to urlparse, this is just a sanity check
- with check_warnings(('cgi.parse_qs is deprecated, use urlparse.'
- 'parse_qs instead', PendingDeprecationWarning)):
+ # this func is moved to urllib.parse, this is just a sanity check
+ with check_warnings(('cgi.parse_qs is deprecated, use urllib.parse.'
+ 'parse_qs instead', DeprecationWarning)):
self.assertEqual({'a': ['A1'], 'B': ['B3'], 'b': ['B2']},
cgi.parse_qs('a=A1&b=B2&B=B3'))
def test_deprecated_parse_qsl(self):
- # this func is moved to urlparse, this is just a sanity check
- with check_warnings(('cgi.parse_qsl is deprecated, use urlparse.'
- 'parse_qsl instead', PendingDeprecationWarning)):
+ # this func is moved to urllib.parse, this is just a sanity check
+ with check_warnings(('cgi.parse_qsl is deprecated, use urllib.parse.'
+ 'parse_qsl instead', DeprecationWarning)):
self.assertEqual([('a', 'A1'), ('b', 'B2'), ('B', 'B3')],
cgi.parse_qsl('a=A1&b=B2&B=B3'))
@@ -387,6 +358,37 @@ this is the content of the fake file
("form-data", {"name": "files", "filename": 'fo"o;bar'}))
+BOUNDARY = "---------------------------721837373350705526688164684"
+
+POSTDATA = """-----------------------------721837373350705526688164684
+Content-Disposition: form-data; name="id"
+
+1234
+-----------------------------721837373350705526688164684
+Content-Disposition: form-data; name="title"
+
+
+-----------------------------721837373350705526688164684
+Content-Disposition: form-data; name="file"; filename="test.txt"
+Content-Type: text/plain
+
+Testing 123.
+
+-----------------------------721837373350705526688164684
+Content-Disposition: form-data; name="submit"
+
+ Add\x20
+-----------------------------721837373350705526688164684--
+"""
+
+POSTDATA_NON_ASCII = """-----------------------------721837373350705526688164684
+Content-Disposition: form-data; name="id"
+
+\xe7\xf1\x80
+-----------------------------721837373350705526688164684
+"""
+
+
def test_main():
run_unittest(CgiTests)