Commit 7e9bc113 authored by Fred Drake's avatar Fred Drake

PathExpr._eval():

    Very aggressively cache anything that involves a global lookup.

restrictedTraverse():
    Only cache things once it's possible we might use them.  Use the
    cached getattr() in one plase where the global was being looked up
    again.  Cache hasattr() as well.  Only construct the marker (M)
    once, not once for each call.
parent a93f1dd9
...@@ -89,7 +89,7 @@ Page Template-specific implementation of TALES, with handlers ...@@ -89,7 +89,7 @@ Page Template-specific implementation of TALES, with handlers
for Python expressions, string literals, and paths. for Python expressions, string literals, and paths.
""" """
__version__='$Revision: 1.14 $'[11:-2] __version__='$Revision: 1.15 $'[11:-2]
import re, sys import re, sys
from TALES import Engine, CompilerError, _valid_name, NAME_RE, \ from TALES import Engine, CompilerError, _valid_name, NAME_RE, \
...@@ -171,14 +171,15 @@ class PathExpr: ...@@ -171,14 +171,15 @@ class PathExpr:
dp.reverse() dp.reverse()
return base, path, dp return base, path, dp
def _eval(self, (base, path, dp), econtext): def _eval(self, (base, path, dp), econtext,
list=list, isinstance=isinstance, StringType=type('')):
path = list(path) # Copy! path = list(path) # Copy!
contexts = econtext.contexts contexts = econtext.contexts
var = contexts['var'] var = contexts['var']
# Expand dynamic path parts from right to left. # Expand dynamic path parts from right to left.
for i, varname in dp: for i, varname in dp:
val = var[varname] val = var[varname]
if type(val) is type(''): if isinstance(val, StringType):
path[i] = val path[i] = val
else: else:
# If the value isn't a string, assume it's a sequence # If the value isn't a string, assume it's a sequence
...@@ -270,26 +271,24 @@ class NotExpr: ...@@ -270,26 +271,24 @@ class NotExpr:
return '<NotExpr %s>' % `self._s` return '<NotExpr %s>' % `self._s`
def restrictedTraverse(self, path): def restrictedTraverse(self, path,
get=getattr, has=hasattr, N=None, M=[]):
if not path: return self if not path: return self
get=getattr
N=None
M=[] #marker
REQUEST={'TraversalRequestNameStack': path}
securityManager = getSecurityManager() securityManager = getSecurityManager()
plen = len(path)
i = 0 i = 0
if not path[0]: if not path[0]:
# If the path starts with an empty string, go to the root first. # If the path starts with an empty string, go to the root first.
i = 1
self = self.getPhysicalRoot() self = self.getPhysicalRoot()
if not securityManager.validateValue(self): if not securityManager.validateValue(self):
raise 'Unauthorized', name raise 'Unauthorized', name
i = 1
plen = len(path)
REQUEST={'TraversalRequestNameStack': path}
validate = securityManager.validate
object = self object = self
while i < plen: while i < plen:
__traceback_info__ = (path, i) __traceback_info__ = (path, i)
...@@ -301,9 +300,9 @@ def restrictedTraverse(self, path): ...@@ -301,9 +300,9 @@ def restrictedTraverse(self, path):
raise AttributeError, name raise AttributeError, name
if name=='..': if name=='..':
o = getattr(object, 'aq_parent', M) o = get(object, 'aq_parent', M)
if o is not M: if o is not M:
if not securityManager.validate(object, object, name, o): if not validate(object, object, name, o):
raise 'Unauthorized', name raise 'Unauthorized', name
object=o object=o
continue continue
...@@ -313,27 +312,27 @@ def restrictedTraverse(self, path): ...@@ -313,27 +312,27 @@ def restrictedTraverse(self, path):
o=t(REQUEST, name) o=t(REQUEST, name)
container = None container = None
if (hasattr(get(object, 'aq_base', object), name) if (has(get(object, 'aq_base', object), name)
and get(object, name) is o): and get(object, name) is o):
container = object container = object
if not securityManager.validate(object, container, name, o): if not validate(object, container, name, o):
raise 'Unauthorized', name raise 'Unauthorized', name
else: else:
o=get(object, name, M) o=get(object, name, M)
if o is not M: if o is not M:
# Check security. # Check security.
if hasattr(object, 'aq_acquire'): if has(object, 'aq_acquire'):
object.aq_acquire( object.aq_acquire(
name, validate2, securityManager.validate) name, validate2, validate)
else: else:
if not securityManager.validate(object, object, name, o): if not validate(object, object, name, o):
raise 'Unauthorized', name raise 'Unauthorized', name
else: else:
try: try:
o=object[name] o=object[name]
except (AttributeError, TypeError): except (AttributeError, TypeError):
raise AttributeError, name raise AttributeError, name
if not securityManager.validate(object, object, name, o): if not validate(object, object, name, o):
raise 'Unauthorized', name raise 'Unauthorized', name
object = o object = o
......
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