This commit is contained in:
ton
2024-10-07 10:13:40 +07:00
parent aa1631742f
commit 3a7d696db6
9729 changed files with 1832837 additions and 161742 deletions

View File

@@ -525,9 +525,13 @@ def urlunsplit(components):
empty query; the RFC states that these are equivalent)."""
scheme, netloc, url, query, fragment, _coerce_result = (
_coerce_args(*components))
if netloc or (scheme and scheme in uses_netloc and url[:2] != '//'):
if netloc:
if url and url[:1] != '/': url = '/' + url
url = '//' + (netloc or '') + url
url = '//' + netloc + url
elif url[:2] == '//':
url = '//' + url
elif scheme and scheme in uses_netloc and (not url or url[:1] == '/'):
url = '//' + url
if scheme:
url = scheme + ':' + url
if query:
@@ -763,42 +767,48 @@ def parse_qsl(qs, keep_blank_values=False, strict_parsing=False,
Returns a list, as G-d intended.
"""
qs, _coerce_result = _coerce_args(qs)
separator, _ = _coerce_args(separator)
if not separator or (not isinstance(separator, (str, bytes))):
if not separator or not isinstance(separator, (str, bytes)):
raise ValueError("Separator must be of type string or bytes.")
if isinstance(qs, str):
if not isinstance(separator, str):
separator = str(separator, 'ascii')
eq = '='
def _unquote(s):
return unquote_plus(s, encoding=encoding, errors=errors)
else:
if not qs:
return []
# Use memoryview() to reject integers and iterables,
# acceptable by the bytes constructor.
qs = bytes(memoryview(qs))
if isinstance(separator, str):
separator = bytes(separator, 'ascii')
eq = b'='
def _unquote(s):
return unquote_to_bytes(s.replace(b'+', b' '))
if not qs:
return []
# If max_num_fields is defined then check that the number of fields
# is less than max_num_fields. This prevents a memory exhaustion DOS
# attack via post bodies with many fields.
if max_num_fields is not None:
num_fields = 1 + qs.count(separator) if qs else 0
num_fields = 1 + qs.count(separator)
if max_num_fields < num_fields:
raise ValueError('Max number of fields exceeded')
r = []
query_args = qs.split(separator) if qs else []
for name_value in query_args:
if not name_value and not strict_parsing:
continue
nv = name_value.split('=', 1)
if len(nv) != 2:
if strict_parsing:
for name_value in qs.split(separator):
if name_value or strict_parsing:
name, has_eq, value = name_value.partition(eq)
if not has_eq and strict_parsing:
raise ValueError("bad query field: %r" % (name_value,))
# Handle case of a control-name with no equal sign
if keep_blank_values:
nv.append('')
else:
continue
if len(nv[1]) or keep_blank_values:
name = nv[0].replace('+', ' ')
name = unquote(name, encoding=encoding, errors=errors)
name = _coerce_result(name)
value = nv[1].replace('+', ' ')
value = unquote(value, encoding=encoding, errors=errors)
value = _coerce_result(value)
r.append((name, value))
if value or keep_blank_values:
name = _unquote(name)
value = _unquote(value)
r.append((name, value))
return r
def unquote_plus(string, encoding='utf-8', errors='replace'):