Commit 92047edf authored by 's avatar

- If `IBrowserPage` is provided by a view, form input is decoded.

parent f9cea257
......@@ -28,6 +28,9 @@ Bugs Fixed
Features Added
++++++++++++++
- ZPublisher: If `IBrowserPage` is provided by a view, form input is decoded.
This makes it easier to use ``zope.formlib`` and ``z3c.form`` in Zope 2.
- Report success or failure (when known) of creating a new user with
the addzope2user script.
......
......@@ -40,7 +40,6 @@ from AccessControl.tainted import TaintedString
from ZPublisher.BaseRequest import BaseRequest
from ZPublisher.BaseRequest import quote
from ZPublisher.Converters import get_converter
from ZPublisher.HTTPResponse import HTTPResponse
from ZPublisher.maybe_lock import allocate_lock
# Flags
......@@ -1150,6 +1149,12 @@ class HTTPRequest(BaseRequest):
other['PATH_INFO'] = path = "%s/%s" % (path,meth)
self._hacked_path = 1
def postProcessInputs(self):
"""Process the values in request.form to decode strings to unicode.
"""
for name, value in self.form.iteritems():
self.form[name] = _decode(value, default_encoding)
def resolve_url(self, url):
# Attempt to resolve a url into an object in the Zope
# namespace. The url must be a fully-qualified url. The
......@@ -1754,3 +1759,16 @@ def _filterPasswordFields(items):
result.append((k, v))
return result
def _decode(value, charset):
"""Recursively look for string values and decode.
"""
if isinstance(value, list):
return [_decode(v, charset) for v in value]
elif isinstance(value, tuple):
return tuple(_decode(v, charset) for v in value)
elif isinstance(value, dict):
return dict((k, _decode(v, charset)) for k, v in value.iteritems())
elif isinstance(value, str):
return unicode(value, charset, 'replace')
return value
......@@ -15,18 +15,25 @@
import sys, os
import transaction
from Response import Response
from Request import Request
from maybe_lock import allocate_lock
from mapply import mapply
from zExceptions import Redirect
from zope.event import notify
from zope.publisher.interfaces import ISkinnable
from zope.publisher.interfaces.browser import IBrowserPage
from zope.publisher.skinnable import setDefaultSkin
from zope.security.management import newInteraction, endInteraction
from zope.event import notify
from pubevents import PubStart, PubSuccess, PubFailure, \
PubBeforeCommit, PubAfterTraversal, PubBeforeAbort
from .mapply import mapply
from .maybe_lock import allocate_lock
from .pubevents import PubAfterTraversal
from .pubevents import PubBeforeAbort
from .pubevents import PubBeforeCommit
from .pubevents import PubFailure
from .pubevents import PubStart
from .pubevents import PubSuccess
from .Request import Request
from .Response import Response
class Retry(Exception):
"""Raise this to retry a request
......@@ -114,6 +121,9 @@ def publish(request, module_name, after_list, debug=0,
object=request.traverse(path, validated_hook=validated_hook)
if IBrowserPage.providedBy(object):
request.postProcessInputs()
notify(PubAfterTraversal(request))
if transactions_manager:
......
import unittest
from zope.testing.cleanup import cleanUp
class RecordTests(unittest.TestCase):
def test_repr(self):
......@@ -11,8 +14,12 @@ class RecordTests(unittest.TestCase):
d = eval(r)
self.assertEqual(d, rec.__dict__)
class HTTPRequestTests(unittest.TestCase):
def tearDown(self):
cleanUp()
def _getTargetClass(self):
from ZPublisher.HTTPRequest import HTTPRequest
return HTTPRequest
......@@ -634,7 +641,33 @@ class HTTPRequestTests(unittest.TestCase):
self.assertEquals(req.cookies['multi2'],
'cookie data with unquoted spaces')
def test_postProcessInputs(self):
from ZPublisher.HTTPRequest import default_encoding
_NON_ASCII = u'\xc4\xd6\xdc'
req = self._makeOne()
req.form = {'foo': _NON_ASCII.encode(default_encoding),
'foo_list': [_NON_ASCII.encode(default_encoding), 'SPAM'],
'foo_tuple': (_NON_ASCII.encode(default_encoding), 'HAM'),
'foo_dict': {'foo': _NON_ASCII, 'bar': 'EGGS'}}
req.postProcessInputs()
self.assertTrue(isinstance(req.form['foo'], unicode))
self.assertEqual(req.form['foo'], _NON_ASCII)
self.assertTrue(isinstance(req.form['foo_list'], list))
self.assertTrue(isinstance(req.form['foo_list'][0], unicode))
self.assertEqual(req.form['foo_list'][0], _NON_ASCII)
self.assertTrue(isinstance(req.form['foo_list'][1], unicode))
self.assertEqual(req.form['foo_list'][1], u'SPAM')
self.assertTrue(isinstance(req.form['foo_tuple'], tuple))
self.assertTrue(isinstance(req.form['foo_tuple'][0], unicode))
self.assertEqual(req.form['foo_tuple'][0], _NON_ASCII)
self.assertTrue(isinstance(req.form['foo_tuple'][1], unicode))
self.assertEqual(req.form['foo_tuple'][1], u'HAM')
self.assertTrue(isinstance(req.form['foo_dict'], dict))
self.assertTrue(isinstance(req.form['foo_dict']['foo'], unicode))
self.assertEqual(req.form['foo_dict']['foo'], _NON_ASCII)
self.assertTrue(isinstance(req.form['foo_dict']['bar'], unicode))
self.assertEqual(req.form['foo_dict']['bar'], u'EGGS')
def test_close_removes_stdin_references(self):
# Verifies that all references to the input stream go away on
......
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