summaryrefslogtreecommitdiff
path: root/src/zope/pagetemplate
diff options
context:
space:
mode:
Diffstat (limited to 'src/zope/pagetemplate')
-rw-r--r--src/zope/pagetemplate/engine.py27
-rw-r--r--src/zope/pagetemplate/tests/test_engine.py30
2 files changed, 32 insertions, 25 deletions
diff --git a/src/zope/pagetemplate/engine.py b/src/zope/pagetemplate/engine.py
index 662dbcd..9b61498 100644
--- a/src/zope/pagetemplate/engine.py
+++ b/src/zope/pagetemplate/engine.py
@@ -33,13 +33,17 @@ from zope.traversing.interfaces import TraversalError
from zope import component
-try: # pragma: no cover
- # Until https://github.com/zopefoundation/zope.untrustedpython/issues/2
- # is fixed Python 3 does not support special handling for untrusted code:
+try:
+ # The ``untrusted`` extra is needed to have zope.untrustedpython:
from zope.untrustedpython import rcompile
from zope.untrustedpython.builtins import SafeBuiltins
+
+ def guarded_getitem(ob, index):
+ """getitem access which gets guarded in the next line."""
+ return ob[index]
+ guarded_getitem = ProxyFactory(guarded_getitem)
HAVE_UNTRUSTED = True
-except ImportError:
+except ImportError: # pragma: no cover
HAVE_UNTRUSTED = False
# PyPy doesn't support assigning to '__builtins__', even when using eval()
@@ -128,6 +132,8 @@ class ZopePythonExpr(PythonExpr):
def __call__(self, econtext):
__traceback_info__ = self.text
vars = self._bind_used_names(econtext, SafeBuiltins)
+ vars['_getattr_'] = SafeBuiltins.getattr
+ vars['_getitem_'] = guarded_getitem
return eval(self._code, vars)
def _compile(self, text, filename):
@@ -363,14 +369,15 @@ class ZopeEngine(ZopeBaseEngine):
wrapped in security proxies if the 'untrusted' extra is installed::
>>> r = context.evaluate('python: {12: object()}.values')
- >>> str(type(r).__name__) in (
- ... ('_Proxy',) if HAVE_UNTRUSTED else
- ... ('builtin_function_or_method', 'method', 'instancemethod'))
+ >>> str(type(r).__name__) if HAVE_UNTRUSTED else '_Proxy'
+ '_Proxy'
+ >>> ((str(type(r).__name__) in ('method', 'instancemethod'))
+ ... if not HAVE_UNTRUSTED else True)
True
- >>> r = context.evaluate('python: {12: object()}[12].__class__')
- >>> str(type(r).__name__) == '_Proxy' or not HAVE_UNTRUSTED
- True
+ >>> r = context.evaluate('python: {12: (1, 2, 3)}[12]')
+ >>> str(type(r).__name__) if HAVE_UNTRUSTED else '_Proxy'
+ '_Proxy'
General path expressions provide objects that are wrapped in
security proxies as well::
diff --git a/src/zope/pagetemplate/tests/test_engine.py b/src/zope/pagetemplate/tests/test_engine.py
index 946cfba..714d4d2 100644
--- a/src/zope/pagetemplate/tests/test_engine.py
+++ b/src/zope/pagetemplate/tests/test_engine.py
@@ -51,11 +51,7 @@ class DummyEngine:
return {}
def getCompilerError(self):
- # This is only here to get meaningful errors if RestrictedPython denies
- # execution of some code.
- def get_error(text): # pragma: no cover
- raise RuntimeError(text) # pragma: no cover
- return get_error # pragma: no cover
+ return SyntaxError # pragma: no cover
class DummyContext:
@@ -73,21 +69,25 @@ class ZopePythonExprTests(unittest.TestCase):
expr = ZopePythonExpr('python', 'max(a,b)', DummyEngine())
self.assertEqual(expr(DummyContext(a=1, b=2)), 2)
- def test_allowed_module_name(self):
+ def test_import_not_possible(self):
from zope.pagetemplate.engine import ZopePythonExpr
- expr = ZopePythonExpr('python', '__import__("sys").__name__',
- DummyEngine())
- self.assertEqual(expr(DummyContext()), 'sys')
+ with self.assertRaises(SyntaxError) as err:
+ ZopePythonExpr('python', 'import sys', DummyEngine())
+ if zope.pagetemplate.engine.HAVE_UNTRUSTED:
+ self.assertIn(
+ 'SyntaxError: invalid syntax at statement', str(err.exception))
+ else:
+ self.assertEqual(
+ 'invalid syntax (<string>, line 1)', str(err.exception))
@unittest.skipUnless(zope.pagetemplate.engine.HAVE_UNTRUSTED,
"Needs untrusted")
- def test_forbidden_module_name(self):
- from zope.security.interfaces import Forbidden
-
+ def test___import___not_allowed(self):
from zope.pagetemplate.engine import ZopePythonExpr
- expr = ZopePythonExpr('python', '__import__("sys").exit',
- DummyEngine())
- self.assertRaises(Forbidden, expr, DummyContext())
+ with self.assertRaises(SyntaxError) as err:
+ ZopePythonExpr('python', '__import__("sys")', DummyEngine())
+ self.assertIn(
+ '"__import__" is an invalid variable', str(err.exception))
@unittest.skipUnless(zope.pagetemplate.engine.HAVE_UNTRUSTED,
"Needs untrusted")