Skip to content

Commit

Permalink
clean up docs
Browse files Browse the repository at this point in the history
  • Loading branch information
davidism committed Feb 14, 2023
1 parent fe899d0 commit 09449ee
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 16 deletions.
8 changes: 4 additions & 4 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ Unreleased
the requested size in one ``read`` call. :issue:`2558`
- A cookie header that starts with ``=`` is treated as an empty key and discarded,
rather than stripping the leading ``==``.
- Specify a maximum number of multipart parts, default 100, after
which a RequestEntityTooLarge exception is raised on parsing. The
mitigates a DOS attack whereby a larger number file/form parts are
sent resulting in a heavy parsing cost.
- Specify a maximum number of multipart parts, default 1000, after which a
``RequestEntityTooLarge`` exception is raised on parsing. This mitigates a DoS
attack where a larger number of form/file parts would result in disproportionate
resource use.


Version 2.2.2
Expand Down
11 changes: 5 additions & 6 deletions src/werkzeug/formparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,10 +179,8 @@ class FormDataParser:
:param cls: an optional dict class to use. If this is not specified
or `None` the default :class:`MultiDict` is used.
:param silent: If set to False parsing errors will not be caught.
:param max_form_parts: the maximum number of parts to be accepted for the
multipart data sent. If this is exceeded an
:exc:`~exceptions.RequestEntityTooLarge` exception
is raised.
:param max_form_parts: The maximum number of parts to be parsed. If this is
exceeded, a :exc:`~exceptions.RequestEntityTooLarge` exception is raised.
"""

def __init__(
Expand All @@ -194,6 +192,7 @@ def __init__(
max_content_length: t.Optional[int] = None,
cls: t.Optional[t.Type[MultiDict]] = None,
silent: bool = True,
*,
max_form_parts: t.Optional[int] = None,
) -> None:
if stream_factory is None:
Expand All @@ -204,13 +203,13 @@ def __init__(
self.errors = errors
self.max_form_memory_size = max_form_memory_size
self.max_content_length = max_content_length
self.max_form_parts = max_form_parts

if cls is None:
cls = MultiDict

self.cls = cls
self.silent = silent
self.max_form_parts = max_form_parts

def get_parse_func(
self, mimetype: str, options: t.Dict[str, str]
Expand Down Expand Up @@ -419,7 +418,7 @@ def parse(
)

parser = MultipartDecoder(
boundary, self.max_form_memory_size, self.max_form_parts
boundary, self.max_form_memory_size, max_parts=self.max_form_parts
)

fields = []
Expand Down
1 change: 1 addition & 0 deletions src/werkzeug/sansio/multipart.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ def __init__(
self,
boundary: bytes,
max_form_memory_size: Optional[int] = None,
*,
max_parts: Optional[int] = None,
) -> None:
self.buffer = bytearray()
Expand Down
9 changes: 3 additions & 6 deletions src/werkzeug/wrappers/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,9 @@ class Request(_SansIORequest):
#: .. versionadded:: 0.5
max_form_memory_size: t.Optional[int] = None

#: the maximum number of multipart parts. This is forwarded to teh
#: form data parsing function (:func:`parse_form_data`). When the
#: :attr:`form` or :attr:`files` attribute is accessed and the
#: parsing fails because more parts than the specified value is
#: transmitted a :exc:`~werkzeug.exceptions.RequestEntityTooLarge`
#: exception is raised.
#: The maximum number of multipart parts to parse, passed to
#: :attr:`form_data_parser_class`. Parsing form data with more than this
#: many parts will raise :exc:`~.RequestEntityTooLarge`.
#:
#: .. versionadded:: 2.2.3
max_form_parts = 1000
Expand Down

0 comments on commit 09449ee

Please sign in to comment.