|
7 | 7 | from email.utils import formatdate
|
8 | 8 | from urllib.parse import (
|
9 | 9 | ParseResult, SplitResult, _coerce_args, _splitnetloc, _splitparams,
|
10 |
| - scheme_chars, unquote, urlencode as original_urlencode, uses_params, |
| 10 | + scheme_chars, urlencode as original_urlencode, uses_params, |
11 | 11 | )
|
12 | 12 |
|
13 | 13 | from django.utils.datastructures import MultiValueDict
|
@@ -343,78 +343,6 @@ def _url_has_allowed_host_and_scheme(url, allowed_hosts, require_https=False):
|
343 | 343 | (not scheme or scheme in valid_schemes))
|
344 | 344 |
|
345 | 345 |
|
346 |
| -# TODO: Remove when dropping support for PY37. |
347 |
| -def parse_qsl( |
348 |
| - qs, keep_blank_values=False, strict_parsing=False, encoding='utf-8', |
349 |
| - errors='replace', max_num_fields=None, |
350 |
| -): |
351 |
| - """ |
352 |
| - Return a list of key/value tuples parsed from query string. |
353 |
| -
|
354 |
| - Backport of urllib.parse.parse_qsl() from Python 3.8. |
355 |
| - Copyright (C) 2020 Python Software Foundation (see LICENSE.python). |
356 |
| -
|
357 |
| - ---- |
358 |
| -
|
359 |
| - Parse a query given as a string argument. |
360 |
| -
|
361 |
| - Arguments: |
362 |
| -
|
363 |
| - qs: percent-encoded query string to be parsed |
364 |
| -
|
365 |
| - keep_blank_values: flag indicating whether blank values in |
366 |
| - percent-encoded queries should be treated as blank strings. A |
367 |
| - true value indicates that blanks should be retained as blank |
368 |
| - strings. The default false value indicates that blank values |
369 |
| - are to be ignored and treated as if they were not included. |
370 |
| -
|
371 |
| - strict_parsing: flag indicating what to do with parsing errors. If false |
372 |
| - (the default), errors are silently ignored. If true, errors raise a |
373 |
| - ValueError exception. |
374 |
| -
|
375 |
| - encoding and errors: specify how to decode percent-encoded sequences |
376 |
| - into Unicode characters, as accepted by the bytes.decode() method. |
377 |
| -
|
378 |
| - max_num_fields: int. If set, then throws a ValueError if there are more |
379 |
| - than n fields read by parse_qsl(). |
380 |
| -
|
381 |
| - Returns a list, as G-d intended. |
382 |
| - """ |
383 |
| - qs, _coerce_result = _coerce_args(qs) |
384 |
| - |
385 |
| - # If max_num_fields is defined then check that the number of fields is less |
386 |
| - # than max_num_fields. This prevents a memory exhaustion DOS attack via |
387 |
| - # post bodies with many fields. |
388 |
| - if max_num_fields is not None: |
389 |
| - num_fields = 1 + qs.count('&') + qs.count(';') |
390 |
| - if max_num_fields < num_fields: |
391 |
| - raise ValueError('Max number of fields exceeded') |
392 |
| - |
393 |
| - pairs = [s2 for s1 in qs.split('&') for s2 in s1.split(';')] |
394 |
| - r = [] |
395 |
| - for name_value in pairs: |
396 |
| - if not name_value and not strict_parsing: |
397 |
| - continue |
398 |
| - nv = name_value.split('=', 1) |
399 |
| - if len(nv) != 2: |
400 |
| - if strict_parsing: |
401 |
| - raise ValueError("bad query field: %r" % (name_value,)) |
402 |
| - # Handle case of a control-name with no equal sign. |
403 |
| - if keep_blank_values: |
404 |
| - nv.append('') |
405 |
| - else: |
406 |
| - continue |
407 |
| - if len(nv[1]) or keep_blank_values: |
408 |
| - name = nv[0].replace('+', ' ') |
409 |
| - name = unquote(name, encoding=encoding, errors=errors) |
410 |
| - name = _coerce_result(name) |
411 |
| - value = nv[1].replace('+', ' ') |
412 |
| - value = unquote(value, encoding=encoding, errors=errors) |
413 |
| - value = _coerce_result(value) |
414 |
| - r.append((name, value)) |
415 |
| - return r |
416 |
| - |
417 |
| - |
418 | 346 | def escape_leading_slashes(url):
|
419 | 347 | """
|
420 | 348 | If redirecting to an absolute path (two leading slashes), a slash must be
|
|
0 commit comments