Skip to content

Commit a308321

Browse files
author
Richard Jones
committed
update PageTemplates to latest Zope codebase
1 parent ebdb167 commit a308321

File tree

7 files changed

+139
-147
lines changed

7 files changed

+139
-147
lines changed

roundup/cgi/PageTemplates/ComputedAttribute.py

Lines changed: 0 additions & 11 deletions
This file was deleted.

roundup/cgi/PageTemplates/Expressions.py

Lines changed: 57 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,32 @@
11
##############################################################################
22
#
33
# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
4-
#
4+
#
55
# This software is subject to the provisions of the Zope Public License,
66
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
77
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
88
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
99
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
1010
# FOR A PARTICULAR PURPOSE
11-
#
11+
#
1212
##############################################################################
13+
# Modified for Roundup:
14+
#
15+
# 1. Removed all Zope-specific code (doesn't even try to import that stuff now)
16+
# 2. Removed all Acquisition
1317

1418
"""Page Template Expression Engine
1519
1620
Page Template-specific implementation of TALES, with handlers
1721
for Python expressions, string literals, and paths.
18-
19-
20-
Modified for Roundup 0.5 release:
21-
22-
- Removed all Zope-specific code (doesn't even try to import that stuff now)
23-
- Removed all Acquisition
24-
- Made traceback info more informative
25-
2622
"""
27-
__docformat__ = 'restructuredtext'
2823

29-
__version__='$Revision: 1.9 $'[11:-2]
24+
__version__='$Revision: 1.10 $'[11:-2]
3025

3126
import re, sys
3227
from TALES import Engine, CompilerError, _valid_name, NAME_RE, \
3328
Undefined, Default, _parse_expr
34-
from string import strip, split, join, replace, lstrip
29+
3530

3631
_engine = None
3732
def getEngine():
@@ -53,10 +48,17 @@ def installHandlers(engine):
5348
reg('defer', DeferExpr)
5449

5550
from PythonExpr import getSecurityManager, PythonExpr
51+
guarded_getattr = getattr
5652
try:
5753
from zExceptions import Unauthorized
5854
except ImportError:
5955
Unauthorized = "Unauthorized"
56+
57+
def acquisition_security_filter(orig, inst, name, v, real_validate):
58+
if real_validate(orig, inst, name, v):
59+
return 1
60+
raise Unauthorized, name
61+
6062
def call_with_ns(f, ns, arg=1):
6163
if arg==2:
6264
return f(None, ns)
@@ -70,6 +72,8 @@ def __getitem__(self, module):
7072
__import__(module)
7173
return sys.modules[module]
7274

75+
SecureModuleImporter = _SecureModuleImporter()
76+
7377
Undefs = (Undefined, AttributeError, KeyError,
7478
TypeError, IndexError, Unauthorized)
7579

@@ -95,9 +99,9 @@ def render(ob, ns):
9599

