From: afg Date: Tue, 5 Jan 2016 16:43:20 +0000 (+0800) Subject: re_unescape with a much simpler method; raise TypeError on invalid input X-Git-Tag: v4.4.0b1~50^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e85e0b68ab28ccd8728a87e5791dc30732192ef3;p=thirdparty%2Ftornado.git re_unescape with a much simpler method; raise TypeError on invalid input --- diff --git a/tornado/test/util_test.py b/tornado/test/util_test.py index 6a0fa5c4a..70b6e7a1e 100644 --- a/tornado/test/util_test.py +++ b/tornado/test/util_test.py @@ -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') diff --git a/tornado/util.py b/tornado/util.py index e74be97c7..a0401c143 100644 --- a/tornado/util.py +++ b/tornado/util.py @@ -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): diff --git a/tornado/web.py b/tornado/web.py index a5301db16..b45363cca 100644 --- a/tornado/web.py +++ b/tornado/web.py @@ -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)