summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Bangert <ben@groovie.org>2020-07-30 10:59:32 -0700
committerGitHub <noreply@github.com>2020-07-30 10:59:32 -0700
commitd312ea6dfea57a11b75d25f8b1c0c89d6cf854e6 (patch)
tree2fd51aefa4ceffb3ac8e601b040729ac3f346158
parentce4c668485506fc0f3dbaaf3c8590e2247c88d0b (diff)
parent4d5d931c03d742588454e53ee7a579fce400edca (diff)
downloadroutes-d312ea6dfea57a11b75d25f8b1c0c89d6cf854e6.tar.gz
Merge pull request #83 from aib/master
Allow backslash to escape special characters \:*{} in route paths
-rw-r--r--routes/route.py11
-rw-r--r--tests/test_units/test_route_escapes.py31
2 files changed, 41 insertions, 1 deletions
diff --git a/routes/route.py b/routes/route.py
index 84bbd2d..54a37fe 100644
--- a/routes/route.py
+++ b/routes/route.py
@@ -146,13 +146,22 @@ class Route(object):
"""Utility function to walk the route, and pull out the valid
dynamic/wildcard keys."""
collecting = False
+ escaping = False
current = ''
done_on = ''
var_type = ''
just_started = False
routelist = []
for char in routepath:
- if char in [':', '*', '{'] and not collecting and not self.static \
+ if escaping:
+ if char in ['\\', ':', '*', '{', '}']:
+ current += char
+ else:
+ current += '\\' + char
+ escaping = False
+ elif char == '\\':
+ escaping = True
+ elif char in [':', '*', '{'] and not collecting and not self.static \
or char in ['{'] and not collecting:
just_started = True
collecting = True
diff --git a/tests/test_units/test_route_escapes.py b/tests/test_units/test_route_escapes.py
new file mode 100644
index 0000000..fadfd5e
--- /dev/null
+++ b/tests/test_units/test_route_escapes.py
@@ -0,0 +1,31 @@
+import unittest
+from routes.route import Route
+
+class TestRouteEscape(unittest.TestCase):
+ def test_normal_route(self):
+ r = Route('test', '/foo/bar')
+ self.assertEqual(r.routelist, ['/foo/bar'])
+
+ def test_route_with_backslash(self):
+ r = Route('test', '/foo\\\\bar')
+ self.assertEqual(r.routelist, ['/foo\\bar'])
+
+ def test_route_with_random_escapes(self):
+ r = Route('test', '\\/f\\oo\\/ba\\r')
+ self.assertEqual(r.routelist, ['\\/f\\oo\\/ba\\r'])
+
+ def test_route_with_colon(self):
+ r = Route('test', '/foo:bar/baz')
+ self.assertEqual(r.routelist, ['/foo', {'name': 'bar', 'type': ':'}, '/', 'baz'])
+
+ def test_route_with_escaped_colon(self):
+ r = Route('test', '/foo\\:bar/baz')
+ self.assertEqual(r.routelist, ['/foo:bar/baz'])
+
+ def test_route_with_both_colons(self):
+ r = Route('test', '/prefix/escaped\\:escaped/foo=:notescaped/bar=42')
+ self.assertEqual(r.routelist, ['/prefix/escaped:escaped/foo=', {'name': 'notescaped', 'type': ':'}, '/', 'bar=42'])
+
+ def test_route_with_all_escapes(self):
+ r = Route('test', '/hmm\\:\\*\\{\\}*star/{brackets}/:colon')
+ self.assertEqual(r.routelist, ['/hmm:*{}', {'name': 'star', 'type': '*'}, '/', {'name': 'brackets', 'type': ':'}, '/', {'name': 'colon', 'type': ':'}])