diff options
| author | Chris McDonough <chrism@plope.com> | 2012-01-05 06:32:38 -0500 |
|---|---|---|
| committer | Chris McDonough <chrism@plope.com> | 2012-01-05 06:32:38 -0500 |
| commit | 92dcb5f1a52d46fec7c043a1b5b4158f3d013c34 (patch) | |
| tree | 72ff58e0f8559d3f71845b1b1cc52fd70157f593 | |
| parent | ad9807016fd28b7da424174fdb6ed9b93641f58f (diff) | |
| download | pyramid-92dcb5f1a52d46fec7c043a1b5b4158f3d013c34.tar.gz pyramid-92dcb5f1a52d46fec7c043a1b5b4158f3d013c34.tar.bz2 pyramid-92dcb5f1a52d46fec7c043a1b5b4158f3d013c34.zip | |
- Using a dynamic segment named ``traverse`` in a route pattern like this::
config.add_route('trav_route', 'traversal/{traverse:.*}')
Would cause a ``UnicodeDecodeError`` when the route was matched and the
matched portion of the URL contained any high-order characters. See also
https://github.com/Pylons/pyramid/issues/385 .
| -rw-r--r-- | CHANGES.txt | 8 | ||||
| -rw-r--r-- | pyramid/tests/test_traversal.py | 60 | ||||
| -rw-r--r-- | pyramid/traversal.py | 6 |
3 files changed, 67 insertions, 7 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index 93be3eab3..6116da229 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -45,6 +45,14 @@ Bug Fixes URLDecodeError if there were any high-order characters in the traversal pattern or in the matched dynamic segments. +- Using a dynamic segment named ``traverse`` in a route pattern like this:: + + config.add_route('trav_route', 'traversal/{traverse:.*}') + + Would cause a ``UnicodeDecodeError`` when the route was matched and the + matched portion of the URL contained any high-order characters. See also + https://github.com/Pylons/pyramid/issues/385 . + Backwards Incompatibilities --------------------------- diff --git a/pyramid/tests/test_traversal.py b/pyramid/tests/test_traversal.py index 72192b23b..683679253 100644 --- a/pyramid/tests/test_traversal.py +++ b/pyramid/tests/test_traversal.py @@ -1,10 +1,13 @@ import unittest from pyramid.testing import cleanUp -from pyramid.compat import text_ -from pyramid.compat import native_ -from pyramid.compat import text_type -from pyramid.compat import url_quote +from pyramid.compat import ( + text_, + native_, + text_type, + url_quote, + PY3, + ) class TraversalPathTests(unittest.TestCase): def _callFUT(self, path): @@ -131,6 +134,28 @@ class ResourceTreeTraverserTests(unittest.TestCase): self.assertEqual(result['virtual_root'], policy.root) self.assertEqual(result['virtual_root_path'], ()) + def test_call_with_pathinfo_highorder(self): + foo = DummyContext(None, text_(b'Qu\xc3\xa9bec', 'utf-8')) + root = DummyContext(foo, 'root') + policy = self._makeOne(root) + if PY3: + path_info = b'/Qu\xc3\xa9bec'.encode('latin-1') + else: + path_info = b'/Qu\xc3\xa9bec' + environ = self._getEnviron(PATH_INFO=path_info) + request = DummyRequest(environ) + result = policy(request) + self.assertEqual(result['context'], foo) + self.assertEqual(result['view_name'], '') + self.assertEqual(result['subpath'], ()) + self.assertEqual( + result['traversed'], + (text_(b'Qu\xc3\xa9bec', 'utf-8'),) + ) + self.assertEqual(result['root'], policy.root) + self.assertEqual(result['virtual_root'], policy.root) + self.assertEqual(result['virtual_root_path'], ()) + def test_call_pathel_with_no_getitem(self): policy = self._makeOne(None) environ = self._getEnviron(PATH_INFO='/foo/bar') @@ -295,6 +320,33 @@ class ResourceTreeTraverserTests(unittest.TestCase): self.assertEqual(result['virtual_root'], policy.root) self.assertEqual(result['virtual_root_path'], ()) + def test_call_with_vh_root_highorder(self): + bar = DummyContext(None, 'bar') + foo = DummyContext(bar, text_(b'Qu\xc3\xa9bec', 'utf-8')) + root = DummyContext(foo, 'root') + policy = self._makeOne(root) + if PY3: + vhm_root = b'/Qu\xc3\xa9bec'.encode('latin-1') + else: + vhm_root = b'/Qu\xc3\xa9bec' + environ = self._getEnviron(HTTP_X_VHM_ROOT=vhm_root, + PATH_INFO='/bar') + request = DummyRequest(environ) + result = policy(request) + self.assertEqual(result['context'], bar) + self.assertEqual(result['view_name'], '') + self.assertEqual(result['subpath'], ()) + self.assertEqual( + result['traversed'], + (text_(b'Qu\xc3\xa9bec', 'utf-8'), u'bar') + ) + self.assertEqual(result['root'], policy.root) + self.assertEqual(result['virtual_root'], foo) + self.assertEqual( + result['virtual_root_path'], + (text_(b'Qu\xc3\xa9bec', 'utf-8'),) + ) + def test_non_utf8_path_segment_unicode_path_segments_fails(self): from pyramid.exceptions import URLDecodeError foo = DummyContext() diff --git a/pyramid/traversal.py b/pyramid/traversal.py index ffc40fa60..84dcd33ec 100644 --- a/pyramid/traversal.py +++ b/pyramid/traversal.py @@ -667,8 +667,8 @@ class ResourceTreeTraverser(object): if VH_ROOT_KEY in environ: # HTTP_X_VHM_ROOT vroot_path = decode_path_info(environ[VH_ROOT_KEY]) - vroot_tuple = traversal_path_info(vroot_path) - vpath = vroot_path + path + vroot_tuple = split_path_info(vroot_path) + vpath = vroot_path + path # both will (must) be unicode or asciistr vroot_idx = len(vroot_tuple) -1 else: vroot_tuple = () @@ -688,7 +688,7 @@ class ResourceTreeTraverser(object): # and this hurts readability; apologies i = 0 view_selector = self.VIEW_SELECTOR - vpath_tuple = traversal_path_info(vpath) + vpath_tuple = split_path_info(vpath) for segment in vpath_tuple: if segment[:2] == view_selector: return {'context':ob, |
