Log message for revision 106436: Fix regression in treatment of trusted code in view page templates.
Changed: U Zope/branches/2.12/doc/CHANGES.rst U Zope/branches/2.12/src/Products/Five/browser/tests/test_pagetemplatefile.py U Zope/branches/2.12/src/Products/PageTemplates/Expressions.py -=- Modified: Zope/branches/2.12/doc/CHANGES.rst =================================================================== --- Zope/branches/2.12/doc/CHANGES.rst 2009-12-12 10:58:43 UTC (rev 106435) +++ Zope/branches/2.12/doc/CHANGES.rst 2009-12-13 09:28:23 UTC (rev 106436) @@ -27,6 +27,12 @@ Bugs Fixed ++++++++++ +- Fixed a regression in Products.PageTemplates that meant filesystem templates + using Products.Five.browser.pagetemplatefile would treat TALES path + expressions (but not python expressions) as protected code and so attempt + to apply security. See original issue here: + http://codespeak.net/pipermail/z3-five/2007q2/002185.html + - LP #491249: fix tabindex on ZRDB connection test form. - LP #490514: preserve tainting when calling into DTML from ZPT. Modified: Zope/branches/2.12/src/Products/Five/browser/tests/test_pagetemplatefile.py =================================================================== --- Zope/branches/2.12/src/Products/Five/browser/tests/test_pagetemplatefile.py 2009-12-12 10:58:43 UTC (rev 106435) +++ Zope/branches/2.12/src/Products/Five/browser/tests/test_pagetemplatefile.py 2009-12-13 09:28:23 UTC (rev 106436) @@ -42,15 +42,15 @@ from zope.tales.pythonexpr import PythonExpr from zope.contentprovider.tales import TALESProviderExpression from Products.PageTemplates.DeferExpr import LazyExpr - from Products.PageTemplates.Expressions import ZopePathExpr + from Products.PageTemplates.Expressions import TrustedZopePathExpr from Products.PageTemplates.Expressions import SecureModuleImporter vptf = self._makeOne('seagull.pt') engine = vptf.pt_getEngine() - self.assertEqual(engine.types['standard'], ZopePathExpr) - self.assertEqual(engine.types['path'], ZopePathExpr) - self.assertEqual(engine.types['exists'], ZopePathExpr) - self.assertEqual(engine.types['nocall'], ZopePathExpr) + self.assertEqual(engine.types['standard'], TrustedZopePathExpr) + self.assertEqual(engine.types['path'], TrustedZopePathExpr) + self.assertEqual(engine.types['exists'], TrustedZopePathExpr) + self.assertEqual(engine.types['nocall'], TrustedZopePathExpr) self.assertEqual(engine.types['string'], StringExpr) self.assertEqual(engine.types['python'], PythonExpr) self.assertEqual(engine.types['not'], NotExpr) Modified: Zope/branches/2.12/src/Products/PageTemplates/Expressions.py =================================================================== --- Zope/branches/2.12/src/Products/PageTemplates/Expressions.py 2009-12-12 10:58:43 UTC (rev 106435) +++ Zope/branches/2.12/src/Products/PageTemplates/Expressions.py 2009-12-13 09:28:23 UTC (rev 106436) @@ -79,6 +79,26 @@ request=request) 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): """Calls the object, possibly a document template, or just returns it if not callable. (From DT_Util.py) @@ -104,11 +124,13 @@ class ZopePathExpr(PathExpr): + _TRAVERSER = staticmethod(boboAwareZopeTraverse) + def __init__(self, name, expr, engine): if not expr.strip(): expr = 'nothing' super(ZopePathExpr, self).__init__(name, expr, engine, - boboAwareZopeTraverse) + self._TRAVERSER) # override this to support different call metrics (see bottom of # method) and Zope 2's traversal exceptions (ZopeUndefs instead of @@ -146,6 +168,9 @@ return 1 return 0 +class TrustedZopePathExpr(ZopePathExpr): + _TRAVERSER = staticmethod(trustedBoboAwareZopeTraverse) + class SafeMapping(MultiMapping): """Mapping with security declarations and limited method exposure. @@ -347,11 +372,11 @@ return False return ob1 == ob2 -def createZopeEngine(): +def createZopeEngine(zpe=ZopePathExpr): e = ZopeEngine() e.iteratorFactory = PathIterator - for pt in ZopePathExpr._default_type_names: - e.registerType(pt, ZopePathExpr) + for pt in zpe._default_type_names: + e.registerType(pt, zpe) e.registerType('string', StringExpr) e.registerType('python', ZRPythonExpr.PythonExpr) e.registerType('not', NotExpr) @@ -364,7 +389,7 @@ def createTrustedZopeEngine(): # same as createZopeEngine, but use non-restricted Python # expression evaluator - e = createZopeEngine() + e = createZopeEngine(TrustedZopePathExpr) e.types['python'] = PythonExpr return e _______________________________________________ Zope-Checkins maillist - Zope-Checkins@zope.org https://mail.zope.org/mailman/listinfo/zope-checkins