summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2012-01-05 06:32:38 -0500
committerChris McDonough <chrism@plope.com>2012-01-05 06:32:38 -0500
commit92dcb5f1a52d46fec7c043a1b5b4158f3d013c34 (patch)
tree72ff58e0f8559d3f71845b1b1cc52fd70157f593
parentad9807016fd28b7da424174fdb6ed9b93641f58f (diff)
downloadpyramid-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.txt8
-rw-r--r--pyramid/tests/test_traversal.py60
-rw-r--r--pyramid/traversal.py6
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,