Commit c2c58b42 authored by Evan Simpson's avatar Evan Simpson

Prevent traceback leaks.

parent 208e5a18
......@@ -89,7 +89,7 @@ Page Template-specific implementation of TALES, with handlers
for Python expressions, string literals, and paths.
"""
__version__='$Revision: 1.22 $'[11:-2]
__version__='$Revision: 1.23 $'[11:-2]
import re, sys
from TALES import Engine, CompilerError, _valid_name, NAME_RE, \
......@@ -180,16 +180,17 @@ class PathExpr:
vars = econtext.vars
exists = 0
for base, path, dp in self._paths:
path = list(path) # Copy!
# Expand dynamic path parts from right to left.
for i, varname in dp:
val = vars[varname]
if isinstance(val, StringType):
path[i] = val
else:
# If the value isn't a string, assume it's a sequence
# of path names.
path[i:i+1] = list(val)
if dp:
path = list(path) # Copy!
for i, varname in dp:
val = vars[varname]
if isinstance(val, StringType):
path[i] = val
else:
# If the value isn't a string, assume it's a sequence
# of path names.
path[i:i+1] = list(val)
try:
__traceback_info__ = base
if base == 'CONTEXTS':
......
......@@ -87,7 +87,7 @@
An implementation of a generic TALES engine
"""
__version__='$Revision: 1.22 $'[11:-2]
__version__='$Revision: 1.23 $'[11:-2]
import re, sys, ZTUtils
from MultiMapping import MultiMapping
......@@ -107,7 +107,11 @@ class TALESError(Exception):
self.setPosition(position)
def setPosition(self, position):
self.lineno = position[0]
self.offset = position[1]
self.offset = position[1]
def takeTraceback(self):
t = self.traceback
self.traceback = None
return t
def __str__(self):
if self.type is None:
s = self.expression
......@@ -314,8 +318,8 @@ class Context:
try:
v = expression(self)
if isinstance(v, Exception):
if hasattr(v, 'traceback'):
raise v, None, v.traceback
if isinstance(v, TALESError):
raise v, None, v.takeTraceback()
raise v
except TALESError, err:
err.setPosition(self.position)
......
......@@ -87,7 +87,7 @@
Zope object encapsulating a Page Template.
"""
__version__='$Revision: 1.23 $'[11:-2]
__version__='$Revision: 1.24 $'[11:-2]
import os, AccessControl, Acquisition, sys
from Globals import DTMLFile, ImageFile, MessageDialog, package_home
......@@ -275,7 +275,8 @@ class ZopePageTemplate(Script, PageTemplate, Historical, Cacheable,
result = self.pt_render(extra_context=bound_names)
except TALESError, err:
if err.type == 'Unauthorized':
raise err.type, err.value, err.traceback
raise err.type, err.value, err.takeTraceback()
err.takeTraceback()
raise
if keyset is not None:
# Store the result in the cache.
......
......@@ -140,6 +140,11 @@ class TALESError(TALError):
# This exception can carry around another exception + traceback
def takeTraceback(self):
t = self.info[2]
self.info = self.info[:2] + (None,)
return t
def __init__(self, msg, position=(None, None), info=(None, None, None)):
t, v, tb = info
if t:
......
......@@ -637,8 +637,11 @@ class TALInterpreter:
engine.beginScope()
err.lineno, err.offset = self.position
engine.setLocal('error', err)
self.interpret(handler)
engine.endScope()
try:
self.interpret(handler)
finally:
err.takeTraceback()
engine.endScope()
else:
self.restoreOutputState(state)
self.stream_write(stream.getvalue())
......
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