Commit beba9373 authored by Tres Seaver's avatar Tres Seaver

Launchpad #174705: ensure that the error info object exposed to a

'tal:on_error' handler has attributes visible to restricted code.
parent 9c384ec1
......@@ -7,6 +7,9 @@ Zope Changes
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.
......
......@@ -23,7 +23,9 @@ import logging
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,6 +247,23 @@ class ZopeContext(Context):
# 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):
......
......@@ -227,11 +227,47 @@ class UnicodeEncodingConflictResolverTests(PlacelessSetup, unittest.TestCase):
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__':
......
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