Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions Lib/test/test_wsgiref.py
Original file line number Diff line number Diff line change
Expand Up @@ -510,15 +510,28 @@ def testRaisesControlCharacters(self):
headers = Headers()
self.assertRaises(ValueError, headers.__setitem__, f"key{c0}", "val")
self.assertRaises(ValueError, headers.add_header, f"key{c0}", "val", param="param")
self.assertRaises(ValueError, Headers, [(f"key{c0}", "val")])
# HTAB (\x09) is allowed in values, not names.
if c0 == "\t":
headers["key"] = f"val{c0}"
headers.add_header("key", f"val{c0}")
headers.setdefault(f"key", f"val{c0}")
Headers([("key", f"val{c0}")])
else:
self.assertRaises(ValueError, headers.__setitem__, "key", f"val{c0}")
self.assertRaises(ValueError, headers.add_header, "key", f"val{c0}", param="param")
self.assertRaises(ValueError, headers.add_header, "key", "val", param=f"param{c0}")
self.assertRaises(ValueError, Headers, [("key", f"val{c0}")])

def testConstructorValidatesWithoutDebug(self):
# The constructor must reject control characters even under -O, where
# __debug__-guarded code is skipped; the headers it is given are stored
# and written to the response unchanged.
from test.support.script_helper import assert_python_failure
code = ("from wsgiref.headers import Headers\n"
"Headers([('Foo', 'bar\\r\\nSet-Cookie: evil')])\n")
rc, out, err = assert_python_failure('-O', '-c', code)
self.assertIn(b'ValueError', err)

class ErrorHandler(BaseCGIHandler):
"""Simple handler subclass for testing BaseHandler"""
Expand Down
7 changes: 3 additions & 4 deletions Lib/wsgiref/headers.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,9 @@ def __init__(self, headers=None):
if type(headers) is not list:
raise TypeError("Headers must be a list of name/value tuples")
self._headers = headers
if __debug__:
for k, v in headers:
self._convert_string_type(k, name=True)
self._convert_string_type(v, name=False)
for k, v in headers:
self._convert_string_type(k, name=True)
self._convert_string_type(v, name=False)

def _convert_string_type(self, value, *, name):
"""Convert/check value type."""
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
:class:`wsgiref.headers.Headers` now rejects control characters in header
names and values passed to its constructor even when Python is run with
:option:`-O`, where the check was previously skipped.
Loading