Package qm :: Package external :: Package DocumentTemplate :: Module VSEval
[hide private]
[frames] | no frames]

Source Code for Module qm.external.DocumentTemplate.VSEval

  1  ############################################################################## 
  2  # 
  3  # Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved. 
  4  # 
  5  # This software is subject to the provisions of the Zope Public License, 
  6  # Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution. 
  7  # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED 
  8  # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
  9  # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS 
 10  # FOR A PARTICULAR PURPOSE 
 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   
24 -def default_slicer(env, s, *ind):
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
30 -def careful_mul(env, *factors):
31 # r = result (product of all factors) 32 # c = count (product of all non-sequence factors) 33 # s flags whether any of the factors is a sequence 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
59 -class Eval:
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
75 - def __init__(self, expr, globals=default_globals):
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 # Check for valid names, disallowing names that begin with '_' or 99 # 'manage'. This is a DC specific rule and probably needs to be 100 # made customizable! 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
138 - def __call__(self, **kw):
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