[Checkins] SVN: Products.CMFCore/branches/matthewwilkes-traversalprecedence/Products/CMFCore/ Tests and fixes to path traversal

Matthew Wilkes matthew at matthewwilkes.co.uk
Mon Aug 17 08:17:41 EDT 2009


Log message for revision 102874:
  Tests and fixes to path traversal

Changed:
  U   Products.CMFCore/branches/matthewwilkes-traversalprecedence/Products/CMFCore/Skinnable.py
  U   Products.CMFCore/branches/matthewwilkes-traversalprecedence/Products/CMFCore/tests/test_SkinsTool.py

-=-
Modified: Products.CMFCore/branches/matthewwilkes-traversalprecedence/Products/CMFCore/Skinnable.py
===================================================================
--- Products.CMFCore/branches/matthewwilkes-traversalprecedence/Products/CMFCore/Skinnable.py	2009-08-17 12:08:10 UTC (rev 102873)
+++ Products.CMFCore/branches/matthewwilkes-traversalprecedence/Products/CMFCore/Skinnable.py	2009-08-17 12:17:41 UTC (rev 102874)
@@ -255,6 +255,8 @@
         if not path:
             return self
 
+        next = None
+
         if isinstance(path, str):
             # Unicode paths are not allowed
             path = path.split('/')
@@ -348,7 +350,6 @@
                                         is not next):
                                     raise Unauthorized(name)
                     else:
-                        next = None
                         try:
                             next = obj.__getattribute__(name)
                         except AttributeError:
@@ -362,28 +363,10 @@
                             if restricted:
                                 guard(obj, next)
                         if next is None:
-                            try:
-                                next = obj[name]
-                                # The item lookup may return a NullResource,
-                                # if this is the case we save it and return it
-                                # if all other lookups fail.
-                                if isinstance(next, NullResource):
-                                    resource = next
-                                    raise KeyError(name)
-                            except AttributeError:
-                                # Raise NotFound for easier debugging
-                                # instead of AttributeError: __getitem__
-                                raise NotFound(name)
-                            if restricted and not validate(
-                                obj, obj, None, next):
-                                raise Unauthorized(name)
-                        if next is None:
-                            if restricted:
-                                next = guarded_getattr(obj, name, _MARKER)
-                            else:
-                                next = getattr(obj, name, _MARKER)
+                            # Go to the case below which handles views and 
+                            # acquired attributes.
+                            raise NotFound(name)
 
-
                 except (AttributeError, NotFound, KeyError), e:
                     # Try to look for a view
                     next = queryMultiAdapter((obj, aq_acquire(self, 'REQUEST')),
@@ -407,12 +390,28 @@
                                 next = getattr(obj, name, _MARKER)
                         except AttributeError:
                             raise e
-                        if next is _MARKER:
+                        if next is None:
                             # If we have a NullResource from earlier use it.
                             next = resource
                             if next is _MARKER:
                                 # Nothing found re-raise error
                                 raise e
+                        if next is None:
+                            try:
+                                next = obj[name]
+                                # The item lookup may return a NullResource,
+                                # if this is the case we save it and return it
+                                # if all other lookups fail.
+                                if isinstance(next, NullResource):
+                                    resource = next
+                                    raise KeyError(name)
+                            except AttributeError:
+                                # Raise NotFound for easier debugging
+                                # instead of AttributeError: __getitem__
+                                raise NotFound(name)
+                            if restricted and not validate(
+                                obj, obj, None, next):
+                                raise Unauthorized(name)
 
                 obj = next
 

Modified: Products.CMFCore/branches/matthewwilkes-traversalprecedence/Products/CMFCore/tests/test_SkinsTool.py
===================================================================
--- Products.CMFCore/branches/matthewwilkes-traversalprecedence/Products/CMFCore/tests/test_SkinsTool.py	2009-08-17 12:08:10 UTC (rev 102873)
+++ Products.CMFCore/branches/matthewwilkes-traversalprecedence/Products/CMFCore/tests/test_SkinsTool.py	2009-08-17 12:17:41 UTC (rev 102874)
@@ -144,8 +144,39 @@
         # Finally, we override that with a real object at the skinnable root
         setattr(som, "a", a_root)
         assert pt.publishTraverse({"URL":"/"}, "a") is a_root
+
+    def test_path_traversal(self):
+        som = self._makeOne()
+        fake_request = som.REQUEST
+    
+        class FakeView(object):
+            implements(Interface)
+            adapts(som.__class__, object)
+            
+            def __init__(self, context, request):
+                pass
+
+        a_root = object()
+        a_skinlayer = object()
         
+        class mock_skin(object):
+            def __init__(self):
+                self.a = a_skinlayer
 
+        # We set up a fake skin that contains a marker object at "a"
+        som.tool.getSkinByName = lambda x:mock_skin()
+        som.changeSkin("mock")
+        assert som.unrestrictedTraverse("a") is a_skinlayer
+        
+        # Now, we override that with a view
+        gsm = getGlobalSiteManager()
+        gsm.registerAdapter(FakeView, (som.__class__, fake_request), Interface, 'a')
+        assert som.unrestrictedTraverse("a").__class__ is FakeView
+        
+        # Finally, we override that with a real object at the skinnable root
+        setattr(som, "a", a_root)
+        assert som.unrestrictedTraverse("a") is a_root
+        
 def test_suite():
     return unittest.TestSuite((
         unittest.makeSuite(SkinsContainerTests),



More information about the Checkins mailing list