Ticket #19101: 19101-1.diff

File 19101-1.diff, 3.4 KB (added by claudep, 3 years ago)

Fixed non-ascii form data decoding with Python 3

  • django/core/handlers/wsgi.py

    diff --git a/django/core/handlers/wsgi.py b/django/core/handlers/wsgi.py
    index 7d2ee44..48b3b7f 100644
    a b  
    11from __future__ import unicode_literals
    22
     3import codecs
    34import logging
    45import sys
    56from io import BytesIO
    class WSGIRequest(http.HttpRequest): 
    144145        self.META['PATH_INFO'] = path_info
    145146        self.META['SCRIPT_NAME'] = script_name
    146147        self.method = environ['REQUEST_METHOD'].upper()
     148        if 'charset=' in self.META.get('CONTENT_TYPE', ''):
     149            charset = self.META['CONTENT_TYPE'].split('charset=')[-1]
     150            try:
     151                codecs.lookup(charset)
     152            except LookupError:
     153                pass
     154            else:
     155                self.encoding = charset
    147156        self._post_parse_error = False
    148157        try:
    149158            content_length = int(self.environ.get('CONTENT_LENGTH'))
  • django/http/__init__.py

    diff --git a/django/http/__init__.py b/django/http/__init__.py
    index b67c182..9999185 100644
    a b class HttpRequest(object): 
    342342                self._mark_post_parse_error()
    343343                raise
    344344        elif self.META.get('CONTENT_TYPE', '').startswith('application/x-www-form-urlencoded'):
    345             self._post, self._files = QueryDict(self.body, encoding=self._encoding), MultiValueDict()
     345            self._post, self._files = QueryDict(force_str(self.body), encoding=self._encoding), MultiValueDict()
    346346        else:
    347347            self._post, self._files = QueryDict('', encoding=self._encoding), MultiValueDict()
    348348
  • tests/regressiontests/requests/tests.py

    diff --git a/tests/regressiontests/requests/tests.py b/tests/regressiontests/requests/tests.py
    index 2ec478a..16ceea7 100644
    a b  
     1# -*- encoding: utf-8 -*-
    12from __future__ import unicode_literals
    23
    34import time
    from django.http import HttpRequest, HttpResponse, parse_cookie, build_request_r 
    1213from django.test.client import FakePayload
    1314from django.test.utils import str_prefix
    1415from django.utils import unittest
    15 from django.utils.http import cookie_date
     16from django.utils.http import cookie_date, urlencode
    1617from django.utils.timezone import utc
    1718
    1819
    class RequestsTests(unittest.TestCase): 
    364365        self.assertRaises(Exception, lambda: request.body)
    365366        self.assertEqual(request.POST, {})
    366367
     368    def test_non_ascii_POST(self):
     369        payload = FakePayload(urlencode({'key': 'España'}))
     370        request = WSGIRequest({
     371            'REQUEST_METHOD': 'POST',
     372            'CONTENT_LENGTH': len(payload),
     373            'CONTENT_TYPE': 'application/x-www-form-urlencoded',
     374            'wsgi.input': payload,
     375        })
     376        self.assertEqual(request.POST, {'key': ['España']})
     377
     378        # latin-1 encoding
     379        from django.utils.http import urllib_parse
     380        payload = FakePayload(urllib_parse.urlencode({'key': 'España'.encode('latin-1')}))
     381        request = WSGIRequest({
     382            'REQUEST_METHOD': 'POST',
     383            'CONTENT_LENGTH': len(payload),
     384            'CONTENT_TYPE': 'application/x-www-form-urlencoded; charset=iso-8859-1',
     385            'wsgi.input': payload,
     386        })
     387        self.assertEqual(request.POST, {'key': ['España']})
     388
    367389    def test_body_after_POST_multipart(self):
    368390        """
    369391        Reading body after parsing multipart is not allowed
Back to Top