From 5c1f28ba8e6f0958ee352cdb979197e4b8222fef Mon Sep 17 00:00:00 2001 From: Aviram Hassan Date: Wed, 18 Mar 2020 14:49:59 +0200 Subject: [PATCH] http.cookies: BaseCookie add ignore_errors kwarg to load method --- Doc/library/http.cookies.rst | 6 +++++- Lib/http/cookies.py | 14 +++++++++----- Lib/test/test_http_cookies.py | 7 +++++++ .../2020-03-18-12-33-11.bpo-40001.8jJvn1.rst | 1 + 4 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-03-18-12-33-11.bpo-40001.8jJvn1.rst diff --git a/Doc/library/http.cookies.rst b/Doc/library/http.cookies.rst index 17792b200599bd8..0464be5447b8346 100644 --- a/Doc/library/http.cookies.rst +++ b/Doc/library/http.cookies.rst @@ -109,7 +109,7 @@ Cookie Objects The meaning for *attrs* is the same as in :meth:`output`. -.. method:: BaseCookie.load(rawdata) +.. method:: BaseCookie.load(rawdata, *, ignore_errors=False) 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:: @@ -117,6 +117,10 @@ Cookie Objects for k, v in rawdata.items(): cookie[k] = v + if ignore_errors is True, skip Morsels that raise CookieError. + + .. versionchanged:: 3.9 + *ignore_errors* was added. .. _morsel-objects: diff --git a/Lib/http/cookies.py b/Lib/http/cookies.py index 6694f5478bdadfb..89f3a1588ef7f27 100644 --- a/Lib/http/cookies.py +++ b/Lib/http/cookies.py @@ -519,21 +519,21 @@ def js_output(self, attrs=None): result.append(value.js_output(attrs)) return _nulljoin(result) - def load(self, rawdata): + def load(self, rawdata, *, ignore_errors=False): """Load cookies from a string (presumably HTTP_COOKIE) or from a dictionary. Loading cookies from a dictionary 'd' is equivalent to calling: map(Cookie.__setitem__, d.keys(), d.values()) """ if isinstance(rawdata, str): - self.__parse_string(rawdata) + self.__parse_string(rawdata, ignore_errors) else: # self.update() wouldn't call our custom __setitem__ for key, value in rawdata.items(): self[key] = value return - def __parse_string(self, str, patt=_CookiePattern): + def __parse_string(self, str, ignore_errors, patt=_CookiePattern): i = 0 # Our starting point n = len(str) # Length of string parsed_items = [] # Parsed (type, key, value) triples @@ -590,8 +590,12 @@ def __parse_string(self, str, patt=_CookiePattern): else: assert tp == TYPE_KEYVALUE rval, cval = value - self.__set(key, rval, cval) - M = self[key] + try: + self.__set(key, rval, cval) + M = self[key] + except CookieError: + if not ignore_errors: + raise class SimpleCookie(BaseCookie): diff --git a/Lib/test/test_http_cookies.py b/Lib/test/test_http_cookies.py index 6072c7e15e92be5..a517ae4dd79440d 100644 --- a/Lib/test/test_http_cookies.py +++ b/Lib/test/test_http_cookies.py @@ -83,6 +83,13 @@ def test_load(self): """) + C = cookies.SimpleCookie() + C.load('inv/alid=test; Customer="WILE_E_COYOTE"; Version=1; Path=/acme', ignore_errors=True) + + self.assertEqual(C['Customer'].value, 'WILE_E_COYOTE') + self.assertEqual(C['Customer']['version'], '1') + self.assertEqual(C['Customer']['path'], '/acme') + def test_extended_encode(self): # Issue 9824: some browsers don't follow the standard; we now # encode , and ; to keep them from tripping up. diff --git a/Misc/NEWS.d/next/Library/2020-03-18-12-33-11.bpo-40001.8jJvn1.rst b/Misc/NEWS.d/next/Library/2020-03-18-12-33-11.bpo-40001.8jJvn1.rst new file mode 100644 index 000000000000000..ea52c3c49685d4e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-03-18-12-33-11.bpo-40001.8jJvn1.rst @@ -0,0 +1 @@ +Added `ignore_errors` keyword argument to `BaseCookie` with default value False. When True, BaseCookie load skips invalid Morsels. \ No newline at end of file