[Checkins] SVN: RestrictedPython/trunk/ Synchronize Zope3's
RestrictedPython (which has been set free as an egg) with
Philipp von Weitershausen
philikon at philikon.de
Mon Jun 4 13:40:04 EDT 2007
Log message for revision 76322:
Synchronize Zope3's RestrictedPython (which has been set free as an egg) with
the actually more evolved RestrictedPython from the Zope 2 tree.
Changed:
U RestrictedPython/trunk/README.txt
U RestrictedPython/trunk/src/RestrictedPython/Eval.py
U RestrictedPython/trunk/src/RestrictedPython/Guards.py
U RestrictedPython/trunk/src/RestrictedPython/Limits.py
U RestrictedPython/trunk/src/RestrictedPython/MutatingWalker.py
U RestrictedPython/trunk/src/RestrictedPython/PrintCollector.py
U RestrictedPython/trunk/src/RestrictedPython/RCompile.py
U RestrictedPython/trunk/src/RestrictedPython/RestrictionMutator.py
U RestrictedPython/trunk/src/RestrictedPython/SelectCompiler.py
U RestrictedPython/trunk/src/RestrictedPython/Utilities.py
U RestrictedPython/trunk/src/RestrictedPython/__init__.py
A RestrictedPython/trunk/src/RestrictedPython/notes.txt
U RestrictedPython/trunk/src/RestrictedPython/tests/before_and_after.py
A RestrictedPython/trunk/src/RestrictedPython/tests/before_and_after24.py
U RestrictedPython/trunk/src/RestrictedPython/tests/restricted_module.py
U RestrictedPython/trunk/src/RestrictedPython/tests/security_in_syntax.py
U RestrictedPython/trunk/src/RestrictedPython/tests/testRestrictions.py
U RestrictedPython/trunk/src/RestrictedPython/tests/verify.py
-=-
Modified: RestrictedPython/trunk/README.txt
===================================================================
--- RestrictedPython/trunk/README.txt 2007-06-04 16:57:20 UTC (rev 76321)
+++ RestrictedPython/trunk/README.txt 2007-06-04 17:40:03 UTC (rev 76322)
@@ -8,6 +8,14 @@
********
==================
+3.4.0 (2007/06/04)
+==================
+
+- RestrictedPython now has its own release cycle as a separate egg.
+
+- Synchronized with RestrictedPython from Zope 2 tree.
+
+==================
3.2.0 (2006/01/05)
==================
Modified: RestrictedPython/trunk/src/RestrictedPython/Eval.py
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/Eval.py 2007-06-04 16:57:20 UTC (rev 76321)
+++ RestrictedPython/trunk/src/RestrictedPython/Eval.py 2007-06-04 17:40:03 UTC (rev 76322)
@@ -1,9 +1,9 @@
##############################################################################
#
-# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
+# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
Modified: RestrictedPython/trunk/src/RestrictedPython/Guards.py
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/Guards.py 2007-06-04 16:57:20 UTC (rev 76321)
+++ RestrictedPython/trunk/src/RestrictedPython/Guards.py 2007-06-04 17:40:03 UTC (rev 76322)
@@ -1,9 +1,9 @@
##############################################################################
#
-# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
+# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
Modified: RestrictedPython/trunk/src/RestrictedPython/Limits.py
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/Limits.py 2007-06-04 16:57:20 UTC (rev 76321)
+++ RestrictedPython/trunk/src/RestrictedPython/Limits.py 2007-06-04 17:40:03 UTC (rev 76322)
@@ -1,9 +1,9 @@
##############################################################################
#
-# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
+# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
Modified: RestrictedPython/trunk/src/RestrictedPython/MutatingWalker.py
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/MutatingWalker.py 2007-06-04 16:57:20 UTC (rev 76321)
+++ RestrictedPython/trunk/src/RestrictedPython/MutatingWalker.py 2007-06-04 17:40:03 UTC (rev 76322)
@@ -1,9 +1,9 @@
##############################################################################
#
-# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
+# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
Modified: RestrictedPython/trunk/src/RestrictedPython/PrintCollector.py
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/PrintCollector.py 2007-06-04 16:57:20 UTC (rev 76321)
+++ RestrictedPython/trunk/src/RestrictedPython/PrintCollector.py 2007-06-04 17:40:03 UTC (rev 76322)
@@ -1,9 +1,9 @@
##############################################################################
#
-# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
+# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
Modified: RestrictedPython/trunk/src/RestrictedPython/RCompile.py
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/RCompile.py 2007-06-04 16:57:20 UTC (rev 76321)
+++ RestrictedPython/trunk/src/RestrictedPython/RCompile.py 2007-06-04 17:40:03 UTC (rev 76322)
@@ -1,9 +1,9 @@
##############################################################################
#
-# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
+# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
@@ -46,6 +46,8 @@
# See concrete subclasses below.
def __init__(self, source, filename):
+ if source:
+ source = '\n'.join(source.splitlines())
self.rm = RestrictionMutator()
AbstractCompileMode.__init__(self, source, filename)
@@ -210,6 +212,8 @@
def __init__(self, p, body, name, filename, globals):
self.params = p
+ if body:
+ body = '\n'.join(body.splitlines())
self.body = body
self.name = name
self.globals = globals or []
@@ -224,12 +228,13 @@
# Stitch the body code into the function.
f.code.nodes = body_code.node.nodes
f.name = self.name
- # Look for a docstring.
- stmt1 = f.code.nodes[0]
- if (isinstance(stmt1, ast.Discard) and
- isinstance(stmt1.expr, ast.Const) and
- isinstance(stmt1.expr.value, str)):
- f.doc = stmt1.expr.value
+ # Look for a docstring, if there are any nodes at all
+ if len(f.code.nodes) > 0:
+ stmt1 = f.code.nodes[0]
+ if (isinstance(stmt1, ast.Discard) and
+ isinstance(stmt1.expr, ast.Const) and
+ isinstance(stmt1.expr.value, str)):
+ f.doc = stmt1.expr.value
# The caller may specify that certain variables are globals
# so that they can be referenced before a local assignment.
# The only known example is the variables context, container,
Modified: RestrictedPython/trunk/src/RestrictedPython/RestrictionMutator.py
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/RestrictionMutator.py 2007-06-04 16:57:20 UTC (rev 76321)
+++ RestrictedPython/trunk/src/RestrictedPython/RestrictionMutator.py 2007-06-04 17:40:03 UTC (rev 76322)
@@ -1,9 +1,9 @@
##############################################################################
#
-# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
+# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
@@ -47,6 +47,7 @@
_getiter_name = ast.Name("_getiter_")
_print_target_name = ast.Name("_print")
_write_name = ast.Name("_write_")
+_inplacevar_name = ast.Name("_inplacevar_")
# Constants.
_None_const = ast.Const(None)
@@ -94,6 +95,9 @@
# Note: "_" *is* allowed.
self.error(node, '"%s" is an invalid variable name because'
' it starts with "_"' % name)
+ if name.endswith('__roles__'):
+ self.error(node, '"%s" is an invalid variable name because '
+ 'it ends with "__roles__".' % name)
if name == "printed":
self.error(node, '"printed" is a reserved name.')
@@ -109,6 +113,9 @@
# Note: "_" *is* allowed.
self.error(node, '"%s" is an invalid attribute name '
'because it starts with "_".' % name)
+ if name.endswith('__roles__'):
+ self.error(node, '"%s" is an invalid attribute name '
+ 'because it ends with "__roles__".' % name)
def prepBody(self, body):
"""Insert code for print at the beginning of the code suite."""
@@ -233,9 +240,9 @@
# for x in expr:
# to
# for x in _getiter(expr):
+ # # Note that visitListCompFor is the same thing.
#
- # Note that visitListCompFor is the same thing. Exactly the same
- # transformation is needed to convert
+ # Also for list comprehensions:
# [... for x in expr ...]
# to
# [... for x in _getiter(expr) ...]
@@ -245,6 +252,15 @@
visitListCompFor = visitFor
+ def visitGenExprFor(self, node, walker):
+ # convert
+ # (... for x in expr ...)
+ # to
+ # (... for x in _getiter(expr) ...)
+ node = walker.defaultVisitNode(node)
+ node.iter = ast.CallFunc(_getiter_name, [node.iter])
+ return node
+
def visitGetattr(self, node, walker):
"""Converts attribute access to a function call.
@@ -359,8 +375,23 @@
This could be a problem if untrusted code got access to a
mutable database object that supports augmented assignment.
"""
- node.node.in_aug_assign = True
- return walker.defaultVisitNode(node)
+ if node.node.__class__.__name__ == 'Name':
+ node = walker.defaultVisitNode(node)
+ newnode = ast.Assign(
+ [ast.AssName(node.node.name, OP_ASSIGN)],
+ ast.CallFunc(
+ _inplacevar_name,
+ [ast.Const(node.op),
+ ast.Name(node.node.name),
+ node.expr,
+ ]
+ ),
+ )
+ newnode.lineno = node.lineno
+ return newnode
+ else:
+ node.node.in_aug_assign = True
+ return walker.defaultVisitNode(node)
def visitImport(self, node, walker):
"""Checks names imported using checkName()."""
Modified: RestrictedPython/trunk/src/RestrictedPython/SelectCompiler.py
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/SelectCompiler.py 2007-06-04 16:57:20 UTC (rev 76321)
+++ RestrictedPython/trunk/src/RestrictedPython/SelectCompiler.py 2007-06-04 17:40:03 UTC (rev 76322)
@@ -1,9 +1,9 @@
##############################################################################
#
-# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
+# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
Modified: RestrictedPython/trunk/src/RestrictedPython/Utilities.py
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/Utilities.py 2007-06-04 16:57:20 UTC (rev 76321)
+++ RestrictedPython/trunk/src/RestrictedPython/Utilities.py 2007-06-04 17:40:03 UTC (rev 76322)
@@ -1,9 +1,9 @@
##############################################################################
#
-# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
+# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
@@ -13,8 +13,7 @@
__version__='$Revision: 1.7 $'[11:-2]
-import string, math, random
-import DocumentTemplate.sequence
+import string, math, random, sets
utility_builtins = {}
@@ -22,13 +21,21 @@
utility_builtins['math'] = math
utility_builtins['random'] = random
utility_builtins['whrandom'] = random
-utility_builtins['sequence'] = DocumentTemplate.sequence
+utility_builtins['sets'] = sets
try:
import DateTime
utility_builtins['DateTime']= DateTime.DateTime
-except: pass
+except ImportError:
+ pass
+try:
+ import DocumentTemplate.sequence
+ utility_builtins['sequence']= DocumentTemplate.sequence
+except ImportError:
+ pass
+
+
def same_type(arg1, *args):
'''Compares the class or type of two or more objects.'''
t = getattr(arg1, '__class__', type(arg1))
Modified: RestrictedPython/trunk/src/RestrictedPython/__init__.py
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/__init__.py 2007-06-04 16:57:20 UTC (rev 76321)
+++ RestrictedPython/trunk/src/RestrictedPython/__init__.py 2007-06-04 17:40:03 UTC (rev 76322)
@@ -1,9 +1,9 @@
##############################################################################
#
-# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
+# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
Copied: RestrictedPython/trunk/src/RestrictedPython/notes.txt (from rev 76321, Zope/trunk/lib/python/RestrictedPython/notes.txt)
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/notes.txt (rev 0)
+++ RestrictedPython/trunk/src/RestrictedPython/notes.txt 2007-06-04 17:40:03 UTC (rev 76322)
@@ -0,0 +1,95 @@
+How it works
+============
+
+Every time I see this code, I have to relearn it. These notes will
+hopefully make this a little easier. :)
+
+- The important module is RCompile. The entry points are the
+ compile_restricted_* functions.
+
+ + compile_restricted_function is used by Python scripts.
+
+ + compile_restricted_eval is used by ZPT
+
+ and by DTML indirectly through Eval.RestrictionCapableEval.
+
+- OK, so lets see how this works by following the logic of
+ compile_restricted_eval.
+
+ - First, we create an RExpression, passing the source and a
+ "file name", to be used in tracebacks.
+
+ Now, an RExpression is just:
+
+ + a subclass of RestrictedCompileMode and Expression.
+
+ Expression is a subclass of AbstractCompileMode that sets it's
+ mode to 'eval' and everided compile. Sigh.
+
+ + RestrictedCompileMode is a subclass of AbstractCompileMode
+ that changes a bunch of things. :) These include compile, so we
+ can ignore the compile we got from Expression. It would have
+ been simpler to just set the dang mode in RExpression. Sigh.
+
+ RestrictedCompileMode seem to be the interestng base class. I
+ assume it implements the interesting functionality. We'll see
+ below...
+
+ - Next, we call compileAndTuplize.
+
+ + This calls compile on the RExpression. It has an error
+ handler that does something that I hope I don't care about. :)
+
+ + It then calls the genCode method on the RExpression. This is
+ boring, so we'll not worry about it.
+
+ - The compile method provided by RestrictedCompileMode is
+ interesting.
+
+ + First it calls _get_tree.
+
+ * It uses compiler.parse to parse the source
+
+ * it uses MutatingWalker.walk to mutaate the tree using the
+ RestrictedCompileMode's 'rm' attr, which is a
+ RestrictionMutator.
+
+ The RestrictionMutator has the recipies for mutating the parse
+ tree. (Note, for comparison, that Zope3's
+ zope.security.untrustedpython.rcompile module an alternative
+ RestrictionMutator that provides a much smaller set of
+ changes.)
+
+ A mutator has visit method for different kinds of AST
+ nodes. These visit methods may mutate nodes or return new
+ nodes that replace the originally visited nodes. There is a
+ default visitor that visits a node's children and replaces the
+ children who's visitors returned new nodes.
+
+ The walk function just calls the visitor for the root node of
+ the given tree. Note _get_tree ignores the walk return value,
+ thus assuming that the visitor for the root node doesn't
+ return a new node. This is a theoretical bug that we can
+ ignore.
+
+ + Second, it generates the code. This too is boring.
+
+- So this seems simple enough. ;) When we want to add a check, we
+ need to update or add a visit function in RestrictionMutator.
+
+ How does a visit function work.
+
+ - First, we usually call walker.defaultVisitNode(node). This
+ transforms the node's child nodes.
+
+ - Then we hack the node, or possibly return the node. To do this, we
+ have to know how the node works.
+
+ - The hack often involved changing the code to call some checker
+ function. These have names like _name_. These are names that
+ would be illegal in the input source.
+
+ If this is a new function, we have to provide it in
+ AccessControl.ZopeGuards._safe_globals.
+
+- Don't forget to add a test case to tests.before_and_after.
Modified: RestrictedPython/trunk/src/RestrictedPython/tests/before_and_after.py
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/tests/before_and_after.py 2007-06-04 16:57:20 UTC (rev 76321)
+++ RestrictedPython/trunk/src/RestrictedPython/tests/before_and_after.py 2007-06-04 17:40:03 UTC (rev 76322)
@@ -4,7 +4,7 @@
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
@@ -75,7 +75,7 @@
def nested_list_comprehension_after():
x = [x**2 + y**2 for x in _getiter_(whatever1) if x >= 0
for y in _getiter_(whatever2) if y >= x]
-
+
# print
def simple_print_before():
@@ -244,3 +244,18 @@
def lambda_with_getattr_in_defaults_after():
f = lambda x=_getattr_(y, "z"): x
+
+
+# augmented operators
+# Note that we don't have to worry about item, attr, or slice assignment,
+# as they are disallowed. Yay!
+
+## def inplace_id_add_before():
+## x += y+z
+
+## def inplace_id_add_after():
+## x = _inplacevar_('+=', x, y+z)
+
+
+
+
Copied: RestrictedPython/trunk/src/RestrictedPython/tests/before_and_after24.py (from rev 76321, Zope/trunk/lib/python/RestrictedPython/tests/before_and_after24.py)
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/tests/before_and_after24.py (rev 0)
+++ RestrictedPython/trunk/src/RestrictedPython/tests/before_and_after24.py 2007-06-04 17:40:03 UTC (rev 76322)
@@ -0,0 +1,41 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Restricted Python transformation examples
+
+This module contains pairs of functions. Each pair has a before and an
+after function. The after function shows the source code equivalent
+of the before function after it has been modified by the restricted
+compiler.
+
+These examples are actually used in the testRestrictions.py
+checkBeforeAndAfter() unit tests, which verifies that the restricted compiler
+actually produces the same output as would be output by the normal compiler
+for the after function.
+
+$Id$
+"""
+
+def simple_generator_expression_before():
+ x = (y**2 for y in whatever if y > 3)
+
+def simple_generator_expression_after():
+ x = (y**2 for y in _getiter_(whatever) if y > 3)
+
+def nested_generator_expression_before():
+ x = (x**2 + y**2 for x in whatever1 if x >= 0
+ for y in whatever2 if y >= x)
+
+def nested_generator_expression_after():
+ x = (x**2 + y**2 for x in _getiter_(whatever1) if x >= 0
+ for y in _getiter_(whatever2) if y >= x)
Modified: RestrictedPython/trunk/src/RestrictedPython/tests/restricted_module.py
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/tests/restricted_module.py 2007-06-04 16:57:20 UTC (rev 76321)
+++ RestrictedPython/trunk/src/RestrictedPython/tests/restricted_module.py 2007-06-04 17:40:03 UTC (rev 76322)
@@ -40,6 +40,10 @@
print f(*(300, 20), **{'z': 1}),
return printed
+def try_inplace():
+ x = 1
+ x += 3
+
def primes():
# Somewhat obfuscated code on purpose
print filter(None,map(lambda y:y*reduce(lambda x,y:x*y!=0,
Modified: RestrictedPython/trunk/src/RestrictedPython/tests/security_in_syntax.py
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/tests/security_in_syntax.py 2007-06-04 16:57:20 UTC (rev 76321)
+++ RestrictedPython/trunk/src/RestrictedPython/tests/security_in_syntax.py 2007-06-04 17:40:03 UTC (rev 76322)
@@ -54,3 +54,16 @@
def keyword_arg_with_bad_name():
def f(okname=1, __badname=2):
pass
+
+def no_augmeneted_assignment_to_sub():
+ a[b] += c
+
+def no_augmeneted_assignment_to_attr():
+ a.b += c
+
+def no_augmeneted_assignment_to_slice():
+ a[x:y] += c
+
+def no_augmeneted_assignment_to_slice2():
+ a[x:y:z] += c
+
Modified: RestrictedPython/trunk/src/RestrictedPython/tests/testRestrictions.py
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/tests/testRestrictions.py 2007-06-04 16:57:20 UTC (rev 76321)
+++ RestrictedPython/trunk/src/RestrictedPython/tests/testRestrictions.py 2007-06-04 17:40:03 UTC (rev 76322)
@@ -12,8 +12,8 @@
from RestrictedPython import compile_restricted, PrintCollector
from RestrictedPython.Eval import RestrictionCapableEval
-from RestrictedPython.tests import before_and_after, restricted_module, verify
-from RestrictedPython.RCompile import RModule
+from RestrictedPython.tests import restricted_module, verify
+from RestrictedPython.RCompile import RModule, RFunction
try:
__file__
@@ -51,8 +51,13 @@
return fn, msg
def get_source(func):
- """Less silly interface to find_source""" # Sheesh
- return find_source(func.func_globals['__file__'], func.func_code)[1]
+ """Less silly interface to find_source"""
+ file = func.func_globals['__file__']
+ if file.endswith('.pyc'):
+ file = file[:-1]
+ source = find_source(file, func.func_code)[1]
+ assert source.strip(), "Source should not be empty!"
+ return source
def create_rmodule():
global rmodule
@@ -175,6 +180,14 @@
apply_wrapper_called.append('yes')
return func(*args, **kws)
+inplacevar_wrapper_called = {}
+def inplacevar_wrapper(op, x, y):
+ inplacevar_wrapper_called[op] = x, y
+ # This is really lame. But it's just a test. :)
+ globs = {'x': x, 'y': y}
+ exec 'x'+op+'y' in globs
+ return globs['x']
+
class RestrictionTests(unittest.TestCase):
def execFunc(self, name, *args, **kw):
func = rmodule[name]
@@ -191,6 +204,7 @@
# work for everything.
'_getiter_': list,
'_apply_': apply_wrapper,
+ '_inplacevar_': inplacevar_wrapper,
})
return func(*args, **kw)
@@ -243,6 +257,11 @@
self.assertEqual(apply_wrapper_called, ["yes"])
self.assertEqual(res, "321")
+ def checkInplace(self):
+ inplacevar_wrapper_called.clear()
+ res = self.execFunc('try_inplace')
+ self.assertEqual(inplacevar_wrapper_called['+='], (1, 3))
+
def checkDenied(self):
for k in rmodule.keys():
if k[:6] == 'denied':
@@ -314,7 +333,7 @@
def checkBeforeAndAfter(self):
from RestrictedPython.RCompile import RModule
-
+ from RestrictedPython.tests import before_and_after
from compiler import parse
defre = re.compile(r'def ([_A-Za-z0-9]+)_(after|before)\(')
@@ -339,6 +358,34 @@
rm.compile()
verify.verify(rm.getCode())
+ if sys.version_info[:2] >= (2, 4):
+ def checkBeforeAndAfter24(self):
+ from RestrictedPython.RCompile import RModule
+ from RestrictedPython.tests import before_and_after24
+ from compiler import parse
+
+ defre = re.compile(r'def ([_A-Za-z0-9]+)_(after|before)\(')
+
+ beforel = [name for name in before_and_after24.__dict__
+ if name.endswith("_before")]
+
+ for name in beforel:
+ before = getattr(before_and_after24, name)
+ before_src = get_source(before)
+ before_src = re.sub(defre, r'def \1(', before_src)
+ rm = RModule(before_src, '')
+ tree_before = rm._get_tree()
+
+ after = getattr(before_and_after24, name[:-6]+'after')
+ after_src = get_source(after)
+ after_src = re.sub(defre, r'def \1(', after_src)
+ tree_after = parse(after_src)
+
+ self.assertEqual(str(tree_before), str(tree_after))
+
+ rm.compile()
+ verify.verify(rm.getCode())
+
def _compile_file(self, name):
path = os.path.join(_HERE, name)
f = open(path, "r")
@@ -355,7 +402,7 @@
def getiter(seq):
calls.append(seq)
return list(seq)
- globals = {"_getiter_": getiter}
+ globals = {"_getiter_": getiter, '_inplacevar_': inplacevar_wrapper}
exec co in globals, {}
# The comparison here depends on the exact code that is
# contained in unpack.py.
@@ -437,6 +484,12 @@
co = self._compile_file("lambda.py")
exec co in {}, {}
+ def checkEmpty(self):
+ rf = RFunction("", "", "issue945", "empty.py", {})
+ rf.parse()
+ rf2 = RFunction("", "# still empty\n\n# by", "issue945", "empty.py", {})
+ rf2.parse()
+
def checkSyntaxError(self):
err = ("def f(x, y):\n"
" if x, y < 2 + 1:\n"
@@ -446,9 +499,37 @@
self.assertRaises(SyntaxError,
compile_restricted, err, "<string>", "exec")
+ # these two tests check that source code with Windows line
+ # endings still works.
+
+ def checkLineEndingsRFunction(self):
+ from RestrictedPython.RCompile import RFunction
+ gen = RFunction(
+ p='',
+ body='# testing\r\nprint "testing"\r\nreturn printed\n',
+ name='test',
+ filename='<test>',
+ globals=(),
+ )
+ gen.mode = 'exec'
+ # if the source has any line ending other than \n by the time
+ # parse() is called, then you'll get a syntax error.
+ gen.parse()
+
+ def checkLineEndingsRestrictedCompileMode(self):
+ from RestrictedPython.RCompile import RestrictedCompileMode
+ gen = RestrictedCompileMode(
+ '# testing\r\nprint "testing"\r\nreturn printed\n',
+ '<testing>'
+ )
+ gen.mode='exec'
+ # if the source has any line ending other than \n by the time
+ # parse() is called, then you'll get a syntax error.
+ gen.parse()
+
+
create_rmodule()
-
def test_suite():
return unittest.makeSuite(RestrictionTests, 'check')
Modified: RestrictedPython/trunk/src/RestrictedPython/tests/verify.py
===================================================================
--- RestrictedPython/trunk/src/RestrictedPython/tests/verify.py 2007-06-04 16:57:20 UTC (rev 76321)
+++ RestrictedPython/trunk/src/RestrictedPython/tests/verify.py 2007-06-04 17:40:03 UTC (rev 76322)
@@ -3,7 +3,7 @@
# Copyright (c) 2003 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
More information about the Checkins
mailing list