Commit 63089a55 authored by Evan Simpson's avatar Evan Simpson

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.
parent f9d24c8b
......@@ -89,7 +89,7 @@ Page Template-specific implementation of TALES, with handlers
for Python expressions, Python string literals, and paths.
"""
__version__='$Revision: 1.9 $'[11:-2]
__version__='$Revision: 1.10 $'[11:-2]
import re, sys
from TALES import Engine, CompilerError, _valid_name, NAME_RE, \
......@@ -217,15 +217,9 @@ class PathExpr:
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 @@ if sys.modules.has_key('Zope'):
# 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 @@ else:
# 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 @@ def restrictedTraverse(self, path):
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
......
......@@ -87,7 +87,7 @@
An implementation of a generic TALES engine
"""
__version__='$Revision: 1.8 $'[11:-2]
__version__='$Revision: 1.9 $'[11:-2]
import re, sys, ZTUtils
from MultiMapping import MultiMapping
......@@ -121,6 +121,28 @@ class RegistrationError(Exception):
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 @@ class Context:
# 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 @@ class Context:
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()
......
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