[1.5.x] Fixed #15152 -- Avoided crash of CommonMiddleware on broken querystring

Backport of 973f539 from master.
This commit is contained in:
Aymeric Augustin 2012-11-03 21:26:59 +01:00
parent e51a9c0c94
commit be6522561f
2 changed files with 21 additions and 1 deletions

View File

@ -6,6 +6,7 @@ from django.conf import settings
from django import http
from django.core.mail import mail_managers
from django.utils.http import urlquote
from django.utils import six
from django.core import urlresolvers
@ -87,7 +88,17 @@ class CommonMiddleware(object):
else:
newurl = urlquote(new_url[1])
if request.META.get('QUERY_STRING', ''):
newurl += '?' + request.META['QUERY_STRING']
if six.PY3:
newurl += '?' + request.META['QUERY_STRING']
else:
# `query_string` is a bytestring. Appending it to the unicode
# string `newurl` will fail if it isn't ASCII-only. This isn't
# allowed; only broken software generates such query strings.
# Better drop the invalid query string than crash (#15152).
try:
newurl += '?' + request.META['QUERY_STRING'].decode()
except UnicodeDecodeError:
pass
return http.HttpResponsePermanentRedirect(newurl)
def process_response(self, request, response):

View File

@ -294,6 +294,15 @@ class CommonMiddlewareTest(TestCase):
CommonMiddleware().process_response(request, response)
self.assertEqual(len(mail.outbox), 0)
# Other tests
def test_non_ascii_query_string_does_not_crash(self):
"""Regression test for #15152"""
request = self._get_request('slash')
request.META['QUERY_STRING'] = 'drink=café'
response = CommonMiddleware().process_request(request)
self.assertEqual(response.status_code, 301)
class ConditionalGetMiddlewareTest(TestCase):
urls = 'regressiontests.middleware.cond_get_urls'