[Checkins] SVN: plone.z3cform/trunk/plone/z3cform/traversal.py Fix security bug with ++widget++ traverser that would show up on Zope 2.12, and explain the rather convoluted way to support both 2.10 and 2.12
Martin Aspeli
optilude at gmx.net
Sat Dec 19 11:44:17 EST 2009
Log message for revision 106778:
Fix security bug with ++widget++ traverser that would show up on Zope 2.12, and explain the rather convoluted way to support both 2.10 and 2.12
Changed:
U plone.z3cform/trunk/plone/z3cform/traversal.py
-=-
Modified: plone.z3cform/trunk/plone/z3cform/traversal.py
===================================================================
--- plone.z3cform/trunk/plone/z3cform/traversal.py 2009-12-19 00:59:56 UTC (rev 106777)
+++ plone.z3cform/trunk/plone/z3cform/traversal.py 2009-12-19 16:44:16 UTC (rev 106778)
@@ -7,12 +7,27 @@
from plone.z3cform.interfaces import IFormWrapper
from plone.z3cform import z2
+from Acquisition import aq_inner
+
class WidgetTraversal(object):
"""Allow traversal to widgets via the ++widget++ namespace. The context
is the from layout wrapper.
- Note that widgets may need to mixing in Acquisition.Explicit for this to
- work.
+ Note that to support security in Zope 2.10, the widget being traversed to
+ must have an __of__ method, i.e. it must support acquisition. The easiest
+ way to do that, is to mix in Acquisition.Explicit. The acquisition parent
+ will be the layout form wrapper view.
+
+ In Zope 2.12, this is not necessary, because we also set the __parent__
+ pointer of the returned widget to be the traversal context.
+
+ Unfortunately, if you mix in Acquisition.Explicit in Zope 2.12 *and* the
+ class implements IAcquirer, Zope may complain because the view probably
+ does *not* implement acquisition (in Zope 2.12, views no longer mix in
+ Acquisiton.Explicit). To support both Zope 2.10 and Zope 2.12, you will
+ need to cheat and mix in Acquisition.Explicit, but use implementsOnly()
+ or some other mechanism to make sure the instance does not provide
+ IAcquirer.
"""
implements(ITraversable)
@@ -31,10 +46,16 @@
# Find the widget - it may be in a group
if name in form.widgets:
- return form.widgets.get(name)
+ widget = form.widgets.get(name)
elif form.groups is not None:
for group in form.groups:
if name in group.widgets:
- return group.widgets.get(name)
+ widget = group.widgets.get(name)
- return None
\ No newline at end of file
+ # Make the parent of the widget the traversal parent.
+ # This is required for security to work in Zope 2.12
+ if widget is not None:
+ widget.__parent__ = aq_inner(self.context)
+ return widget
+
+ return None
More information about the checkins
mailing list