diff options
author | Stephan Richter <stephan.richter@gmail.com> | 2013-03-10 21:19:38 -0400 |
---|---|---|
committer | Stephan Richter <stephan.richter@gmail.com> | 2013-03-10 21:19:38 -0400 |
commit | 19f01d59f4b4e7dac9a714d202c5f44e7a850701 (patch) | |
tree | dcafa1ee03ee5f5572ac3c94ea3214c64f6920a8 /src/zope | |
parent | ded617955b2dba40a1739cf27d155e7da3608644 (diff) | |
download | zope-security-19f01d59f4b4e7dac9a714d202c5f44e7a850701.tar.gz |
Implemented proper handling when __str__ and __repr__ are not allowed. In
those cases we do not want to fail with a cryptic error, but provide an
informative output.
Diffstat (limited to 'src/zope')
-rw-r--r-- | src/zope/security/proxy.py | 34 | ||||
-rw-r--r-- | src/zope/security/tests/test_proxy.py | 2 |
2 files changed, 32 insertions, 4 deletions
diff --git a/src/zope/security/proxy.py b/src/zope/security/proxy.py index 0c228af..48892bf 100644 --- a/src/zope/security/proxy.py +++ b/src/zope/security/proxy.py @@ -16,9 +16,10 @@ __docformat__ = 'restructuredtext' import functools - +import sys from zope.proxy import PyProxyBase +from zope.security.interfaces import ForbiddenAttribute def _check_name(meth): @@ -45,6 +46,15 @@ def _check_name_inplace(meth): return ProxyPy(getattr(wrapped, x_name)(*args, **kw), checker) return functools.update_wrapper(_wrapper, meth) +def _fmt_address(obj): + # Try to replicate PyString_FromString("%p", obj), which actually uses + # the platform sprintf(buf, "%p", obj), which we cannot access from Python + # directly (and ctypes seems like overkill). + if sys.platform == 'win32': + return '0x%08x' % id(obj) + else: + return '0x%0x' % id(obj) + class ProxyPy(PyProxyBase): __slots__ = ('_wrapped', '_checker') @@ -96,6 +106,24 @@ class ProxyPy(PyProxyBase): wrapped = super(PyProxyBase, self).__getattribute__('_wrapped') return hash(wrapped) + def __str__(self): + try: + return _check_name(PyProxyBase.__str__)(self) + except ForbiddenAttribute: + wrapped = super(PyProxyBase, self).__getattribute__('_wrapped') + return '<security proxied %s.%s instance at %s>' %( + wrapped.__class__.__module__, wrapped.__class__.__name__, + _fmt_address(wrapped)) + + def __repr__(self): + try: + return _check_name(PyProxyBase.__repr__)(self) + except ForbiddenAttribute: + wrapped = super(PyProxyBase, self).__getattribute__('_wrapped') + return '<security proxied %s.%s instance at %s>' %( + wrapped.__class__.__module__, wrapped.__class__.__name__, + _fmt_address(wrapped)) + def __nonzero__(self): # no check wrapped = super(PyProxyBase, self).__getattribute__('_wrapped') @@ -103,8 +131,8 @@ class ProxyPy(PyProxyBase): __bool__ = __nonzero__ for name in ['__call__', - '__repr__', - '__str__', + #'__repr__', + #'__str__', '__unicode__', '__reduce__', '__reduce_ex__', diff --git a/src/zope/security/tests/test_proxy.py b/src/zope/security/tests/test_proxy.py index 231c3c3..7408419 100644 --- a/src/zope/security/tests/test_proxy.py +++ b/src/zope/security/tests/test_proxy.py @@ -1378,7 +1378,7 @@ class DummyChecker(object): self._checked = name if name not in self._allowed: if self._raising is not None: - raise self._raising() + raise self._raising(name) check_getattr = check_setattr = check def proxy(self, value): self._proxied = value |