Opened 8 years ago
Closed 8 years ago
#27198 closed Bug (fixed)
QueryDict getlist allows data to be mutated
Reported by: | Fraser Nevett | Owned by: | Jani Tiainen |
---|---|---|---|
Component: | HTTP handling | Version: | 1.10 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Accepted | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Calling getlist()
on a QueryDict
simply returns the underlying list
, which means it can be mutated:
>>> q = QueryDict('a=1&a=2&a=3', mutable=False) >>> a = q.getlist('a') >>> a [u'1', u'2', u'3'] >>> a.append(u'4') >>> q.getlist('a') [u'1', u'2', u'3', u'4'] >>> q <QueryDict: {u'a': [u'1', u'2', u'3', u'4']}>
I encountered this unexpected behaviour in code using the following pattern:
values = request.POST.getlist('a') values += request.POST.getlist('b') values += request.POST.getlist('c')
This results in request.POST
being updated so that a now also contains the values for b and c.
Given request.GET
and request.POST
are created as immutable QueryDict
objects, I would not expect this behaviour.
At present, getlist
is inherited from MultiValueDict
. I think the fix would be to add a getlist
method to QueryDict
that forces a new list
to be created:
def setlist(self, key, default=None): return list(super(QueryDict, self).getlist(key, default))
Attachments (1)
Change History (6)
comment:1 by , 8 years ago
Triage Stage: | Unreviewed → Accepted |
---|
by , 8 years ago
Attachment: | 27198-test.diff added |
---|
comment:2 by , 8 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:3 by , 8 years ago
Has patch: | set |
---|
Agreed that doesn't seem correct. Attached is a regression test for Django's test suite that currently fails.