[Zope-Checkins] SVN: Zope/trunk/ merged fix from
tseaver-collector_1460 branch
Yvo Schubbe
y.2005- at wcm-solutions.de
Sat Apr 2 04:11:40 EST 2005
Log message for revision 29837:
merged fix from tseaver-collector_1460 branch
Changed:
U Zope/trunk/doc/CHANGES.txt
U Zope/trunk/lib/python/AccessControl/ZopeGuards.py
U Zope/trunk/lib/python/AccessControl/tests/testZopeGuards.py
-=-
Modified: Zope/trunk/doc/CHANGES.txt
===================================================================
--- Zope/trunk/doc/CHANGES.txt 2005-04-02 09:08:42 UTC (rev 29836)
+++ Zope/trunk/doc/CHANGES.txt 2005-04-02 09:11:40 UTC (rev 29837)
@@ -72,6 +72,8 @@
Bugs fixed
+ - Collector #1460: guarded_apply was too restrictive.
+
- OFS.Traversable still used a string 'NotFound' exception.
- ZPublisher would fail to recognize a XML-RPC request if the
Modified: Zope/trunk/lib/python/AccessControl/ZopeGuards.py
===================================================================
--- Zope/trunk/lib/python/AccessControl/ZopeGuards.py 2005-04-02 09:08:42 UTC (rev 29836)
+++ Zope/trunk/lib/python/AccessControl/ZopeGuards.py 2005-04-02 09:11:40 UTC (rev 29837)
@@ -155,17 +155,44 @@
# See comment in SimpleObjectPolicies for an explanation of what the
# dicts below actually mean.
-ContainerAssertions[type({})] = {
+_dict_white_list = {
'clear':1, 'copy':1, 'fromkeys':1, 'get':get_dict_get, 'has_key':1,
'items':1, 'iteritems':1, 'keys':1,
'iterkeys': get_iter, 'itervalues':get_iter,
'pop':get_dict_pop, 'popitem':1, 'setdefault':1, 'update':1, 'values':1}
-ContainerAssertions[type([])] = {
+def _check_dict_access(name, value):
+ # Check whether value is a dict method
+ self = getattr(value, '__self__', None)
+ if self is None: # item
+ return 1
+ # Disallow spoofing
+ if type(self) is not dict:
+ return 0
+ if getattr(value, '__name__', None) != name:
+ return 0
+ return _dict_white_list.get(name, 0)
+
+ContainerAssertions[type({})] = _check_dict_access
+
+_list_white_list = {
'append':1, 'count':1, 'extend':1, 'index':1, 'insert':1,
'pop':get_list_pop, 'remove':1, 'reverse':1, 'sort':1}
+def _check_list_access(name, value):
+ # Check whether value is a dict method
+ self = getattr(value, '__self__', None)
+ if self is None: # item
+ return 1
+ # Disallow spoofing
+ if type(self) is not list:
+ return 0
+ if getattr(value, '__name__', None) != name:
+ return 0
+ return _list_white_list.get(name, 0)
+ContainerAssertions[type([])] = _check_list_access
+
# This implementation of a "safe" iterator uses a global guard()
# function to implement the actual guard. This check is defined as a
# global so that it can delay imports of some module to avoid circular
Modified: Zope/trunk/lib/python/AccessControl/tests/testZopeGuards.py
===================================================================
--- Zope/trunk/lib/python/AccessControl/tests/testZopeGuards.py 2005-04-02 09:08:42 UTC (rev 29836)
+++ Zope/trunk/lib/python/AccessControl/tests/testZopeGuards.py 2005-04-02 09:11:40 UTC (rev 29837)
@@ -404,6 +404,44 @@
untouched.sort()
self.fail("Unexercised wrappers: %r" % untouched)
+ def test_dict_access(self):
+ from RestrictedPython.tests import verify
+
+ SIMPLE_DICT_ACCESS_SCRIPT = """
+def foo(text):
+ return text
+
+kw = {'text':'baz'}
+print foo(**kw)
+
+kw = {'text':True}
+print foo(**kw)
+"""
+ code, its_globals = self._compile_str(SIMPLE_DICT_ACCESS_SCRIPT, 'x')
+ verify.verify(code)
+
+ sm = SecurityManager()
+ old = self.setSecurityManager(sm)
+ try:
+ exec code in its_globals
+ finally:
+ self.setSecurityManager(old)
+
+ self.assertEqual(its_globals['_print'](),
+ 'baz\nTrue\n')
+
+ def _compile_str(self, text, name):
+ from RestrictedPython import compile_restricted
+ from AccessControl.ZopeGuards import get_safe_globals, guarded_getattr
+
+ code = compile_restricted(text, name, 'exec')
+
+ g = get_safe_globals()
+ g['_getattr_'] = guarded_getattr
+ g['__debug__'] = 1 # so assert statements are active
+ g['__name__'] = __name__ # so classes can be defined in the script
+ return code, g
+
# Compile code in fname, as restricted Python. Return the
# compiled code, and a safe globals dict for running it in.
# fname is the string name of a Python file; it must be found
@@ -413,14 +451,9 @@
from AccessControl.ZopeGuards import get_safe_globals, guarded_getattr
fn = os.path.join( _HERE, fname)
- code = compile_restricted(open(fn).read(), fn, 'exec')
+ text = open(fn).read()
+ return self._compile_str(text, fn)
- g = get_safe_globals()
- g['_getattr_'] = guarded_getattr
- g['__debug__'] = 1 # so assert statements are active
- g['__name__'] = __name__ # so classes can be defined in the script
- return code, g
-
# d is a dict, the globals for execution or our safe builtins.
# The callable values which aren't the same as the corresponding
# entries in __builtin__ are wrapped in a FuncWrapper, so we can
More information about the Zope-Checkins
mailing list