Ticket #12470: 12470-cookie-fix-2.diff

File 12470-cookie-fix-2.diff, 4.2 KB (added by Luke Plant, 14 years ago)

Added release notes.

  • django/http/__init__.py

    diff -r 3d401cd0dc82 django/http/__init__.py
    a b  
    248248            output.extend([urlencode({k: smart_str(v, self.encoding)}) for v in list_])
    249249        return '&'.join(output)
    250250
     251class CompatCookie(SimpleCookie):
     252    """
     253    Cookie class that handles some issues with browser compatibility.
     254    """
     255    def value_encode(self, val):
     256        # Some browsers do not support quoted-string from RFC 2109,
     257        # including some versions of Safari and Internet Explorer.
     258        # These browsers split on ';', and some versions of Safari
     259        # are known to split on ', '. Therefore, we encode ';' and ','
     260
     261        # SimpleCookie already does the hard work of encoding and decoding.
     262        # It uses octal sequences like '\\012' for newline etc.
     263        # and non-ASCII chars.  We just make use of this mechanism, to
     264        # avoid introducing two encoding schemes which would be confusing
     265        # and especially awkward for javascript.
     266
     267        # NB, contrary to Python docs, value_encode returns a tuple containing
     268        # (real val, encoded_val)
     269        val, encoded = super(CompatCookie, self).value_encode(val)
     270
     271        encoded = encoded.replace(";", "\\073").replace(",","\\054")
     272        # If encoded now contains any quoted chars, we need double quotes
     273        # around the whole string.
     274        if "\\" in encoded and not encoded.startswith('"'):
     275            encoded = '"' + encoded + '"'
     276
     277        return val, encoded
     278
    251279def parse_cookie(cookie):
    252280    if cookie == '':
    253281        return {}
    254282    if not isinstance(cookie, BaseCookie):
    255283        try:
    256             c = SimpleCookie()
     284            c = CompatCookie()
    257285            c.load(cookie)
    258286        except CookieError:
    259287            # Invalid cookie
     
    288316        else:
    289317            self._container = [content]
    290318            self._is_string = True
    291         self.cookies = SimpleCookie()
     319        self.cookies = CompatCookie()
    292320        if status:
    293321            self.status_code = status
    294322
  • docs/releases/1.2.txt

    diff -r 3d401cd0dc82 docs/releases/1.2.txt
    a b  
    240240for any number of test failures. If needed, the number of test failures can be
    241241found at the end of the test runner's output.
    242242
     243Cookie quoting
     244--------------
     245
     246Due to bugs and variations in web browsers, we've slightly changed the way that
     247cookie values are encoded. Comma (',') and semi-colon (';') now use the same
     248octal encoding mechanism that is used for other special characters.  If you
     249were not previously storing either of these two characters in cookies you are
     250not affected.
     251
    243252.. _deprecated-features-1.2:
    244253
    245254Features deprecated in 1.2
  • tests/regressiontests/httpwrappers/tests.py

    diff -r 3d401cd0dc82 tests/regressiontests/httpwrappers/tests.py
    a b  
    465465[u'1', u'2', u'3', u'4']
    466466"""
    467467
    468 from django.http import QueryDict, HttpResponse
     468from django.http import QueryDict, HttpResponse, CompatCookie
     469from django.test import TestCase
     470
     471
     472class Cookies(TestCase):
     473
     474    def test_encode(self):
     475        """
     476        Test that we don't output tricky characters in encoded value
     477        """
     478        c = CompatCookie()
     479        c['test'] = "An,awkward;value"
     480        self.assert_(";" not in c.output()) # IE compat
     481        self.assert_("," not in c.output()) # Safari compat
     482
     483    def test_decode(self):
     484        """
     485        Test that we can still preserve semi-colons and commas
     486        """
     487        c = CompatCookie()
     488        c['test'] = "An,awkward;value"
     489        c2 = CompatCookie()
     490        c2.load(c.output())
     491        self.assertEqual(c['test'].value, c2['test'].value)
     492
     493    def test_decode_2(self):
     494        """
     495        Test that we haven't broken normal encoding
     496        """
     497        c = CompatCookie()
     498        c['test'] = "\xf0"
     499        c2 = CompatCookie()
     500        c2.load(c.output())
     501        self.assertEqual(c['test'].value, c2['test'].value)
    469502
    470503if __name__ == "__main__":
    471504    import doctest
Back to Top