[Zope-Checkins] SVN: Zope/branches/2.11/ Launchpad #174705: ensure that the error info object exposed to a

Tres Seaver tseaver at palladion.com
Mon Dec 1 13:09:08 EST 2008


Log message for revision 93507:
  Launchpad #174705:  ensure that the error info object exposed to a
  'tal:on_error' handler has attributes visible to restricted code.
  
  

Changed:
  U   Zope/branches/2.11/doc/CHANGES.txt
  U   Zope/branches/2.11/lib/python/Products/PageTemplates/Expressions.py
  U   Zope/branches/2.11/lib/python/Products/PageTemplates/tests/testExpressions.py

-=-
Modified: Zope/branches/2.11/doc/CHANGES.txt
===================================================================
--- Zope/branches/2.11/doc/CHANGES.txt	2008-12-01 18:07:36 UTC (rev 93506)
+++ Zope/branches/2.11/doc/CHANGES.txt	2008-12-01 18:09:08 UTC (rev 93507)
@@ -7,6 +7,9 @@
   Zope 2.11.3 (unreleased)
 
     Bugs Fixed
+
+      - Launchpad #174705:  ensure that the error info object exposed to a
+        'tal:on_error' handler has attributes visible to restricted code.
   
       - Testing.ZopeTestCase: Remove quota argument from DemoStorage calls in
         preparation for ZODB 3.9.

Modified: Zope/branches/2.11/lib/python/Products/PageTemplates/Expressions.py
===================================================================
--- Zope/branches/2.11/lib/python/Products/PageTemplates/Expressions.py	2008-12-01 18:07:36 UTC (rev 93506)
+++ Zope/branches/2.11/lib/python/Products/PageTemplates/Expressions.py	2008-12-01 18:09:08 UTC (rev 93507)
@@ -23,7 +23,9 @@
 from zope.component import getUtility
 from zope.component.interfaces import ComponentLookupError
 from zope.interface import implements
-from zope.tales.tales import Context, Iterator
+from zope.tales.tales import Context
+from zope.tales.tales import ErrorInfo as BaseErrorInfo
+from zope.tales.tales import Iterator
 from zope.tales.expressions import PathExpr, StringExpr, NotExpr
 from zope.tales.expressions import DeferExpr, SubPathExpr, Undefs
 from zope.tales.pythonexpr import PythonExpr
@@ -245,7 +247,24 @@
             # objects
             return unicode(text)
 
+    def createErrorInfo(self, err, position):
+        # Override, returning an object accessible to untrusted code.
+        # See: https://bugs.launchpad.net/zope2/+bug/174705
+        return ErrorInfo(err, position)
 
+    def evaluateCode(self, lang, code):
+        """ See ITALExpressionEngine.
+
+        o This method is a fossil:  nobody actually calls it, but the
+          interface requires it.
+        """
+        raise NotImplementedError
+
+class ErrorInfo(BaseErrorInfo):
+    """Information about an exception passed to an on-error handler.
+    """
+    __allow_access_to_unprotected_subobjects__ = True
+
 class ZopeEngine(zope.app.pagetemplate.engine.ZopeEngine):
 
     _create_context = ZopeContext

Modified: Zope/branches/2.11/lib/python/Products/PageTemplates/tests/testExpressions.py
===================================================================
--- Zope/branches/2.11/lib/python/Products/PageTemplates/tests/testExpressions.py	2008-12-01 18:07:36 UTC (rev 93506)
+++ Zope/branches/2.11/lib/python/Products/PageTemplates/tests/testExpressions.py	2008-12-01 18:09:08 UTC (rev 93507)
@@ -227,11 +227,47 @@
         self.assertEqual(resolver.resolve(None, 'äüö', None),
                          u'\ufffd\ufffd\ufffd')
 
+class ZopeContextTests(unittest.TestCase):
+
+    def _getTargetClass(self):
+        from Products.PageTemplates.Expressions import ZopeContext
+        return ZopeContext
+
+    def _makeOne(self, engine=None, contexts=None):
+        if engine is None:
+            engine = self._makeEngine()
+        if contexts is None:
+            contexts = {}
+        return self._getTargetClass()(engine, contexts)
+
+    def _makeEngine(self):
+        class DummyEngine:
+            pass
+        return DummyEngine()
+
+    def test_class_conforms_to_ITALExpressionEngine(self):
+        from zope.interface.verify import verifyClass
+        from zope.tal.interfaces import ITALExpressionEngine
+        verifyClass(ITALExpressionEngine, self._getTargetClass())
+
+    def test_instance_conforms_to_ITALExpressionEngine(self):
+        from zope.interface.verify import verifyObject
+        from zope.tal.interfaces import ITALExpressionEngine
+        verifyObject(ITALExpressionEngine, self._makeOne())
+
+    def test_createErrorInfo_returns_unrestricted_object(self):
+        # See: https://bugs.launchpad.net/zope2/+bug/174705
+        context = self._makeOne()
+        info = context.createErrorInfo(AttributeError('nonesuch'), (12, 3))
+        self.failUnless(info.type is AttributeError)
+        self.assertEqual(info.__allow_access_to_unprotected_subobjects__, 1)
+
 def test_suite():
     return unittest.TestSuite((
          unittest.makeSuite(UntrustedEngineTests),
          unittest.makeSuite(TrustedEngineTests),
-         unittest.makeSuite(UnicodeEncodingConflictResolverTests)
+         unittest.makeSuite(UnicodeEncodingConflictResolverTests),
+         unittest.makeSuite(ZopeContextTests),
     ))
 
 if __name__=='__main__':



More information about the Zope-Checkins mailing list