Log message for revision 29821: Branch for fixes for Collector #1460. Changed: A Zope/branches/tseaver-collector_1460/ U Zope/branches/tseaver-collector_1460/lib/python/AccessControl/ZopeGuards.py U Zope/branches/tseaver-collector_1460/lib/python/AccessControl/tests/testZopeGuards.py
-=- Copied: Zope/branches/tseaver-collector_1460 (from rev 29817, Zope/trunk) Modified: Zope/branches/tseaver-collector_1460/lib/python/AccessControl/ZopeGuards.py =================================================================== --- Zope/trunk/lib/python/AccessControl/ZopeGuards.py 2005-04-01 22:57:54 UTC (rev 29817) +++ Zope/branches/tseaver-collector_1460/lib/python/AccessControl/ZopeGuards.py 2005-04-01 23:36:13 UTC (rev 29821) @@ -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/branches/tseaver-collector_1460/lib/python/AccessControl/tests/testZopeGuards.py =================================================================== --- Zope/trunk/lib/python/AccessControl/tests/testZopeGuards.py 2005-04-01 22:57:54 UTC (rev 29817) +++ Zope/branches/tseaver-collector_1460/lib/python/AccessControl/tests/testZopeGuards.py 2005-04-01 23:36:13 UTC (rev 29821) @@ -404,6 +404,45 @@ 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) + import pdb; pdb.set_trace() + 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 +452,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 _______________________________________________ Zope-Checkins maillist - Zope-Checkins@zope.org http://mail.zope.org/mailman/listinfo/zope-checkins