summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStephan Richter <stephan.richter@gmail.com>2013-03-10 21:19:38 -0400
committerStephan Richter <stephan.richter@gmail.com>2013-03-10 21:19:38 -0400
commit19f01d59f4b4e7dac9a714d202c5f44e7a850701 (patch)
treedcafa1ee03ee5f5572ac3c94ea3214c64f6920a8 /src
parentded617955b2dba40a1739cf27d155e7da3608644 (diff)
downloadzope-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')
-rw-r--r--src/zope/security/proxy.py34
-rw-r--r--src/zope/security/tests/test_proxy.py2
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