Commit db63355c authored by Martin Aspeli's avatar Martin Aspeli

Fix processInputs() so that it no longer stomps on things like :records or :int:list

parent 3297779b
......@@ -11,6 +11,10 @@ http://docs.zope.org/zope2/releases/.
Bugs Fixed
++++++++++
- Five's processInputs() would stomp on :list or :tuple values that contained
ints or other non-strings, would clear out :records entirely, and would not
do anything for :record fields.
- LP #143261: The (very old-fashioned) Zope2.debug interactive request
debugger still referred to the toplevel module ``Zope``, which was
renamed to ``Zope2`` a long time ago.
......
......@@ -32,23 +32,40 @@ def _decode(text, charsets):
pass
return text
def processInputValue(value, charsets):
"""Recursively look for values (e.g. elements of lists, tuples or dicts)
and attempt to decode.
"""
if isinstance(value, list):
return [processInputValue(v, charsets) for v in value]
elif isinstance(value, tuple):
return tuple([processInputValue(v, charsets) for v in value])
elif isinstance(value, dict):
for k, v in value.items():
value[k] = processInputValue(v, charsets)
return value
elif isinstance(value, str):
return _decode(value, charsets)
else:
return value
def processInputs(request, charsets=None):
"""Process the values in request.form to decode strings to unicode, using
the passed-in list of charsets. If none are passed in, look up the user's
preferred charsets. The default is to use utf-8.
"""
if charsets is None:
envadapter = IUserPreferredCharsets(request)
charsets = envadapter.getPreferredCharsets() or ['utf-8']
envadapter = IUserPreferredCharsets(request, None)
if envadapter is None:
charsets = ['utf-8']
else:
charsets = envadapter.getPreferredCharsets() or ['utf-8']
for name, value in request.form.items():
if not (isCGI_NAME(name) or name.startswith('HTTP_')):
if isinstance(value, str):
request.form[name] = _decode(value, charsets)
elif isinstance(value, list):
request.form[name] = [ _decode(val, charsets)
for val in value
if isinstance(val, str) ]
elif isinstance(value, tuple):
request.form[name] = tuple([ _decode(val, charsets)
for val in value
if isinstance(val, str) ])
request.form[name] = processInputValue(value, charsets)
def setPageEncoding(request):
"""Set the encoding of the form page via the Content-Type header.
......
......@@ -46,6 +46,42 @@ def test_processInputs():
>>> processInputs(request, charsets)
>>> request.form['foo'] == (u'f\xf6\xf6',)
True
Ints in lists are not lost::
>>> request.form['foo'] = [1, 2, 3]
>>> processInputs(request, charsets)
>>> request.form['foo'] == [1, 2, 3]
True
Ints in tuples are not lost::
>>> request.form['foo'] = (1, 2, 3,)
>>> processInputs(request, charsets)
>>> request.form['foo'] == (1, 2, 3)
True
Mixed lists work:
>>> request.form['foo'] = [u'f\xf6\xf6'.encode('iso-8859-1'), 2, 3]
>>> processInputs(request, charsets)
>>> request.form['foo'] == [u'f\xf6\xf6', 2, 3]
True
Mixed dicts work:
>>> request.form['foo'] = {'foo': u'f\xf6\xf6'.encode('iso-8859-1'), 'bar': 2}
>>> processInputs(request, charsets)
>>> request.form['foo'] == {'foo': u'f\xf6\xf6', 'bar': 2}
True
Deep recursion works:
>>> request.form['foo'] = [{'foo': u'f\xf6\xf6'.encode('iso-8859-1'), 'bar': 2}, {'foo': u"one", 'bar': 3}]
>>> processInputs(request, charsets)
>>> request.form['foo'] == [{'foo': u'f\xf6\xf6', 'bar': 2}, {'foo': u"one", 'bar': 3}]
True
"""
def test_suite():
......
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