]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
reverse_url should unescape regex string
authorafg <afg984@gmail.com>
Mon, 28 Dec 2015 06:06:56 +0000 (14:06 +0800)
committerafg <afg984@gmail.com>
Mon, 28 Dec 2015 06:06:56 +0000 (14:06 +0800)
tornado/test/util_test.py
tornado/test/web_test.py
tornado/util.py
tornado/web.py

index 98378fa0514a85ebeda5cc66f92625d158453df1..6a0fa5c4abb5684be82fa5753e6b9bc30aef7e2f 100644 (file)
@@ -1,11 +1,12 @@
 # coding: utf-8
 from __future__ import absolute_import, division, print_function, with_statement
+import re
 import sys
 import datetime
 
 import tornado.escape
 from tornado.escape import utf8
-from tornado.util import raise_exc_info, Configurable, exec_in, ArgReplacer, timedelta_to_seconds, import_object
+from tornado.util import raise_exc_info, Configurable, exec_in, ArgReplacer, timedelta_to_seconds, import_object, re_unescape
 from tornado.test.util import unittest
 
 try:
@@ -199,3 +200,16 @@ class ImportObjectTest(unittest.TestCase):
         # whether the thing being imported is a module or not.
         # This variant requires a byte string in python 2.
         self.assertIs(import_object(u'tornado.escape'), tornado.escape)
+
+
+class ReUnescapeTest(unittest.TestCase):
+    def test_re_unescape(self):
+        test_strings = (
+            '/favicon.ico',
+            'index.html',
+            '\x00\x01\\000',
+            'Hello, World!',
+            '!$@#%;',
+        )
+        for string in test_strings:
+            self.assertEqual(string, re_unescape(re.escape(string)))
index 9f3582d12905ff5a78749b2834c0e34112201963..7ae3d874536729f2b9d86a53d0456923cc843f39 100644 (file)
@@ -2763,3 +2763,8 @@ class ApplicationTest(AsyncTestCase):
         app = Application([])
         server = app.listen(0, address='127.0.0.1')
         server.stop()
+
+
+class URLSpecReverseTest(unittest.TestCase):
+    def test_reverse(self):
+        self.assertEqual('/favicon.ico', url(r'/favicon\.ico', None).reverse())
index 5e083961a10bf9b00d87559502176c6b61cadaaa..e74be97c7255988f8edbf730c89e22e78c1e6250 100644 (file)
@@ -14,6 +14,7 @@ from __future__ import absolute_import, division, print_function, with_statement
 
 import array
 import os
+import re
 import sys
 import zlib
 
@@ -172,6 +173,22 @@ def errno_from_exception(e):
         return None
 
 
+_re_unescape_split_pattern = re.compile(r'(\\[^0])')
+# re.escape('\x00') is a special case
+
+def re_unescape(s):
+    '''
+    unescape a string escaped by ``re.escape()``
+    '''
+    parts = []
+    for i, splited in enumerate(_re_unescape_split_pattern.split(s)):
+        if i % 2:
+            parts.append(splited[1])
+        else:
+            parts.append(splited.replace(r'\000', '\000'))
+    return ''.join(parts)
+
+
 class Configurable(object):
     """Base class for configurable interfaces.
 
index c51d5f68a5cdddf09e9af0a2f449433b3bb8e840..a5301db1614ec504044344f77d46f916d048c542 100644 (file)
@@ -90,7 +90,7 @@ from tornado import stack_context
 from tornado import template
 from tornado.escape import utf8, _unicode
 from tornado.util import (import_object, ObjectDict, raise_exc_info,
-                          unicode_type, _websocket_mask)
+                          unicode_type, _websocket_mask, re_unescape)
 from tornado.httputil import split_host_and_port
 
 
@@ -184,7 +184,7 @@ class RequestHandler(object):
 
     def initialize(self):
         """Hook for subclass initialization. Called for each request.
-          
+
         A dictionary passed as the third argument of a url spec will be
         supplied as keyword arguments to initialize().
 
@@ -3024,7 +3024,7 @@ class URLSpec(object):
                 if paren_loc >= 0:
                     pieces.append('%s' + fragment[paren_loc + 1:])
             else:
-                pieces.append(fragment)
+                pieces.append(re_unescape(fragment))
 
         return (''.join(pieces), self.regex.groups)