[cookies] Improve `LenientSimpleCookie` (#5195)

Closes #5186 
Authored by: Grub4K
pull/5208/head
Simon Sawicki 2 years ago committed by GitHub
parent 0468a3b325
commit 36069409ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -277,9 +277,24 @@ class TestLenientSimpleCookie(unittest.TestCase):
"a=b; invalid; Version=1; c=d", "a=b; invalid; Version=1; c=d",
{"a": "b", "c": "d"}, {"a": "b", "c": "d"},
), ),
(
"Reset morsel after invalid to not capture attributes",
"a=b; $invalid; $Version=1; c=d",
{"a": "b", "c": "d"},
),
( (
"Continue after non-flag attribute without value", "Continue after non-flag attribute without value",
"a=b; path; Version=1; c=d", "a=b; path; Version=1; c=d",
{"a": "b", "c": "d"}, {"a": "b", "c": "d"},
), ),
(
"Allow cookie attributes with `$` prefix",
'Customer="WILE_E_COYOTE"; $Version=1; $Secure; $Path=/acme',
{"Customer": ("WILE_E_COYOTE", {"version": "1", "secure": True, "path": "/acme"})},
),
(
"Invalid Morsel keys should not result in an error",
"Key=Value; [Invalid]=Value; Another=Value",
{"Key": "Value", "Another": "Value"},
),
) )

@ -999,8 +999,9 @@ def _parse_browser_specification(browser_name, profile=None, keyring=None, conta
class LenientSimpleCookie(http.cookies.SimpleCookie): class LenientSimpleCookie(http.cookies.SimpleCookie):
"""More lenient version of http.cookies.SimpleCookie""" """More lenient version of http.cookies.SimpleCookie"""
# From https://github.com/python/cpython/blob/v3.10.7/Lib/http/cookies.py # From https://github.com/python/cpython/blob/v3.10.7/Lib/http/cookies.py
_LEGAL_KEY_CHARS = r"\w\d!#%&'~_`><@,:/\$\*\+\-\.\^\|\)\(\?\}\{\=" # We use Morsel's legal key chars to avoid errors on setting values
_LEGAL_VALUE_CHARS = _LEGAL_KEY_CHARS + r"\[\]" _LEGAL_KEY_CHARS = r'\w\d' + re.escape('!#$%&\'*+-.:^_`|~')
_LEGAL_VALUE_CHARS = _LEGAL_KEY_CHARS + re.escape('(),/<=>?@[]{}')
_RESERVED = { _RESERVED = {
"expires", "expires",
@ -1046,25 +1047,17 @@ class LenientSimpleCookie(http.cookies.SimpleCookie):
return super().load(data) return super().load(data)
morsel = None morsel = None
index = 0 for match in self._COOKIE_PATTERN.finditer(data):
length = len(data) if match.group('bad'):
while 0 <= index < length:
match = self._COOKIE_PATTERN.search(data, index)
if not match:
break
index = match.end(0)
if match.group("bad"):
morsel = None morsel = None
continue continue
key, value = match.group("key", "val") key, value = match.group('key', 'val')
if key[0] == "$": is_attribute = False
if morsel is not None: if key.startswith('$'):
morsel[key[1:]] = True key = key[1:]
continue is_attribute = True
lower_key = key.lower() lower_key = key.lower()
if lower_key in self._RESERVED: if lower_key in self._RESERVED:
@ -1081,6 +1074,9 @@ class LenientSimpleCookie(http.cookies.SimpleCookie):
morsel[key] = value morsel[key] = value
elif is_attribute:
morsel = None
elif value is not None: elif value is not None:
morsel = self.get(key, http.cookies.Morsel()) morsel = self.get(key, http.cookies.Morsel())
real_value, coded_value = self.value_decode(value) real_value, coded_value = self.value_decode(value)

Loading…
Cancel
Save