Opened 2 years ago

Closed 12 months ago

#19802 closed Bug (fixed)

HttpResponse.set_cookie doesn't handle unicode data

Reported by: django@… Owned by: qingfeng
Component: HTTP handling Version: 1.5
Severity: Normal Keywords: cookie
Cc: semenov@… Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When calling HttpResponse.set_cookie as below, you get an error from translate saying it doesn't expect two variables. The backtrace is (relevant parts only):

TypeError at /js/utils/cookie/set/
translate() takes exactly one argument (2 given)

...

Traceback:
File "/home/patrick/spng/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  111.                         response = callback(request, *callback_args, **callback_kwargs)
File "/home/patrick/spng/src/utils/views.py" in ajax_set_cookie
  210.             response.set_cookie(key, value)
File "/home/patrick/spng/lib/python2.7/site-packages/django/http/__init__.py" in set_cookie
  657.         self.cookies[key] = value
File "/usr/lib/python2.7/Cookie.py" in __setitem__
  592.         self.__set(key, rval, cval)
File "/home/patrick/spng/lib/python2.7/site-packages/django/http/__init__.py" in _BaseCookie__set
  103.                     M.set(key, real_value, coded_value)
File "/usr/lib/python2.7/Cookie.py" in set
  459.         if "" != translate(key, idmap, LegalChars):
File "/usr/lib/python2.7/string.py" in translate
  493.         return s.translate(table, deletions)

Exception Type: TypeError at /js/utils/cookie/set/
Exception Value: translate() takes exactly one argument (2 given)

This is happening under Django 1.4.2 and Python 2.7.3 (both latest from the Ubuntu 12.10 repository). The code used to trigger this bug is:

from django.http import HttpResponse

def view(request):
    response = HttpResponse()
    response.set_cookie(u'unicode_string', 'does not work!')
    return response


Change History (10)

comment:1 Changed 2 years ago by claudep

  • Component changed from Core (Other) to HTTP handling
  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Resolution set to worksforme
  • Status changed from new to closed

Django 1.5 should support unicode cookie keys. On 1.4, you can workaround this by encoding the key (e.g. u'unicode_string'.encode('utf-8')).

comment:2 Changed 17 months ago by semenov

  • Cc semenov@… added
  • Resolution worksforme deleted
  • Status changed from closed to new
  • Type changed from Uncategorized to Bug
  • Version changed from 1.4 to 1.5

This is still broken in 1.5. To reproduce the bug, use the experiment file below:

# Put this in a file called experiment19802.py and run it with:
# django-admin.py runserver --settings=experiment19802

from django.conf.urls import patterns, url
from django.http import HttpResponse

DEBUG = True
ROOT_URLCONF = 'experiment19802'
SECRET_KEY = 'whatever'

def view(request):
        res = HttpResponse('OK')
        res.set_cookie('test', request.GET.get('cookie', ''))
        return res

urlpatterns = patterns('',
    url(r'.*', view),
)

and try to open: http://localhost:8000/?cookie=M%C3%BCller

It will raise the exception:

Traceback:
File "/Users/semenov/work/xxx/venv/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  115.                         response = callback(request, *callback_args, **callback_kwargs)
File "/Users/semenov/tmp/19802/experiment19802.py" in view
  13. 	res.set_cookie('test', request.GET.get('cookie', ''))
File "/Users/semenov/work/xxx/venv/lib/python2.7/site-packages/django/http/response.py" in set_cookie
  157.         self.cookies[key] = value
File "/usr/local/Cellar/python/2.7.6/Frameworks/Python.framework/Versions/2.7/lib/python2.7/Cookie.py" in __setitem__
  591.         rval, cval = self.value_encode(value)
File "/usr/local/Cellar/python/2.7.6/Frameworks/Python.framework/Versions/2.7/lib/python2.7/Cookie.py" in value_encode
  680.         strval = str(val)

Exception Type: UnicodeEncodeError at /
Exception Value: 'ascii' codec can't encode character u'\xfc' in position 1: ordinal not in range(128)

comment:3 Changed 16 months ago by erikr

  • Triage Stage changed from Unreviewed to Accepted

I can reproduce this issue on current master.

comment:4 Changed 16 months ago by erikr

However, it is only reproducible on Python 2 - it works fine for me in Python 3.3. So, it seems the issue is that Python 2 cookielib coerces str() on the cookie contents. Not sure what the proper solution would be here.

comment:5 Changed 12 months ago by anonymous

  • Has patch set
  • Needs tests set
  • Owner changed from nobody to anonymous
  • Status changed from new to assigned

comment:6 Changed 12 months ago by qingfeng

  • Owner changed from anonymous to qingfeng

comment:7 Changed 12 months ago by qingfeng

@erikr @claudep pls review, thanks :beer:

comment:8 Changed 12 months ago by timo

  • Needs tests unset
  • Patch needs improvement set

I left comments for improvement on PR. Please uncheck "Patch needs improvement" when you update it, thanks.

comment:9 Changed 12 months ago by claudep

  • Patch needs improvement unset
  • Triage Stage changed from Accepted to Ready for checkin

For the committer, please just add in the commit message that this is a Python 2 only issue.

comment:10 Changed 12 months ago by Tim Graham <timograham@…>

  • Resolution set to fixed
  • Status changed from assigned to closed

In 0d23450e81dc355c354a873fe187687e4aaa4886:

Fixed #19802 -- Fixed HttpResponse.set_cookie() with unicode data on Python 2.

Thanks django at patrickbregman.eu for the report.

Note: See TracTickets for help on using tickets.
Back to Top