96100
class SubPathExpr:
97101
def __init__(self, path):
98-
self._path = path = split(strip(path), '/')
102+
self._path = path = path.strip().split('/')
99103
self._base = base = path.pop(0)
100-
if not _valid_name(base):
104+
if base and not _valid_name(base):
101105
raise CompilerError, 'Invalid variable name "%s"' % base
102106
# Parse path
103107
self._dp = dp = []
@@ -123,7 +127,7 @@ def _eval(self, econtext,
123127
path[i:i+1] = list(val)
124128
base = self._base
125129
__traceback_info__ = 'path expression "%s"'%('/'.join(self._path))
126-
if base == 'CONTEXTS':
130+
if base == 'CONTEXTS' or not base:
127131
ob = econtext.contexts
128132
else:
129133
ob = vars[base]
@@ -138,15 +142,15 @@ def __init__(self, name, expr, engine):
138142
self._s = expr
139143
self._name = name
140144
self._hybrid = 0
141-
paths = split(expr, '|')
145+
paths = expr.split('|')
142146
self._subexprs = []
143147
add = self._subexprs.append
144148
for i in range(len(paths)):
145-
path = lstrip(paths[i])
149+
path = paths[i].lstrip()
146150
if _parse_expr(path):
147151
# This part is the start of another expression type,
148152
# so glue it back together and compile it.
149-
add(engine.compile(lstrip(join(paths[i:], '|'))))
153+
add(engine.compile(('|'.join(paths[i:]).lstrip())))
150154
self._hybrid = 1
151155
break
152156
add(SubPathExpr(path)._eval)
@@ -194,18 +198,18 @@ def __str__(self):
194198
def __repr__(self):
195199
return '%s:%s' % (self._name, `self._s`)
196200

197-
198-
_interp = re.compile(r'\$(%(n)s)|\${(%(n)s(?:/%(n)s)*)}' % {'n': NAME_RE})
201+
202+
_interp = re.compile(r'\$(%(n)s)|\${(%(n)s(?:/[^}]*)*)}' % {'n': NAME_RE})
199203

200204
class StringExpr:
201205
def __init__(self, name, expr, engine):
202206
self._s = expr
203207
if '%' in expr:
204-
expr = replace(expr, '%', '%%')
208+
expr = expr.replace('%', '%%')
205209
self._vars = vars = []
206210
if '$' in expr:
207211
parts = []
208-
for exp in split(expr, '$$'):
212+
for exp in expr.split('$$'):
209213
if parts: parts.append('$')
210214
m = _interp.search(exp)
211215
while m is not None:
@@ -219,15 +223,16 @@ def __init__(self, name, expr, engine):
219223
raise CompilerError, (
220224
'$ must be doubled or followed by a simple path')
221225
parts.append(exp)
222-
expr = join(parts, '')
226+
expr = ''.join(parts)
223227
self._expr = expr
224-
228+
225229
def __call__(self, econtext):
226230
vvals = []
227231
for var in self._vars:
228232
v = var(econtext)
229-
if isinstance(v, Exception):
230-
raise v
233+
# I hope this isn't in use anymore.
234+
## if isinstance(v, Exception):
235+
## raise v
231236
vvals.append(v)
232237
return self._expr % tuple(vvals)
233238

@@ -239,11 +244,14 @@ def __repr__(self):
239244

240245
class NotExpr:
241246
def __init__(self, name, expr, compiler):
242-
self._s = expr = lstrip(expr)
247+
self._s = expr = expr.lstrip()
243248
self._c = compiler.compile(expr)
244-
249+
245250
def __call__(self, econtext):
246-
return not econtext.evaluateBoolean(self._c)
251+
# We use the (not x) and 1 or 0 formulation to avoid changing
252+
# the representation of the result in Python 2.3, where the
253+
# result of "not" becomes an instance of bool.
254+
return (not econtext.evaluateBoolean(self._c)) and 1 or 0
247255

248256
def __repr__(self):
249257
return 'not:%s' % `self._s`
@@ -261,53 +269,45 @@ def __call__(self):
261269

262270
class DeferExpr:
263271
def __init__(self, name, expr, compiler):
264-
self._s = expr = lstrip(expr)
272+
self._s = expr = expr.lstrip()
265273
self._c = compiler.compile(expr)
266-
274+
267275
def __call__(self, econtext):
268276
return DeferWrapper(self._c, econtext)
269277

270278
def __repr__(self):
271279
return 'defer:%s' % `self._s`
272280

273-
class TraversalError:
274-
def __init__(self, path, name):
275-
self.path = path
276-
self.name = name
277281

278-
def restrictedTraverse(self, path, securityManager,
282+
def restrictedTraverse(object, path, securityManager,
279283
get=getattr, has=hasattr, N=None, M=[],
280284
TupleType=type(()) ):
281285

282286
REQUEST = {'path': path}
283287
REQUEST['TraversalRequestNameStack'] = path = path[:] # Copy!
284-
if not path[0]:
285-
# If the path starts with an empty string, go to the root first.
286-
self = self.getPhysicalRoot()
287-
path.pop(0)
288-
289288
path.reverse()
290-
object = self
291-
#print 'TRAVERSE', (object, path)
292-
done = []
289+
validate = securityManager.validate
290+
__traceback_info__ = REQUEST
293291
while path:
294292
name = path.pop()
295-
__traceback_info__ = TraversalError(done, name)
296293

297-
# if isinstance(name, TupleType):
298-
# object = apply(object, name)
299-
# continue
294+
if isinstance(name, TupleType):
295+
object = object(*name)
296+
continue
300297

301-
# if name[0] == '_':
302-
# # Never allowed in a URL.
303-
# raise AttributeError, name
298+
if not name:
299+
# Skip directly to item access
300+
o = object[name]
301+
# Check access to the item.
302+
if not validate(object, object, name, o):
303+
raise Unauthorized, name
304+
object = o
305+
continue
304306

305307
# Try an attribute.
306-
o = get(object, name, M)
307-
# print '...', (object, name, M, o)
308+
o = guarded_getattr(object, name, M)
308309
if o is M:
309310
# Try an item.
310-
# print '... try an item'
311311
try:
312312
# XXX maybe in Python 2.2 we can just check whether
313313
# the object has the attribute "__getitem__"
@@ -319,18 +319,15 @@ def restrictedTraverse(self, path, securityManager,
319319
# Try to re-raise the original attribute error.
320320
# XXX I think this only happens with
321321
# ExtensionClass instances.
322-
get(object, name)
322+
guarded_getattr(object, name)
323323
raise
324324
except TypeError, exc:
325325
if str(exc).find('unsubscriptable') >= 0:
326326
# The object does not support the item interface.
327327
# Try to re-raise the original attribute error.
328328
# XXX This is sooooo ugly.
329-
get(object, name)
329+
guarded_getattr(object, name)
330330
raise
331-
#print '... object is now', `o`
332331
object = o
333-
done.append((name, o))
334332

335333
return object
336-

0 commit comments

Comments
 (0)