]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
re_unescape with a much simpler method; raise TypeError on invalid input 1619/head
authorafg <afg984@gmail.com>
Tue, 5 Jan 2016 16:43:20 +0000 (00:43 +0800)
committerafg <afg984@gmail.com>
Tue, 5 Jan 2016 16:43:20 +0000 (00:43 +0800)
tornado/test/util_test.py
tornado/util.py
tornado/web.py

index 6a0fa5c4abb5684be82fa5753e6b9bc30aef7e2f..70b6e7a1e299e3d279949c4765254f7831f6ade0 100644 (file)
@@ -207,9 +207,16 @@ class ReUnescapeTest(unittest.TestCase):
         test_strings = (
             '/favicon.ico',
             'index.html',
-            '\x00\x01\\000',
             'Hello, World!',
             '!$@#%;',
         )
         for string in test_strings:
             self.assertEqual(string, re_unescape(re.escape(string)))
+
+    def test_re_unescape_raises_error_on_invalid_input(self):
+        with self.assertRaises(ValueError):
+            re_unescape('\\d')
+        with self.assertRaises(ValueError):
+            re_unescape('\\b')
+        with self.assertRaises(ValueError):
+            re_unescape('\\Z')
index e74be97c7255988f8edbf730c89e22e78c1e6250..a0401c143cf07ff05708190b92af90b8af64ffd4 100644 (file)
@@ -173,20 +173,22 @@ def errno_from_exception(e):
         return None
 
 
-_re_unescape_split_pattern = re.compile(r'(\\[^0])')
-# re.escape('\x00') is a special case
+_alphanum = frozenset(
+    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
+
+def _re_unescape_replacement(match):
+    group = match.group(1)
+    if group[0] in _alphanum:
+        raise ValueError("cannot unescape '\\\\%s'" % group[0])
+    return group
+
+_re_unescape_pattern = re.compile(r'\\(.)', re.DOTALL)
 
 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)
+    return _re_unescape_pattern.sub(_re_unescape_replacement, s)
 
 
 class Configurable(object):
index a5301db1614ec504044344f77d46f916d048c542..b45363cca6794a45b00df53b4f6919ba6862593e 100644 (file)
@@ -3024,6 +3024,10 @@ class URLSpec(object):
                 if paren_loc >= 0:
                     pieces.append('%s' + fragment[paren_loc + 1:])
             else:
+                try:
+                    unescaped_fragment = re_unescape(fragment)
+                except ValueError as exc:
+                    raise ValueError(exc.args[0] + '; invalid url: %r' % pattern)
                 pieces.append(re_unescape(fragment))
 
         return (''.join(pieces), self.regex.groups)