Skip to content

Commit

Permalink
add BadRequestKeyError.show_exception
Browse files Browse the repository at this point in the history
  • Loading branch information
davidism committed Jun 25, 2019
1 parent 18d294e commit 2719776
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 6 deletions.
5 changes: 5 additions & 0 deletions CHANGES.rst
Expand Up @@ -9,6 +9,11 @@ Unreleased
:issue:`1551`
- Fix a C assertion failure in debug builds of some Python 2.7
releases. :issue:`1553`
- :class:`~exceptions.BadRequestKeyError` adds the ``KeyError``
message to the description if ``e.show_exception`` is set to
``True``. This is a more secure default than the original 0.15.0
behavior and makes it easier to control without losing information.
(:pr:`1592`)


Version 0.15.4
Expand Down
19 changes: 13 additions & 6 deletions src/werkzeug/exceptions.py
Expand Up @@ -96,14 +96,21 @@ def wrap(cls, exception, name=None):
The first argument to the class will be passed to the
wrapped ``exception``, the rest to the HTTP exception. If
``self.args`` is not empty, the wrapped exception message is
added to the HTTP exception description.
``e.args`` is not empty and ``e.show_exception`` is ``True``,
the wrapped exception message is added to the HTTP error
description.
.. versionchanged:: 0.15
.. versionchanged:: 1.0.0
The ``show_exception`` attribute controls whether the
description includes the wrapped exception message.
.. versionchanged:: 0.15.0
The description includes the wrapped exception message.
"""

class newcls(cls, exception):
show_exception = False

def __init__(self, arg=None, *args, **kwargs):
super(cls, self).__init__(*args, **kwargs)

Expand All @@ -115,7 +122,7 @@ def __init__(self, arg=None, *args, **kwargs):
def get_description(self, environ=None):
out = super(cls, self).get_description(environ=environ)

if self.args:
if self.show_exception and self.args:
out += "<p><pre><code>{}: {}</code></pre></p>".format(
exception.__name__, escape(exception.__str__(self))
)
Expand Down Expand Up @@ -765,8 +772,8 @@ def abort(status, *args, **kwargs):
_aborter = Aborter()


#: an exception that is used internally to signal both a key error and a
#: bad request. Used by a lot of the datastructures.
#: An exception that is used to signal both a :exc:`KeyError` and a
#: :exc:`BadRequest`. Used by many of the datastructures.
BadRequestKeyError = BadRequest.wrap(KeyError)

# imported here because of circular dependencies of werkzeug.utils
Expand Down
3 changes: 3 additions & 0 deletions tests/test_datastructures.py
Expand Up @@ -583,11 +583,14 @@ def test_get_description(self):
with pytest.raises(BadRequestKeyError) as exc_info:
data["baz"]

assert "baz" not in exc_info.value.get_description()
exc_info.value.show_exception = True
assert "baz" in exc_info.value.get_description()

with pytest.raises(BadRequestKeyError) as exc_info:
data.pop("baz")

exc_info.value.show_exception = True
assert "baz" in exc_info.value.get_description()
exc_info.value.args = ()
assert "baz" not in exc_info.value.get_description()
Expand Down

0 comments on commit 2719776

Please sign in to comment.