Commit 187c84fb authored by Martin Aspeli's avatar Martin Aspeli

Merge r106436 from 2.12 branch, fixing a regression in the ZPT engine for trusted code

parent b02d9cf4
...@@ -42,15 +42,15 @@ class ViewPageTemplateFileTests(unittest.TestCase): ...@@ -42,15 +42,15 @@ class ViewPageTemplateFileTests(unittest.TestCase):
from zope.tales.pythonexpr import PythonExpr from zope.tales.pythonexpr import PythonExpr
from zope.contentprovider.tales import TALESProviderExpression from zope.contentprovider.tales import TALESProviderExpression
from Products.PageTemplates.DeferExpr import LazyExpr from Products.PageTemplates.DeferExpr import LazyExpr
from Products.PageTemplates.Expressions import ZopePathExpr from Products.PageTemplates.Expressions import TrustedZopePathExpr
from Products.PageTemplates.Expressions import SecureModuleImporter from Products.PageTemplates.Expressions import SecureModuleImporter
vptf = self._makeOne('seagull.pt') vptf = self._makeOne('seagull.pt')
engine = vptf.pt_getEngine() engine = vptf.pt_getEngine()
self.assertEqual(engine.types['standard'], ZopePathExpr) self.assertEqual(engine.types['standard'], TrustedZopePathExpr)
self.assertEqual(engine.types['path'], ZopePathExpr) self.assertEqual(engine.types['path'], TrustedZopePathExpr)
self.assertEqual(engine.types['exists'], ZopePathExpr) self.assertEqual(engine.types['exists'], TrustedZopePathExpr)
self.assertEqual(engine.types['nocall'], ZopePathExpr) self.assertEqual(engine.types['nocall'], TrustedZopePathExpr)
self.assertEqual(engine.types['string'], StringExpr) self.assertEqual(engine.types['string'], StringExpr)
self.assertEqual(engine.types['python'], PythonExpr) self.assertEqual(engine.types['python'], PythonExpr)
self.assertEqual(engine.types['not'], NotExpr) self.assertEqual(engine.types['not'], NotExpr)
......
...@@ -79,6 +79,26 @@ def boboAwareZopeTraverse(object, path_items, econtext): ...@@ -79,6 +79,26 @@ def boboAwareZopeTraverse(object, path_items, econtext):
request=request) request=request)
return object return object
def trustedBoboAwareZopeTraverse(object, path_items, econtext):
"""Traverses a sequence of names, first trying attributes then items.
This uses Zope 3 path traversal where possible and interacts
correctly with objects providing OFS.interface.ITraversable when
necessary (bobo-awareness).
"""
request = getattr(econtext, 'request', None)
path_items = list(path_items)
path_items.reverse()
while path_items:
name = path_items.pop()
if OFS.interfaces.ITraversable.providedBy(object):
object = object.unrestrictedTraverse(name)
else:
object = traversePathElement(object, name, path_items,
request=request)
return object
def render(ob, ns): def render(ob, ns):
"""Calls the object, possibly a document template, or just returns """Calls the object, possibly a document template, or just returns
it if not callable. (From DT_Util.py) it if not callable. (From DT_Util.py)
...@@ -104,11 +124,13 @@ def render(ob, ns): ...@@ -104,11 +124,13 @@ def render(ob, ns):
class ZopePathExpr(PathExpr): class ZopePathExpr(PathExpr):
_TRAVERSER = staticmethod(boboAwareZopeTraverse)
def __init__(self, name, expr, engine): def __init__(self, name, expr, engine):
if not expr.strip(): if not expr.strip():
expr = 'nothing' expr = 'nothing'
super(ZopePathExpr, self).__init__(name, expr, engine, super(ZopePathExpr, self).__init__(name, expr, engine,
boboAwareZopeTraverse) self._TRAVERSER)
# override this to support different call metrics (see bottom of # override this to support different call metrics (see bottom of
# method) and Zope 2's traversal exceptions (ZopeUndefs instead of # method) and Zope 2's traversal exceptions (ZopeUndefs instead of
...@@ -146,6 +168,9 @@ class ZopePathExpr(PathExpr): ...@@ -146,6 +168,9 @@ class ZopePathExpr(PathExpr):
return 1 return 1
return 0 return 0
class TrustedZopePathExpr(ZopePathExpr):
_TRAVERSER = staticmethod(trustedBoboAwareZopeTraverse)
class SafeMapping(MultiMapping): class SafeMapping(MultiMapping):
"""Mapping with security declarations and limited method exposure. """Mapping with security declarations and limited method exposure.
...@@ -347,11 +372,11 @@ class PathIterator(ZopeIterator): ...@@ -347,11 +372,11 @@ class PathIterator(ZopeIterator):
return False return False
return ob1 == ob2 return ob1 == ob2
def createZopeEngine(): def createZopeEngine(zpe=ZopePathExpr):
e = ZopeEngine() e = ZopeEngine()
e.iteratorFactory = PathIterator e.iteratorFactory = PathIterator
for pt in ZopePathExpr._default_type_names: for pt in zpe._default_type_names:
e.registerType(pt, ZopePathExpr) e.registerType(pt, zpe)
e.registerType('string', StringExpr) e.registerType('string', StringExpr)
e.registerType('python', ZRPythonExpr.PythonExpr) e.registerType('python', ZRPythonExpr.PythonExpr)
e.registerType('not', NotExpr) e.registerType('not', NotExpr)
...@@ -364,7 +389,7 @@ def createZopeEngine(): ...@@ -364,7 +389,7 @@ def createZopeEngine():
def createTrustedZopeEngine(): def createTrustedZopeEngine():
# same as createZopeEngine, but use non-restricted Python # same as createZopeEngine, but use non-restricted Python
# expression evaluator # expression evaluator
e = createZopeEngine() e = createZopeEngine(TrustedZopePathExpr)
e.types['python'] = PythonExpr e.types['python'] = PythonExpr
return e return e
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment