[Zope-Checkins] SVN: Zope/trunk/src/Products/Five/browser/ Merge c112780 from 2.12 branch

2010-05-27 Thread Martin Aspeli
Log message for revision 112781:
  Merge c112780 from 2.12 branch

Changed:
  U   Zope/trunk/src/Products/Five/browser/decode.py
  U   Zope/trunk/src/Products/Five/browser/tests/test_decode.py

-=-
Modified: Zope/trunk/src/Products/Five/browser/decode.py
===
--- Zope/trunk/src/Products/Five/browser/decode.py  2010-05-27 13:27:15 UTC 
(rev 112780)
+++ Zope/trunk/src/Products/Five/browser/decode.py  2010-05-27 13:30:02 UTC 
(rev 112781)
@@ -32,23 +32,40 @@
 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.

Modified: Zope/trunk/src/Products/Five/browser/tests/test_decode.py
===
--- Zope/trunk/src/Products/Five/browser/tests/test_decode.py   2010-05-27 
13:27:15 UTC (rev 112780)
+++ Zope/trunk/src/Products/Five/browser/tests/test_decode.py   2010-05-27 
13:30:02 UTC (rev 112781)
@@ -46,6 +46,42 @@
   >>> 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():

___
Zope-Checkins maillist  -  Zope-Checkins@zope.org
https://mail.zope.org/mailman/listinfo/zope-checkins


[Zope-Checkins] SVN: Zope/branches/2.12/ Fix processInputs() so that it no longer stomps on things like :records or :int:list

2010-05-27 Thread Martin Aspeli
Log message for revision 112780:
  Fix processInputs() so that it no longer stomps on things like :records or 
:int:list

Changed:
  U   Zope/branches/2.12/doc/CHANGES.rst
  U   Zope/branches/2.12/src/Products/Five/browser/decode.py
  U   Zope/branches/2.12/src/Products/Five/browser/tests/test_decode.py

-=-
Modified: Zope/branches/2.12/doc/CHANGES.rst
===
--- Zope/branches/2.12/doc/CHANGES.rst  2010-05-27 12:12:28 UTC (rev 112779)
+++ Zope/branches/2.12/doc/CHANGES.rst  2010-05-27 13:27:15 UTC (rev 112780)
@@ -11,6 +11,10 @@
 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.

Modified: Zope/branches/2.12/src/Products/Five/browser/decode.py
===
--- Zope/branches/2.12/src/Products/Five/browser/decode.py  2010-05-27 
12:12:28 UTC (rev 112779)
+++ Zope/branches/2.12/src/Products/Five/browser/decode.py  2010-05-27 
13:27:15 UTC (rev 112780)
@@ -32,23 +32,40 @@
 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.

Modified: Zope/branches/2.12/src/Products/Five/browser/tests/test_decode.py
===
--- Zope/branches/2.12/src/Products/Five/browser/tests/test_decode.py   
2010-05-27 12:12:28 UTC (rev 112779)
+++ Zope/branches/2.12/src/Products/Five/browser/tests/test_decode.py   
2010-05-27 13:27:15 UTC (rev 112780)
@@ -46,6 +46,42 @@
   >>> 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}