mirror of
https://github.com/django/django.git
synced 2025-10-24 14:16:09 +00:00
Fixed #24013 -- Fixed escaping of reverse() prefix.
Prefix was treated as a part of the url pattern, which it is not. Improved tests to conform with RFC 3986 which allows certain characters in path segments without being escaped.
This commit is contained in:
@@ -453,16 +453,15 @@ class RegexURLResolver(LocaleRegexProvider):
|
||||
)
|
||||
possibilities = self.reverse_dict.getlist(lookup_view)
|
||||
|
||||
prefix_norm, prefix_args = normalize(urlquote(_prefix))[0]
|
||||
for possibility, pattern, defaults in possibilities:
|
||||
for result, params in possibility:
|
||||
if args:
|
||||
if len(args) != len(params) + len(prefix_args):
|
||||
if len(args) != len(params):
|
||||
continue
|
||||
candidate_subs = dict(zip(prefix_args + params, text_args))
|
||||
candidate_subs = dict(zip(params, text_args))
|
||||
else:
|
||||
if (set(kwargs.keys()) | set(defaults.keys()) != set(params) |
|
||||
set(defaults.keys()) | set(prefix_args)):
|
||||
set(defaults.keys())):
|
||||
continue
|
||||
matches = True
|
||||
for k, v in defaults.items():
|
||||
@@ -477,12 +476,10 @@ class RegexURLResolver(LocaleRegexProvider):
|
||||
# without quoting to build a decoded URL and look for a match.
|
||||
# Then, if we have a match, redo the substitution with quoted
|
||||
# arguments in order to return a properly encoded URL.
|
||||
candidate_pat = prefix_norm.replace('%', '%%') + result
|
||||
if re.search('^%s%s' % (prefix_norm, pattern), candidate_pat % candidate_subs, re.UNICODE):
|
||||
candidate_pat = _prefix.replace('%', '%%') + result
|
||||
if re.search('^%s%s' % (re.escape(_prefix), pattern), candidate_pat % candidate_subs, re.UNICODE):
|
||||
# safe characters from `pchar` definition of RFC 3986
|
||||
candidate_subs = dict((k, urlquote(v, safe=RFC3986_SUBDELIMS + str('/~:@')))
|
||||
for (k, v) in candidate_subs.items())
|
||||
url = candidate_pat % candidate_subs
|
||||
url = urlquote(candidate_pat % candidate_subs, safe=RFC3986_SUBDELIMS + str('/~:@'))
|
||||
# Don't allow construction of scheme relative urls.
|
||||
if url.startswith('//'):
|
||||
url = '/%%2F%s' % url[2:]
|
||||
|
||||
Reference in New Issue
Block a user