diff -r 831be7dc260a Doc/library/http.cookies.rst --- a/Doc/library/http.cookies.rst Sat Feb 23 07:53:56 2013 +0200 +++ b/Doc/library/http.cookies.rst Sat Feb 23 17:30:50 2013 +0100 @@ -106,7 +106,8 @@ .. method:: BaseCookie.load(rawdata) If *rawdata* is a string, parse it as an ``HTTP_COOKIE`` and add the values - found there as :class:`Morsel`\ s. If it is a dictionary, it is equivalent to:: + found there as :class:`Morsel`\ s. In case the string contains duplicate + keys, the first value is used. If it is a dictionary, it is equivalent to:: for k, v in rawdata.items(): cookie[k] = v diff -r 831be7dc260a Lib/http/cookies.py --- a/Lib/http/cookies.py Sat Feb 23 07:53:56 2013 +0200 +++ b/Lib/http/cookies.py Sat Feb 23 17:30:50 2013 +0100 @@ -529,6 +529,7 @@ i = 0 # Our starting point n = len(str) # Length of string M = None # current morsel + keys = set() # Keys found in string while 0 <= i < n: # Start looking for a cookie @@ -540,6 +541,13 @@ key, value = match.group("key"), match.group("val") i = match.end(0) + # If a key is duplicated in the string, + # only use the first value and ignore duplicates + if key in keys: + continue + else: + keys.add(key) + # Parse the key, value in case it's metainfo if key[0] == "$": # We ignore attributes which pertain to the cookie diff -r 831be7dc260a Lib/test/test_http_cookies.py --- a/Lib/test/test_http_cookies.py Sat Feb 23 07:53:56 2013 +0200 +++ b/Lib/test/test_http_cookies.py Sat Feb 23 17:30:50 2013 +0100 @@ -29,6 +29,12 @@ 'repr': '''''', 'output': 'Set-Cookie: keebler="E=mc2; L=\\"Loves\\"; fudge=\\012;"'}, + # Check that first value for a duplicate key is used + {'data': 'duplicate=first; duplicate=second', + 'dict': {'duplicate':'first'}, + 'repr': "", + 'output': 'Set-Cookie: duplicate=first'}, + # Check illegal cookies that have an '=' char in an unquoted value {'data': 'keebler=E=mc2', 'dict': {'keebler' : 'E=mc2'},