Commit 6ef81bdb authored by Evan Simpson's avatar Evan Simpson

Change Error handling and turn on path restrictions.

parent f262f5ca
...@@ -89,10 +89,10 @@ Page Template-specific implementation of TALES, with handlers ...@@ -89,10 +89,10 @@ Page Template-specific implementation of TALES, with handlers
for Python expressions, Python string literals, and paths. for Python expressions, Python string literals, and paths.
""" """
__version__='$Revision: 1.2 $'[11:-2] __version__='$Revision: 1.3 $'[11:-2]
import re, sys import re, sys
from TALES import Engine, TALESError, _valid_name, NAME_RE from TALES import Engine, CompilerError, _valid_name, NAME_RE
from string import strip, split, join, replace from string import strip, split, join, replace
from DocumentTemplate.DT_Util import TemplateDict from DocumentTemplate.DT_Util import TemplateDict
...@@ -121,7 +121,7 @@ class PathExpr: ...@@ -121,7 +121,7 @@ class PathExpr:
self._path = path = split(expr, '/') self._path = path = split(expr, '/')
self._base = base = path.pop(0) self._base = base = path.pop(0)
if not _valid_name(base): if not _valid_name(base):
raise TALESError, 'Invalid variable name "%s"' % base raise CompilerError, 'Invalid variable name "%s"' % base
self._dynparts = dp = [] self._dynparts = dp = []
for i in range(len(path)): for i in range(len(path)):
e = path[i] e = path[i]
...@@ -183,15 +183,15 @@ class StringExpr: ...@@ -183,15 +183,15 @@ class StringExpr:
for exp in split(expr, '$$'): for exp in split(expr, '$$'):
if parts: parts.append('$') if parts: parts.append('$')
m = _interp.search(exp) m = _interp.search(exp)
if m is not None: while m is not None:
parts.append(exp[:m.start()]) parts.append(exp[:m.start()])
parts.append('%s') parts.append('%s')
vars.append(PathExpr('path', m.group(1) or m.group(2))) vars.append(PathExpr('path', m.group(1) or m.group(2)))
exp = exp[m.end():] exp = exp[m.end():]
m = _interp.search(exp) m = _interp.search(exp)
if '$' in exp: if '$' in exp:
raise TALESError, ('$ must be doubled or ' raise CompilerError, (
'followed by a variable name ' '$ must be doubled or followed by a variable name '
'in string expression "%s"' % expr) 'in string expression "%s"' % expr)
parts.append(exp) parts.append(exp)
expr = join(parts, '') expr = join(parts, '')
...@@ -231,7 +231,7 @@ if sys.modules.has_key('Zope'): ...@@ -231,7 +231,7 @@ if sys.modules.has_key('Zope'):
self.expr = expr = strip(expr) self.expr = expr = strip(expr)
blk = GuardedBlock('def f():\n return %s\n' % expr) blk = GuardedBlock('def f():\n return %s\n' % expr)
if blk.errors: if blk.errors:
raise TALESError, ('Python expression error:\n%s' % raise CompilerError, ('Python expression error:\n%s' %
join(blk.errors, '\n') ) join(blk.errors, '\n') )
guards = {'$guard': theGuard, '$write_guard': WriteGuard, guards = {'$guard': theGuard, '$write_guard': WriteGuard,
'$read_guard': ReadGuard, '__debug__': __debug__} '$read_guard': ReadGuard, '__debug__': __debug__}
...@@ -263,6 +263,12 @@ if sys.modules.has_key('Zope'): ...@@ -263,6 +263,12 @@ if sys.modules.has_key('Zope'):
def __str__(self): def __str__(self):
return 'Python expression "%s"' % self.expr return 'Python expression "%s"' % self.expr
else: else:
class getSecurityManager:
'''Null security manager'''
def validate(self, *args, **kwargs):
return 1
validateValue = validate
class PythonExpr: class PythonExpr:
def __init__(self, name, expr): def __init__(self, name, expr):
try: try:
...@@ -270,7 +276,7 @@ else: ...@@ -270,7 +276,7 @@ else:
exec 'def f():\n return %s\n' % strip(expr) in d exec 'def f():\n return %s\n' % strip(expr) in d
self._f = d['f'] self._f = d['f']
except: except:
raise TALESError, ('Python expression error:\n' raise CompilerError, ('Python expression error:\n'
'%s: %s') % sys.exc_info()[:2] '%s: %s') % sys.exc_info()[:2]
self._f_varnames = vnames = [] self._f_varnames = vnames = []
for vname in self._f.func_code.co_names: for vname in self._f.func_code.co_names:
...@@ -310,14 +316,14 @@ def restrictedTraverse(self, path): ...@@ -310,14 +316,14 @@ def restrictedTraverse(self, path):
REQUEST={'TraversalRequestNameStack': path} REQUEST={'TraversalRequestNameStack': path}
path.reverse() path.reverse()
pop=path.pop pop=path.pop
#securityManager=getSecurityManager() securityManager=getSecurityManager()
if not path[-1]: if not path[-1]:
# 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.
pop() pop()
self=self.getPhysicalRoot() self=self.getPhysicalRoot()
#if not securityManager.validateValue(self): if not securityManager.validateValue(self):
# raise 'Unauthorized', name raise 'Unauthorized', name
object = self object = self
while path: while path:
...@@ -330,8 +336,8 @@ def restrictedTraverse(self, path): ...@@ -330,8 +336,8 @@ def restrictedTraverse(self, path):
if name=='..': if name=='..':
o=getattr(object, 'aq_parent', M) o=getattr(object, 'aq_parent', M)
if o is not M: if o is not M:
#if not securityManager.validate(object, object, name, o): if not securityManager.validate(object, object, name, o):
# raise 'Unauthorized', name raise 'Unauthorized', name
object=o object=o
continue continue
...@@ -341,8 +347,8 @@ def restrictedTraverse(self, path): ...@@ -341,8 +347,8 @@ def restrictedTraverse(self, path):
# Note we pass no container, because we have no # Note we pass no container, because we have no
# way of knowing what it is # way of knowing what it is
#if not securityManager.validate(object, None, name, o): if not securityManager.validate(object, None, name, o):
# raise 'Unauthorized', name raise 'Unauthorized', name
else: else:
o=get(object, name, M) o=get(object, name, M)
...@@ -350,20 +356,20 @@ def restrictedTraverse(self, path): ...@@ -350,20 +356,20 @@ def restrictedTraverse(self, path):
# waaaa # waaaa
if hasattr(get(object,'aq_base',object), name): if hasattr(get(object,'aq_base',object), name):
# value wasn't acquired # value wasn't acquired
#if not securityManager.validate( if not securityManager.validate(
# object, object, name, o): object, object, name, o):
# raise 'Unauthorized', name raise 'Unauthorized', name
pass pass
else: else:
#if not securityManager.validate( if not securityManager.validate(
# object, None, name, o): object, None, name, o):
# raise 'Unauthorized', name raise 'Unauthorized', name
pass pass
else: else:
o=object[name] o=object[name]
#if not securityManager.validate(object, object, None, o): if not securityManager.validate(object, object, None, o):
# raise 'Unauthorized', name raise 'Unauthorized', name
object = o object = o
return object return object
...@@ -87,7 +87,7 @@ ...@@ -87,7 +87,7 @@
HTML- and XML-based template objects using TAL, TALES, and METAL. HTML- and XML-based template objects using TAL, TALES, and METAL.
""" """
__version__='$Revision: 1.1 $'[11:-2] __version__='$Revision: 1.2 $'[11:-2]
import os, sys, traceback import os, sys, traceback
from TAL.TALParser import TALParser from TAL.TALParser import TALParser
...@@ -157,6 +157,9 @@ class PageTemplate: ...@@ -157,6 +157,9 @@ class PageTemplate:
def __call__(self, **kwargs): def __call__(self, **kwargs):
return self.pt_render(extra_context={'options': kwargs}) return self.pt_render(extra_context={'options': kwargs})
def pt_errors(self):
return self._v_errors
def pt_diagnostic(self): def pt_diagnostic(self):
return ('<html><body>\n' return ('<html><body>\n'
'<h4>Page Template Diagnostics</h4>\n' '<h4>Page Template Diagnostics</h4>\n'
......
...@@ -87,7 +87,7 @@ ...@@ -87,7 +87,7 @@
An implementation of a generic TALES engine An implementation of a generic TALES engine
""" """
__version__='$Revision: 1.1 $'[11:-2] __version__='$Revision: 1.2 $'[11:-2]
import re, sys import re, sys
from MultiMapping import MultiMapping from MultiMapping import MultiMapping
...@@ -97,11 +97,17 @@ _parse_expr = re.compile(r"(%s):(.*)" % NAME_RE).match ...@@ -97,11 +97,17 @@ _parse_expr = re.compile(r"(%s):(.*)" % NAME_RE).match
_valid_name = re.compile('%s$' % NAME_RE).match _valid_name = re.compile('%s$' % NAME_RE).match
class TALESError(Exception): class TALESError(Exception):
'''TALES Error''' __allow_access_to_unprotected_subobjects__ = 1
def __init__(self, expression, info=(None, None, None)):
self.type, self.value, self.traceback = info
self.expression = expression
class RegistrationError(TALESError): class RegistrationError(Exception):
'''TALES Type Registration Error''' '''TALES Type Registration Error'''
class CompilerError(Exception):
'''TALES Compiler Error'''
class Iterator: class Iterator:
'''Simple Iterator class for use in Contexts''' '''Simple Iterator class for use in Contexts'''
def __init__(self, name, seq, context): def __init__(self, name, seq, context):
...@@ -168,7 +174,7 @@ class Engine: ...@@ -168,7 +174,7 @@ class Engine:
try: try:
handler = self.types[type] handler = self.types[type]
except KeyError: except KeyError:
raise TALESError, ( raise CompilerError, (
'Unrecognized expression type "%s".' % type) 'Unrecognized expression type "%s".' % type)
try: try:
return handler(type, expr, self) return handler(type, expr, self)
...@@ -244,8 +250,7 @@ class Context: ...@@ -244,8 +250,7 @@ class Context:
try: try:
return expression(self) return expression(self)
except: except:
raise TALESError, "%s\n %s" % (expression, raise TALESError, (`expression`, sys.exc_info())
"%s:%s" % sys.exc_info()[:2])
evaluateValue = evaluate evaluateValue = evaluate
......
...@@ -87,7 +87,7 @@ ...@@ -87,7 +87,7 @@
Zope object encapsulating a Page Template. Zope object encapsulating a Page Template.
""" """
__version__='$Revision: 1.2 $'[11:-2] __version__='$Revision: 1.3 $'[11:-2]
import os, AccessControl, Acquisition, sys import os, AccessControl, Acquisition, sys
from Globals import DTMLFile, MessageDialog, package_home from Globals import DTMLFile, MessageDialog, package_home
...@@ -152,6 +152,8 @@ class ZopePageTemplate(PageTemplate, Script, Historical, Cacheable, ...@@ -152,6 +152,8 @@ class ZopePageTemplate(PageTemplate, Script, Historical, Cacheable,
pt_editForm = DTMLFile('dtml/ptEdit', globals()) pt_editForm = DTMLFile('dtml/ptEdit', globals())
manage = manage_main = pt_editForm manage = manage_main = pt_editForm
pt_diagnostic = DTMLFile('dtml/ptDiagnostic', globals())
security.declareProtected('Change Page Templates', security.declareProtected('Change Page Templates',
'pt_editAction', 'pt_setTitle', 'pt_edit', 'pt_editAction', 'pt_setTitle', 'pt_edit',
'pt_upload', 'pt_changePrefs') 'pt_upload', 'pt_changePrefs')
......
<dtml-var manage_page_header>
<dtml-var expr="manage_form_title(this(), _,
form_title='Page Template Diagnostics',
)">
<p class="form-help">
This Page Template needs the following changes in order to operate.
</p>
<dtml-in expr="container.pt_errors()">
<p class="form-help>
&dtml-sequence-item;
</p>
</dtml-in>
<dtml-var manage_page_footer>
...@@ -13,7 +13,7 @@ class ExpressionTests(unittest.TestCase): ...@@ -13,7 +13,7 @@ class ExpressionTests(unittest.TestCase):
e.compile('x/y') e.compile('x/y')
e.compile('string:Fred') e.compile('string:Fred')
e.compile('string:A$B') e.compile('string:A$B')
e.compile('string:a${x/y}b') e.compile('string:a ${x/y} b ${y/z} c')
e.compile('python: 2 + 2') e.compile('python: 2 + 2')
def test_suite(): def test_suite():
......
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