Skip to content

Commit

Permalink
Merge pull request #2967 from hirokiky/fix23070
Browse files Browse the repository at this point in the history
Fixed #23070 -- not to break the debug page by callable setting with __slots__
  • Loading branch information
ubernostrum committed Jul 26, 2014
2 parents 6eed751 + d088986 commit 6305878
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 2 deletions.
16 changes: 15 additions & 1 deletion django/views/debug.py
Expand Up @@ -33,6 +33,19 @@ def linebreak_iter(template_source):
yield len(template_source) + 1


class CallableSettingWrapper(object):
""" Object to wrap callable appearing in settings
* Not to call in the debug page (#21345).
* Not to break the debug page if the callable forbidding to set attributes (#23070).
"""
def __init__(self, callable_setting):
self._wrapped = callable_setting

def __repr__(self):
return repr(self._wrapped)


def cleanse_setting(key, value):
"""Cleanse an individual setting key/value of sensitive content.
Expand All @@ -52,7 +65,8 @@ def cleanse_setting(key, value):
cleansed = value

if callable(cleansed):
cleansed.do_not_call_in_templates = True
# For fixing #21345 and #23070
cleansed = CallableSettingWrapper(cleansed)

return cleansed

Expand Down
32 changes: 31 additions & 1 deletion tests/view_tests/tests/test_debug.py
Expand Up @@ -20,7 +20,7 @@
from django.test.utils import override_with_test_loader
from django.utils.encoding import force_text, force_bytes
from django.utils import six
from django.views.debug import ExceptionReporter
from django.views.debug import CallableSettingWrapper, ExceptionReporter

from .. import BrokenException, except_args
from ..views import (sensitive_view, non_sensitive_view, paranoid_view,
Expand All @@ -29,6 +29,21 @@
multivalue_dict_key_error)


class CallableSettingWrapperTests(TestCase):
""" Unittests for CallableSettingWrapper
"""
def test_repr(self):
class WrappedCallable(object):
def __repr__(self):
return "repr from the wrapped callable"

def __call__(self):
pass

actual = repr(CallableSettingWrapper(WrappedCallable()))
self.assertEqual(actual, "repr from the wrapped callable")


@override_settings(DEBUG=True, TEMPLATE_DEBUG=True,
ROOT_URLCONF="view_tests.urls")
class DebugViewTests(TestCase):
Expand Down Expand Up @@ -660,6 +675,21 @@ def callable_setting():
response = self.client.get('/raises500/')
self.assertNotContains(response, "This should not be displayed", status_code=500)

def test_callable_settings_forbidding_to_set_attributes(self):
"""
Callable settings which forbid to set attributes should not break
the debug page (#23070).
"""
class CallableSettingWithSlots(object):
__slots__ = []

def __call__(self):
return "This should not be displayed"

with self.settings(DEBUG=True, WITH_SLOTS=CallableSettingWithSlots()):
response = self.client.get('/raises500/')
self.assertNotContains(response, "This should not be displayed", status_code=500)

def test_dict_setting_with_non_str_key(self):
"""
A dict setting containing a non-string key should not break the
Expand Down

0 comments on commit 6305878

Please sign in to comment.