Welcome, guest | Sign In | My Account | Store | Cart

This is a function that evaluate all expressions and statements and return the result as a string. It also return Exceptions as strings. It is used in trypython.jcubic.pl

Python, 27 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from StringIO import StringIO

def execute(code, _globals={}, _locals={}):
    import sys
    fake_stdout = StringIO()
    __stdout = sys.stdout
    sys.stdout = fake_stdout
    try:
        #try if this is expressions
        ret = eval(code, _globals, _locals)
        result = fake_stdout.getvalue()
        sys.stdout = __stdout
        if ret:
            result += str(ret)
        return result
    except:
        try:
            exec(code, _globals, _locals)
        except:
            sys.stdout = __stdout
            import traceback
            buf = StringIO()
            traceback.print_exc(file=buf)
            return buf.getvalue()
        else:
            sys.stdout = __stdout
            return fake_stdout.getvalue()

It change stdout to StringIO and try to return result of eval along with output, if fail it try to use exec and return output from that.

4 comments

James Mills 13 years, 2 months ago  # | flag

Nice impl. however I should point out to those that read this;

This is considered very evil and dangerous and UNLESS you trust the source of the data don't do things like this.

Otherwise, nice post :)

--JamesMills (prologic)

Jakub Jankiewicz (author) 13 years, 2 months ago  # | flag

This is the same evil and dangerous as eval/exec itself.

PS: I use this on JSON-RPC Interpreter but I block imports from 'os' and 'subprocess' modules and block access to files. I use this function:

import types

def check_env(env):
    "prevent exec('import x'.replace('x', 'os'))"
    modules = ['os', 'subprocess', 'posix']
    module_emsg = "For security reason you can't import '%s' module"
    fun_emsg = "For security reason you can't import functions from '%s' module"
    file_emsg = "For security reason you can't open files"
    for k, v in env.items():
        if type(v) == types.ModuleType and v.__name__ in modules:
            return module_emsg % v.__name__
        elif type(v) == types.FileType:
            return file_emsg
        elif type(v) == types.BuiltinFunctionType and v.__module__ in modules:
            if v.__module__ == 'posix':
                module = 'os'
            else:
                module = v.__module__
            return fun_emsg % module

I use 'posix' for 'os' because it's hosted on GNU/Linux.

Sunjay Varma 13 years, 2 months ago  # | flag

Go to this directory and read "text.txt" /home/jcubic/domains/jcubic.pl/public_html/trypython/cgi-bin

Exec is EVIL!

(Don't worry, I touched nothing else)

Jakub Jankiewicz (author) 13 years, 1 month ago  # | flag

I forget about modules inside modules this is list of all sub modules:

modules = ['os', 'copy_reg', 'UserDict', 'posixpath', 'errno', 'subprocess',
           'posix', 'popen2', 'urllib', 'shutil', 'UserDict', 'copy_reg',
           'errno', 'posixpath', 'sys', 'errno', 'fcntl', 'gc', 'os', 'pickle',
           'select', 'signal', 'sys', 'traceback', 'types', 'os', 'sys',
           'warnings', 'os', 'socket', 'ssl', 'string', 'sys', 'time',
           'errno', 'fnmatch', 'os', 'stat', 'sys']