sandbox.py (1803B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\script\sys\sandbox.py 2 from future.utils import raise_ 3 import dis 4 5 def _get_opcodes(codeobj): 6 i = 0 7 opcodes = {} 8 s = codeobj.co_code 9 while i < len(s): 10 code = ord(s[i]) 11 opcodes[code] = True 12 if code >= dis.HAVE_ARGUMENT: 13 i += 3 14 else: 15 i += 1 16 17 return opcodes.keys() 18 19 20 def fingerprint(*args): 21 allCodes = {} 22 for expr in args: 23 try: 24 c = compile(expr, '', 'eval') 25 except: 26 raise_(ValueError, '%s is not a valid expression' % strx(expr)) 27 28 for code in _get_opcodes(c): 29 allCodes[code] = True 30 31 return allCodes.keys() 32 33 34 constant_codes = fingerprint('+1', '-1L', "'asdf'", "u'asdf'", '(1,2)', '[1,2]') 35 expression_codes = fingerprint('+1', '-1L', "'asdf'", "u'asdf'", '(1,2)', '[1,2]', '(1)', '1+1', '1-1', '2*2', '2/2', '2%2', '2**2', '~2', '1<<1', '1>>1', '1&1', '1|1', '1 or 1', '1 and 1', 'not 1') 36 37 def test_expr(expr, allowed_codes): 38 try: 39 c = compile(expr, '', 'eval') 40 except: 41 raise_(ValueError, '%s is not a valid expression' % strx(expr)) 42 43 codes = _get_opcodes(c) 44 for code in codes: 45 if code not in allowed_codes: 46 raise_(ValueError, 'opcode %s not allowed' % dis.opname[code]) 47 48 return c 49 50 51 def eval_fingerprinted(expr, fingerprint, g = None, l = None): 52 c = test_expr(expr, fingerprint) 53 if l is not None: 54 return eval(c, g, l) 55 if g is not None: 56 return eval(c, g) 57 return eval(c) 58 59 60 def eval_constant(expr, g = None, l = None): 61 return eval_fingerprinted(expr, constant_codes, g, l) 62 63 64 def eval_expression(expr, g = None, l = None): 65 return eval_fingerprinted(expr, expression_codes, g, l)