Fixed #27606 -- Fixed HttpResponseRedirect.__repr__() crash when DisallowedRedirect is raised.

This commit is contained in:
Jerome Leclanche 2016-12-17 17:34:32 +02:00 committed by Tim Graham
parent 6af23a4521
commit a849ec1880
2 changed files with 14 additions and 3 deletions

View File

@ -420,11 +420,11 @@ class HttpResponseRedirectBase(HttpResponse):
allowed_schemes = ['http', 'https', 'ftp'] allowed_schemes = ['http', 'https', 'ftp']
def __init__(self, redirect_to, *args, **kwargs): def __init__(self, redirect_to, *args, **kwargs):
super(HttpResponseRedirectBase, self).__init__(*args, **kwargs)
self['Location'] = iri_to_uri(redirect_to)
parsed = urlparse(force_text(redirect_to)) parsed = urlparse(force_text(redirect_to))
if parsed.scheme and parsed.scheme not in self.allowed_schemes: if parsed.scheme and parsed.scheme not in self.allowed_schemes:
raise DisallowedRedirect("Unsafe redirect to URL with protocol '%s'" % parsed.scheme) raise DisallowedRedirect("Unsafe redirect to URL with protocol '%s'" % parsed.scheme)
super(HttpResponseRedirectBase, self).__init__(*args, **kwargs)
self['Location'] = iri_to_uri(redirect_to)
url = property(lambda self: self['Location']) url = property(lambda self: self['Location'])

View File

@ -8,7 +8,7 @@ import pickle
import unittest import unittest
import uuid import uuid
from django.core.exceptions import SuspiciousOperation from django.core.exceptions import DisallowedRedirect, SuspiciousOperation
from django.core.serializers.json import DjangoJSONEncoder from django.core.serializers.json import DjangoJSONEncoder
from django.core.signals import request_finished from django.core.signals import request_finished
from django.db import close_old_connections from django.db import close_old_connections
@ -517,6 +517,17 @@ class HttpResponseSubclassesTests(SimpleTestCase):
expected = '<HttpResponseRedirect status_code=302, "text/html; charset=utf-8", url="/redirected/">' expected = '<HttpResponseRedirect status_code=302, "text/html; charset=utf-8", url="/redirected/">'
self.assertEqual(repr(response), expected) self.assertEqual(repr(response), expected)
def test_invalid_redirect_repr(self):
"""
If HttpResponseRedirect raises DisallowedRedirect, its __repr__()
should work (in the debug view, for example).
"""
response = HttpResponseRedirect.__new__(HttpResponseRedirect)
with self.assertRaisesMessage(DisallowedRedirect, "Unsafe redirect to URL with protocol 'ssh'"):
HttpResponseRedirect.__init__(response, 'ssh://foo')
expected = '<HttpResponseRedirect status_code=302, "text/html; charset=utf-8", url="ssh://foo">'
self.assertEqual(repr(response), expected)
def test_not_modified(self): def test_not_modified(self):
response = HttpResponseNotModified() response = HttpResponseNotModified()
self.assertEqual(response.status_code, 304) self.assertEqual(response.status_code, 304)