[ZPT] CVS: Packages/Products/PageTemplates (Products/DC/PageTemplates) - Expressions.py:1.10 TALES.py:1.9

evan@serenade.digicool.com evan@serenade.digicool.com
Mon, 7 May 2001 21:51:43 -0400


Update of /cvs-repository/Packages/Products/PageTemplates
In directory serenade.digicool.com:/home/evan/Zope/pt/lib/python/Products/PageTemplates

Modified Files:
	Expressions.py TALES.py 
Log Message:
Fixed access to 'repeat' variable, and security of all namespace variables,
with SecureMultiMap wrapper.

There's nothing you can't fix with another layer of indirection, except
for too many layers of indirection.



--- Updated File Expressions.py in package Packages/Products/PageTemplates --
--- Expressions.py	2001/04/27 20:54:01	1.9
+++ Expressions.py	2001/05/08 01:51:43	1.10
@@ -217,15 +217,9 @@
                 path[i:i+1] = list(val)
         try:
             __traceback_info__ = base
-            if var.has_key(base):
-                ob = var[base]
-            else:
+            has, ob = var.has_get(base)
+            if not has:
                 ob = contexts[base]
-                # Work around lack of security declaration
-                if path and (ob is contexts['repeat']):
-                    step = path.pop(0)
-                    __traceback_info__ = (base, step)
-                    ob = ob[step]
             return restrictedTraverse(ob, path)
         except (AttributeError, KeyError, TypeError, IndexError), e:
             raise Undefined, (self._s, sys.exc_info()), sys.exc_info()[2]
@@ -317,8 +311,8 @@
             # Bind template variables
             var = econtext.contexts['var']
             for vname in self._f_varnames:
-                val = var.get(vname, _marker)
-                if val is not _marker:
+                has, val = var.has_get(vname)
+                if has:
                     f.func_globals[vname] = val
 
             # Execute the function in a new security context.
@@ -364,8 +358,8 @@
             # Bind template variables
             var = econtext.contexts['var']
             for vname in self._f_varnames:
-                val = var.get(vname, _marker)
-                if val is not _marker:
+                has, val = var.has_get(vname)
+                if has:
                     f.func_globals[vname] = val
 
             # Execute the function in a new security context.
@@ -443,7 +437,7 @@
                     o=object[name]
                 except (AttributeError, TypeError):
                     raise AttributeError, name
-                if not securityManager.validate(object, object, None, o):
+                if not securityManager.validate(object, object, name, o):
                     raise 'Unauthorized', name
         object = o
 

--- Updated File TALES.py in package Packages/Products/PageTemplates --
--- TALES.py	2001/05/01 05:06:03	1.8
+++ TALES.py	2001/05/08 01:51:43	1.9
@@ -121,6 +121,28 @@
 class CompilerError(Exception):
     '''TALES Compiler Error'''
 
+class SecureMultiMap:
+    '''MultiMapping wrapper with security declarations'''
+    __allow_access_to_unprotected_subobjects__ = 1
+    def __init__(self, *dicts):
+        self._mm = apply(MultiMapping, dicts)
+    def __getitem__(self, index):
+        return self._mm[index]
+    def __len__(self):
+        return len(self._mm)
+    def _push(self, arg):
+        self._mm.push(arg)
+    def _pop(self):
+        return self._mm.pop()
+    def has_key(self, key):
+        return self._mm.has_key(key)
+    def has_get(self, key):
+        v = self._mm.get(key, self)
+        if v is self:
+            return 0, None
+        else:
+            return 1, v
+
 class Iterator(ZTUtils.Iterator):
     def __init__(self, name, seq, context):
         ZTUtils.Iterator.__init__(self, seq)
@@ -204,15 +226,15 @@
         # These contexts will need to be pushed.
         self._current_ctxts = {'local': 1, 'repeat': 1}
         
-        contexts['local'] = lv = MultiMapping()
+        contexts['local'] = lv = SecureMultiMap()
         init_local = contexts.get('local', None)
         if init_local:
-            lv.push(init_local)
+            lv._push(init_local)
+        contexts['repeat'] = rep =  SecureMultiMap()
+        contexts['loop'] = rep # alias
         contexts['global'] = gv = contexts.copy()
         gv['standard'] = contexts
-        contexts['var'] = MultiMapping(gv, lv)
-        contexts['repeat'] = rep =  MultiMapping()
-        contexts['loop'] = rep # alias
+        contexts['var'] = SecureMultiMap(gv, lv)
         
     def beginScope(self):
         oldctxts = self._current_ctxts
@@ -221,13 +243,13 @@
         for ctxname in oldctxts.keys():
             # Push fresh namespace on each local stack.
             ctxts[ctxname] = ctx = {}
-            self.contexts[ctxname].push(ctx)
+            self.contexts[ctxname]._push(ctx)
 
     def endScope(self):
         self._current_ctxts = ctxts = self._ctxts_pushed.pop()
         # Pop the ones that were pushed at the beginning of the scope.
         for ctxname in ctxts.keys():
-            ctx = self.contexts[ctxname].pop()
+            ctx = self.contexts[ctxname]._pop()
             # Make sure there's no circular garbage
             ctx.clear()