Commit 233f8644 authored by Jannis Leidel's avatar Jannis Leidel
Browse files

Merge pull request #490 from gabrielhurley/reverse-prefix-special-chars

Fixed #18210 -- Escaped special characters in reverse prefixes.
parents b8848023 90e53097
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@ from django.core.exceptions import ImproperlyConfigured, ViewDoesNotExist
from django.utils.datastructures import MultiValueDict
from django.utils.encoding import force_str, force_text, iri_to_uri
from django.utils.functional import memoize, lazy
from django.utils.http import urlquote
from django.utils.importlib import import_module
from django.utils.module_loading import module_has_submodule
from django.utils.regex_helper import normalize
@@ -379,7 +380,8 @@ class RegexURLResolver(LocaleRegexProvider):
        except (ImportError, AttributeError) as e:
            raise NoReverseMatch("Error importing '%s': %s." % (lookup_view, e))
        possibilities = self.reverse_dict.getlist(lookup_view)
        prefix_norm, prefix_args = normalize(_prefix)[0]

        prefix_norm, prefix_args = normalize(urlquote(_prefix))[0]
        for possibility, pattern, defaults in possibilities:
            for result, params in possibility:
                if args:
@@ -398,8 +400,8 @@ class RegexURLResolver(LocaleRegexProvider):
                    if not matches:
                        continue
                    unicode_kwargs = dict([(k, force_text(v)) for (k, v) in kwargs.items()])
                    candidate = (prefix_norm + result) % unicode_kwargs
                if re.search('^%s%s' % (_prefix, pattern), candidate, re.UNICODE):
                    candidate = (prefix_norm.replace('%', '%%') + result) % unicode_kwargs
                if re.search('^%s%s' % (prefix_norm, pattern), candidate, re.UNICODE):
                    return candidate
        # lookup_view can be URL label, or dotted path, or callable, Any of
        # these can be passed in at the top, but callables are not friendly in
+12 −0
Original line number Diff line number Diff line
@@ -171,6 +171,18 @@ class URLPatternReverse(TestCase):
        # Reversing None should raise an error, not return the last un-named view.
        self.assertRaises(NoReverseMatch, reverse, None)

    def test_prefix_braces(self):
        self.assertEqual('/%7B%7Binvalid%7D%7D/includes/non_path_include/',
               reverse('non_path_include', prefix='/{{invalid}}/'))

    def test_prefix_parenthesis(self):
        self.assertEqual('/bogus%29/includes/non_path_include/',
               reverse('non_path_include', prefix='/bogus)/'))

    def test_prefix_format_char(self):
        self.assertEqual('/bump%2520map/includes/non_path_include/',
               reverse('non_path_include', prefix='/bump%20map/'))

class ResolverTests(unittest.TestCase):
    def test_resolver_repr(self):
        """