[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