summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVinay Karanam <vinayinvicible@gmail.com>2016-11-16 18:52:38 +0530
committerTim Graham <timograham@gmail.com>2016-12-07 08:28:46 -0500
commit4a246a02bdcbc13b15480c014f51cb0682af7c1e (patch)
treeeebd27f89e806db66f5344b63d63c574578b5697
parent183f5015408ffe0d3a22203ddaf7a3a56da025fd (diff)
Refs #17235 -- Made MultiPartParser leave request.POST immutable.
-rw-r--r--django/contrib/admin/options.py2
-rw-r--r--django/contrib/auth/admin.py1
-rw-r--r--django/http/multipartparser.py1
-rw-r--r--docs/releases/1.11.txt4
-rw-r--r--tests/requests/tests.py19
5 files changed, 26 insertions, 1 deletions
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
index 12487dcc9b..75c256963b 100644
--- a/django/contrib/admin/options.py
+++ b/django/contrib/admin/options.py
@@ -1785,7 +1785,7 @@ class ModelAdmin(BaseModelAdmin):
}
if request.method == 'POST':
formset_params.update({
- 'data': request.POST,
+ 'data': request.POST.copy(),
'files': request.FILES,
'save_as_new': '_saveasnew' in request.POST
})
diff --git a/django/contrib/auth/admin.py b/django/contrib/auth/admin.py
index f84652f8b4..f3c69023be 100644
--- a/django/contrib/auth/admin.py
+++ b/django/contrib/auth/admin.py
@@ -205,6 +205,7 @@ class UserAdmin(admin.ModelAdmin):
# * The user has pressed the 'Save and add another' button
# * We are adding a user in a popup
if '_addanother' not in request.POST and IS_POPUP_VAR not in request.POST:
+ request.POST = request.POST.copy()
request.POST['_continue'] = 1
return super(UserAdmin, self).response_add(request, obj,
post_url_continue)
diff --git a/django/http/multipartparser.py b/django/http/multipartparser.py
index 87d80bdde5..616185f021 100644
--- a/django/http/multipartparser.py
+++ b/django/http/multipartparser.py
@@ -289,6 +289,7 @@ class MultiPartParser(object):
if retval:
break
+ self._post._mutable = False
return self._post, self._files
def handle_file_complete(self, old_field_name, counters):
diff --git a/docs/releases/1.11.txt b/docs/releases/1.11.txt
index 7bf206c678..59b7fb54f9 100644
--- a/docs/releases/1.11.txt
+++ b/docs/releases/1.11.txt
@@ -634,6 +634,10 @@ Miscellaneous
* The undocumented ``django.utils.functional.lazy_property`` is removed.
+* For consistency with non-multipart requests, ``MultiPartParser.parse()`` now
+ leaves ``request.POST`` immutable. If you're modifying that ``QueryDict``,
+ you must now first copy it, e.g. ``request.POST.copy()``.
+
.. _deprecated-features-1.11:
Features deprecated in 1.11
diff --git a/tests/requests/tests.py b/tests/requests/tests.py
index 0942619715..27dc439e5f 100644
--- a/tests/requests/tests.py
+++ b/tests/requests/tests.py
@@ -533,6 +533,25 @@ class RequestsTests(SimpleTestCase):
self.assertEqual(request.read(13), b'--boundary\r\nC')
self.assertEqual(request.POST, {'name': ['value']})
+ def test_POST_immutable_for_mutipart(self):
+ """
+ MultiPartParser.parse() leaves request.POST immutable.
+ """
+ payload = FakePayload("\r\n".join([
+ '--boundary',
+ 'Content-Disposition: form-data; name="name"',
+ '',
+ 'value',
+ '--boundary--',
+ ]))
+ request = WSGIRequest({
+ 'REQUEST_METHOD': 'POST',
+ 'CONTENT_TYPE': 'multipart/form-data; boundary=boundary',
+ 'CONTENT_LENGTH': len(payload),
+ 'wsgi.input': payload,
+ })
+ self.assertFalse(request.POST._mutable)
+
def test_POST_connection_error(self):
"""
If wsgi.input.read() raises an exception while trying to read() the