1
2
3
4
5
6
7
8
9
10
11
12
13 """Very Safe Python Expressions
14 """
15 __rcs_id__='$Id: VSEval.py 1069 2008-11-13 21:55:43Z stefan $'
16 __version__='$Revision: 1069 $'[11:-2]
17
18 from string import translate, strip
19 import string
20 gparse=None
21
22 nltosp=string.maketrans('\r\n',' ')
23
25 l=len(ind)
26 if l==2: return s[ind[0]:ind[1]]
27 elif l==1: return s[ind[0]:]
28 return s[:]
29
31
32
33
34 r=c=1
35 s=None
36 for factor in factors:
37 try:
38 l=len(factor)
39 s=1
40 except TypeError:
41 c=c*factor
42 if s and c > 1000:
43 raise TypeError, \
44 'Illegal sequence repeat (too many repetitions: %d)' % c
45 r=r*factor
46 return r
47
48
49 default_globals={
50 '__builtins__':{},
51 '__guarded_mul__': careful_mul,
52 '__guarded_getattr__': lambda env, inst, name: getattr(inst, name),
53 '__guarded_getitem__': lambda env, coll, key: coll[key],
54 '__guarded_getslice__': default_slicer,
55 }
56
57
58
60 """Provide a very-safe environment for evaluating expressions
61
62 This class lets you overide operations, __power__, __mul__,
63 __div__, __mod__, __add__, __sub__, __getitem__, __lshift__,
64 __rshift__, __and__, __xor__, __or__,__pos__, __neg__, __not__,
65 __repr__, __invert__, and __getattr__.
66
67 For example, __mult__ might be overridden to prevent expressions like::
68
69 'I like spam' * 100000000
70
71 or to disallow or limit attribute access.
72
73 """
74
76 """Create a 'safe' expression
77
78 where:
79
80 expr -- a string containing the expression to be evaluated.
81
82 globals -- A global namespace.
83 """
84 global gparse
85 if gparse is None: import gparse
86
87 expr=strip(expr)
88
89 self.__name__=expr
90 expr=translate(expr,nltosp)
91 self.expr=expr
92 self.globals=globals
93
94 co=compile(expr,'<string>','eval')
95
96 names=list(co.co_names)
97
98
99
100
101 for name in names:
102 if name[:1]=='_' and name not in ('_', '_vars', '_getattr'):
103 raise TypeError, 'illegal name used in expression'
104
105 used={}
106
107 i=0
108 code=co.co_code
109 l=len(code)
110 LOAD_NAME=101
111 HAVE_ARGUMENT=90
112 def HAS_ARG(op): ((op) >= HAVE_ARGUMENT)
113 while(i < l):
114 c=ord(code[i])
115 if c==LOAD_NAME:
116 name=names[ord(code[i+1])+256*ord(code[i+2])]
117 used[name]=1
118 i=i+3
119 elif c >= HAVE_ARGUMENT: i=i+3
120 else: i=i+1
121
122 self.code=gparse.compile(expr,'<string>','eval')
123 self.used=tuple(used.keys())
124
125 - def eval(self, mapping):
126 d={'_vars': mapping}
127 code=self.code
128 globals=self.globals
129 for name in self.used:
130 try: d[name]=mapping.getitem(name,0)
131 except KeyError:
132 if name=='_getattr':
133 d['__builtins__']=globals
134 exec compiled_getattr in d
135
136 return eval(code,globals,d)
137
139 return eval(self.code, self.globals, kw)
140
141 compiled_getattr=compile(
142 'def _getattr(o,n): return __guarded_getattr__(_vars,o,n)',
143 '<string>','exec')
144