# `pwnlib.util.safeeval` — Safe evaluation of python code

pwnlib.util.safeeval._get_opcodes(codeobj) → [opcodes]

  Extract the actual opcodes as a list from a code object

      >>> c = compile("[1 + 2, (1,2)]", "", "eval")
      >>> _get_opcodes(c)
      [...100, 100, 103, 83]

pwnlib.util.safeeval.const(expression) → value

  Safe Python constant evaluation

  Evaluates a string that contains an expression describing a Python constant. Strings that are not valid Python expressions or that contain other code besides the constant raise ValueError.

  Examples

      >>> const("10")
      10
      >>> const("[1,2, (3,4), {'foo':'bar'}]")
      [1, 2, (3, 4), {'foo': 'bar'}]
      >>> const("[1]+[2]")
      Traceback (most recent call last):
      ...
      ValueError: opcode BINARY_ADD not allowed

pwnlib.util.safeeval.expr(expression) → value

  Safe Python expression evaluation

  Evaluates a string that contains an expression that only uses Python constants. This can be used to e.g. evaluate a numerical expression from an untrusted source.

  Examples

      >>> expr("1+2")
      3
      >>> expr("[1,2]*2")
      [1, 2, 1, 2]
      >>> expr("__import__('sys').modules")
      Traceback (most recent call last):
      ...
      ValueError: opcode LOAD_NAME not allowed

pwnlib.util.safeeval.test_expr(expr, allowed_codes) → codeobj

  Test that the expression contains only the listed opcodes. If the expression is valid and contains only allowed codes, return the compiled code object. Otherwise raise a ValueError

pwnlib.util.safeeval.values(expression, dict) → value

  Safe Python expression evaluation

  Evaluates a string that contains an expression that only uses Python constants and values from a supplied dictionary. This can be used to e.g. evaluate e.g. an argument to a syscall.

  Note: This is potentially unsafe if e.g. the __add__ method has side

    effects.

  Examples

      >>> values("A + 4", {'A': 6})
      10
      >>> class Foo:
      ...    def __add__(self, other):
      ...        print("Firing the missiles")
      >>> values("A + 1", {'A': Foo()})
      Firing the missiles
      >>> values("A.x", {'A': Foo()})
      Traceback (most recent call last):
      ...
      ValueError: opcode LOAD_ATTR not allowed