summaryrefslogtreecommitdiff
path: root/django/http/request.py
diff options
context:
space:
mode:
authorNick Pope <nick.pope@flightdataservices.com>2019-11-04 12:06:49 +0000
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2020-09-03 14:24:42 +0200
commitfd209f62f1d83233cc634443cfac5ee4328d98b8 (patch)
tree476f3b0c54339831288823b75afa74822198188a /django/http/request.py
parent8d59075184f4cd2852b374359850ff7aeb412ec1 (diff)
downloaddjango-fd209f62f1d83233cc634443cfac5ee4328d98b8.tar.gz
Refs #21231 -- Backport urllib.parse.parse_qsl() from Python 3.8.
Diffstat (limited to 'django/http/request.py')
-rw-r--r--django/http/request.py31
1 files changed, 25 insertions, 6 deletions
diff --git a/django/http/request.py b/django/http/request.py
index 083bf2d80f..addcf05329 100644
--- a/django/http/request.py
+++ b/django/http/request.py
@@ -4,12 +4,12 @@ import copy
import warnings
from io import BytesIO
from itertools import chain
-from urllib.parse import quote, urlencode, urljoin, urlsplit
+from urllib.parse import parse_qsl, quote, urlencode, urljoin, urlsplit
from django.conf import settings
from django.core import signing
from django.core.exceptions import (
- DisallowedHost, ImproperlyConfigured, RequestDataTooBig,
+ DisallowedHost, ImproperlyConfigured, RequestDataTooBig, TooManyFieldsSent,
)
from django.core.files import uploadhandler
from django.http.multipartparser import MultiPartParser, MultiPartParserError
@@ -19,11 +19,20 @@ from django.utils.datastructures import (
from django.utils.deprecation import RemovedInDjango40Warning
from django.utils.encoding import escape_uri_path, iri_to_uri
from django.utils.functional import cached_property
-from django.utils.http import is_same_domain, limited_parse_qsl
+from django.utils.http import is_same_domain
+from django.utils.inspect import func_supports_parameter
from django.utils.regex_helper import _lazy_re_compile
from .multipartparser import parse_header
+# TODO: Remove when dropping support for PY37. inspect.signature() is used to
+# detect whether the max_num_fields argument is available as this security fix
+# was backported to Python 3.6.8 and 3.7.2, and may also have been applied by
+# downstream package maintainers to other versions in their repositories.
+if func_supports_parameter(parse_qsl, 'max_num_fields'):
+ from django.utils.http import parse_qsl
+
+
RAISE_ERROR = object()
host_validation_re = _lazy_re_compile(r"^([a-z0-9.-]+|\[[a-f0-9]*:[a-f0-9\.:]+\])(:\d+)?$")
@@ -446,8 +455,8 @@ class QueryDict(MultiValueDict):
query_string = query_string or ''
parse_qsl_kwargs = {
'keep_blank_values': True,
- 'fields_limit': settings.DATA_UPLOAD_MAX_NUMBER_FIELDS,
'encoding': self.encoding,
+ 'max_num_fields': settings.DATA_UPLOAD_MAX_NUMBER_FIELDS,
}
if isinstance(query_string, bytes):
# query_string normally contains URL-encoded data, a subset of ASCII.
@@ -456,8 +465,18 @@ class QueryDict(MultiValueDict):
except UnicodeDecodeError:
# ... but some user agents are misbehaving :-(
query_string = query_string.decode('iso-8859-1')
- for key, value in limited_parse_qsl(query_string, **parse_qsl_kwargs):
- self.appendlist(key, value)
+ try:
+ for key, value in parse_qsl(query_string, **parse_qsl_kwargs):
+ self.appendlist(key, value)
+ except ValueError as e:
+ # ValueError can also be raised if the strict_parsing argument to
+ # parse_qsl() is True. As that is not used by Django, assume that
+ # the exception was raised by exceeding the value of max_num_fields
+ # instead of fragile checks of exception message strings.
+ raise TooManyFieldsSent(
+ 'The number of GET/POST parameters exceeded '
+ 'settings.DATA_UPLOAD_MAX_NUMBER_FIELDS.'
+ ) from e
self._mutable = mutable
@classmethod