示例#1
0
def execute_python(code, stdin='', explain=False):
    code = bytes(code, 'utf-8')
    stdin = bytes(stdin, 'utf-8')

    this_dir = dirname(__file__)

    with open(this_dir + '/script.py', 'rb') as script_file:
        script = script_file.read()
        jail_res = jail_code(
            'python',
            script,
            files=[
                this_dir + '/execplainator.py',
                this_dir + '/execplainator_encoder.py'
            ],
            extra_files=[
                ('code.py', code),
                ('stdin.txt', stdin),
            ],
            stdin=bytes(
                dumps({  # options
                    'trace': explain,
                }),
                'utf-8'),
        )

        return ExecuteResult(jail_res)
 def _run(self, grader_path, thecode, seed):
     files = SUPPORT_FILES + [grader_path]
     if self.locale_dir.exists():
         files.append(self.locale_dir)
     extra_files = [('submission.py', thecode.encode('utf-8'))]
     argv = ["-m", "grader_support.run", path(grader_path).basename(), 'submission.py', seed]
     r = jail_code(self.codejail_python, files=files, extra_files=extra_files, argv=argv)
     return r
示例#3
0
 def _run(self, grader_path, thecode, seed):
     files = SUPPORT_FILES + [grader_path]
     if self.locale_dir.exists():
         files.append(self.locale_dir)
     extra_files = [('submission.py', thecode.encode('utf-8'))]
     argv = [
         "-m", "grader_support.run",
         path(grader_path).basename(), 'submission.py', seed
     ]
     r = jail_code(self.codejail_python,
                   files=files,
                   extra_files=extra_files,
                   argv=argv)
     return r
示例#4
0
 def run(self, grader_path, tests, grabber, app, seed):
     files = SUPPORT_FILES + [grader_path]
     if self.locale_dir.exists():
         files.append(self.locale_dir)
     extra_files = [('submission.py', tests.encode('utf-8')),
                    ('grabber.py', grabber.encode('utf-8')),
                    ('flask_app.py', app.encode('utf-8'))]
     argv = [
         "-m", "grader_support.run",
         path(grader_path).basename(), 'submission.py', seed
     ]
     #self.log.warning("\nOne: {0}\nFiles: {1}\nExtra: {2}\nArgv: {3}".format(self.codejail_python, files, extra_files, argv))
     r = jail_code(self.codejail_python,
                   files=files,
                   extra_files=extra_files,
                   argv=argv)
     return r
def execute_python(code, stdin='', explain=False):
	this_dir = dirname(__file__)

	with open(this_dir + '/script.py', 'r') as script_file:
		script = script_file.read()
		jail_res = jail_code(
			'python', script,

			files = [this_dir + '/execplainator.py', this_dir + '/execplainator_encoder.py'],
			extra_files = [
				('code.py', code),
				('stdin.txt', stdin),
			],

			stdin = bytes(dumps({ # options
				'trace': explain,
			}), 'utf-8'),
		)

		return ExecuteResult(jail_res)
示例#6
0
文件: iofiles.py 项目: matts1/Kno
    def save(self):
        program = self.cleaned_data['program'].read().decode('UTF-8')
        zipfile = ZipFile(self.cleaned_data['zipfile'])
        for name in zipfile.namelist():
            prefix = '.'.join(name.split('.')[:-1])
            zipfile.extract(name, 'media/zips')  # potential race condition
            inputfile = zipfile.open(name)
            output = jail_code('python3', program, stdin=inputfile.read()).stdout
            outfile = open('media/zips/testout', 'w')
            outfile.write(output.decode('UTF-8'))
            outfile.close()

            TestCase(
                name=prefix,
                task=self.cleaned_data['task'],
                infile=InMemoryUploadedFile(open('media/zips/' + name), 'infile', name, 'text/plain', len(inputfile.read()), None),
                outfile=InMemoryUploadedFile(open('media/zips/testout'), 'outfile', prefix + '.out', 'text/plain', len(output), None),
                hidden=False,  # TODO: make user able to change this
                order=0,  # TODO: autoincrement this
            ).save()
示例#7
0
文件: codejail.py 项目: matts1/Kno
 def test_installed(self):
     self.assertEqual(
         jail_code('python3', 'print("Hello,", input())', stdin=b'Matt\n').stdout,
         b'Hello, Matt\n'
     )
示例#8
0
def safe_exec(code, globals_dict, files=None, python_path=None, slug=None):
    """
    Execute code as "exec" does, but safely.

    `code` is a string of Python code.  `globals_dict` is used as the globals
    during execution.  Modifications the code makes to `globals_dict` are
    reflected in the dictionary on return.

    `files` is a list of file paths, either files or directories.  They will be
    copied into the temp directory used for execution.  No attempt is made to
    determine whether the file is appropriate or safe to copy.  The caller must
    determine which files to provide to the code.

    `python_path` is a list of directory paths.  They will be copied just as
    `files` are, but will also be added to `sys.path` so that modules there can
    be imported.

    `slug` is an arbitrary string, a description that's meaningful to the
    caller, that will be used in log messages.

    Returns None.  Changes made by `code` are visible in `globals_dict`.  If
    the code raises an exception, this function will raise `SafeExecException`
    with the stderr of the sandbox process, which usually includes the original
    exception message and traceback.

    """
    the_code = []
    files = list(files or ())

    the_code.append(textwrap.dedent(
        """
        import sys
        try:
            import simplejson as json
        except ImportError:
            import json
        """
        # We need to prevent the sandboxed code from printing to stdout,
        # or it will pollute the json we print there.  This isn't a
        # security concern (they can put any values in the json output
        # anyway, either by writing to sys.__stdout__, or just by defining
        # global values), but keeps accidents from happening.
        """
        class DevNull(object):
            def write(self, *args, **kwargs):
                pass
        sys.stdout = DevNull()
        """
        # Read the code and the globals from the stdin.
        """
        code, g_dict = json.load(sys.stdin)
        """))

    for pydir in python_path or ():
        pybase = os.path.basename(pydir)
        the_code.append("sys.path.append(%r)\n" % pybase)
        files.append(pydir)

    the_code.append(textwrap.dedent(
        # Execute the sandboxed code.
        """
        exec code in g_dict
        """
        # Clean the globals for sending back as JSON over stdout.
        """
        ok_types = (
            type(None), int, long, float, str, unicode, list, tuple, dict
        )
        bad_keys = ("__builtins__",)
        def jsonable(v):
            if not isinstance(v, ok_types):
                return False
            try:
                json.dumps(v)
            except Exception:
                return False
            return True
        g_dict = {
            k:v
            for k,v in g_dict.iteritems()
            if jsonable(v) and k not in bad_keys
        }
        """
        # Write the globals back to the calling process.
        """
        json.dump(g_dict, sys.__stdout__)
        """))

    stdin = json.dumps([code, json_safe(globals_dict)])
    jailed_code = "".join(the_code)

    # Turn this on to see what's being executed.
    if LOG_ALL_CODE:        # pragma: no cover
        log.debug("Jailed code: %s", jailed_code)
        log.debug("Exec: %s", code)
        log.debug("Stdin: %s", stdin)

    res = jail_code.jail_code(
        "python", code=jailed_code, stdin=stdin, files=files, slug=slug,
    )
    if res.status != 0:
        raise SafeExecException(
            "Couldn't execute jailed code: %s" % res.stderr
        )
    globals_dict.update(json.loads(res.stdout))
示例#9
0
def safe_exec(code, globals_dict, files=None, python_path=None, slug=None):
    """
    Execute code as "exec" does, but safely.

    `code` is a string of Python code.  `globals_dict` is used as the globals
    during execution.  Modifications the code makes to `globals_dict` are
    reflected in the dictionary on return.

    `files` is a list of file paths, either files or directories.  They will be
    copied into the temp directory used for execution.  No attempt is made to
    determine whether the file is appropriate or safe to copy.  The caller must
    determine which files to provide to the code.

    `python_path` is a list of directory paths.  They will be copied just as
    `files` are, but will also be added to `sys.path` so that modules there can
    be imported.

    `slug` is an arbitrary string, a description that's meaningful to the
    caller, that will be used in log messages.

    Returns None.  Changes made by `code` are visible in `globals_dict`.  If
    the code raises an exception, this function will raise `SafeExecException`
    with the stderr of the sandbox process, which usually includes the original
    exception message and traceback.

    """
    the_code = []
    files = list(files or ())

    the_code.append(textwrap.dedent(
        """
        import sys
        try:
            import simplejson as json
        except ImportError:
            import json
        """
        # We need to prevent the sandboxed code from printing to stdout,
        # or it will pollute the json we print there.  This isn't a
        # security concern (they can put any values in the json output
        # anyway, either by writing to sys.__stdout__, or just by defining
        # global values), but keeps accidents from happening.
        """
        class DevNull(object):
            def write(self, *args, **kwargs):
                pass
        sys.stdout = DevNull()
        """
        # Read the code and the globals from the stdin.
        """
        code, g_dict = json.load(sys.stdin)
        """))

    for pydir in python_path or ():
        pybase = os.path.basename(pydir)
        the_code.append("sys.path.append(%r)\n" % pybase)
        files.append(pydir)

    the_code.append(textwrap.dedent(
        # Execute the sandboxed code.
        """
        exec code in g_dict
        """
        # Clean the globals for sending back as JSON over stdout.
        """
        ok_types = (
            type(None), int, long, float, str, unicode, list, tuple, dict
        )
        bad_keys = ("__builtins__",)
        def jsonable(v):
            if not isinstance(v, ok_types):
                return False
            try:
                json.dumps(v)
            except Exception:
                return False
            return True
        g_dict = {
            k:v
            for k,v in g_dict.iteritems()
            if jsonable(v) and k not in bad_keys
        }
        """
        # Write the globals back to the calling process.
        """
        json.dump(g_dict, sys.__stdout__)
        """))

    stdin = json.dumps([code, json_safe(globals_dict)])
    jailed_code = "".join(the_code)

    # Turn this on to see what's being executed.
    if LOG_ALL_CODE:        # pragma: no cover
        log.debug("Jailed code: %s", jailed_code)
        log.debug("Exec: %s", code)
        log.debug("Stdin: %s", stdin)

    res = jail_code.jail_code(
        "python", code=jailed_code, stdin=stdin, files=files, slug=slug,
    )
    if res.status != 0:
        raise SafeExecException(
            "Couldn't execute jailed code: %s" % res.stderr
        )
    globals_dict.update(json.loads(res.stdout))
示例#10
0
def jailpy(code=None, *args, **kwargs):
    """Run `jail_code` on Python."""
    if code:
        code = textwrap.dedent(code)
    return jail_code("python", code, *args, **kwargs)
示例#11
0
def jailpy(code=None, *args, **kwargs):
    """Run `jail_code` on Python."""
    if code:
        code = textwrap.dedent(code)
    return jail_code("python", code, *args, **kwargs)
示例#12
0
stdin_contents = ''
with open(sys.argv[6], "r") as f:
    stdin_contents = f.read()
output_file = sys.argv[8]
print "Output file: %s" % output_file
unit_test_code = None
if len(sys.argv) >= 10:
    with open(sys.argv[9], "r") as f:
        unit_test_code = f.read()
    print "Unit test code len: %d" % len(unit_test_code)

jail_code.configure('python', python_path, sandbox_user)
jail_code.set_limit('CPU', max_cpu)
jail_code.set_limit('VMEM', max_memory)
jail_code.set_limit('REALTIME', max_real_time)
result = jail_code.jail_code('python', source_code, \
  None, None, stdin_contents, "codemarathon", unit_test_code)

cpu_time = result.res_data.ru_utime + result.res_data.ru_stime
memory_usage = result.res_data.ru_maxrss * resource.getpagesize() / 1024
status = result.status
error_message = result.stderr

with open(output_file, "w") as f:
    f.write(result.stdout)

with open("stat", "w") as f:
    f.write("Time: %f\n" % cpu_time)
    f.write("Memory: %d\n" % memory_usage)
    f.write("Status: %d\n" % status)
    f.write(
        "==== STDERR contents BEGIN ====\n%s\n==== STDERR contents END ====\n"
示例#13
0
def safe_exec(
    code,
    globals_dict,
    files=None,
    python_path=None,
    limit_overrides_context=None,
    slug=None,
    extra_files=None,
):
    """
    Execute code as "exec" does, but safely.

    `code` is a string of Python code.  `globals_dict` is used as the globals
    during execution.  Modifications the code makes to `globals_dict` are
    reflected in the dictionary on return.

    `files` is a list of file paths, either files or directories.  They will be
    copied into the temp directory used for execution.  No attempt is made to
    determine whether the file is appropriate or safe to copy.  The caller must
    determine which files to provide to the code.

    `python_path` is a list of directory or file paths.  These names will be
    added to `sys.path` so that modules they contain can be imported.  Only
    directories and zip files are supported.  If the name is not provided in
    `extras_files`, it will be copied just as if it had been listed in `files`.

    `limit_overrides_context` is an optional string to use as a key against the
    configured limit overrides contexts. If omitted or if no such limit override context
    has been configured, then use the default limits.

    `slug` is an arbitrary string, a description that's meaningful to the
    caller, that will be used in log messages.

    `extra_files` is a list of pairs, each pair is a filename and a bytestring
    of contents to write into that file.  These files will be created in the
    temp directory and cleaned up automatically.  No subdirectories are
    supported in the filename.

    Returns None.  Changes made by `code` are visible in `globals_dict`.  If
    the code raises an exception, this function will raise `SafeExecException`
    with the stderr of the sandbox process, which usually includes the original
    exception message and traceback.

    """
    the_code = []

    files = list(files or ())
    extra_files = extra_files or ()
    python_path = python_path or ()

    extra_names = set(name for name, contents in extra_files)

    the_code.append(
        textwrap.dedent(
            """
        import sys
        import six
        try:
            import simplejson as json
        except ImportError:
            import json
        """

            # We need to prevent the sandboxed code from printing to stdout,
            # or it will pollute the json we print there.  This isn't a
            # security concern (they can put any values in the json output
            # anyway, either by writing to sys.__stdout__, or just by defining
            # global values), but keeps accidents from happening.
            """
        class DevNull(object):
            def write(self, *args, **kwargs):
                pass

            def flush(self, *args, **kwargs):
                pass
        sys.stdout = DevNull()
        """

            # Read the code and the globals from the stdin.
            """
        code, g_dict = json.load(sys.stdin)
        """))

    for pydir in python_path:
        pybase = os.path.basename(pydir)
        the_code.append("sys.path.append(%r)\n" % pybase)
        if pybase not in extra_names:
            files.append(pydir)

    the_code.append(
        textwrap.dedent(
            # Execute the sandboxed code.
            """
        exec(code, g_dict)
        """))

    the_code.append(inspect.getsource(json_safe))

    the_code.append(
        textwrap.dedent("""
        g_dict = json_safe(g_dict)
        """

                        # Write the globals back to the calling process.
                        """
        json.dump(g_dict, sys.__stdout__)
        """))

    stdin = json.dumps([code, json_safe(globals_dict)])
    jailed_code = "".join(the_code)

    # Turn this on to see what's being executed.
    if LOG_ALL_CODE:  # pragma: no cover
        log.debug("Jailed code: %s", jailed_code)
        log.debug("Exec: %s", code)
        log.debug("Stdin: %s", stdin)

    res = jail_code.jail_code(
        "python",
        code=jailed_code,
        stdin=stdin,
        files=files,
        limit_overrides_context=limit_overrides_context,
        slug=slug,
        extra_files=extra_files,
    )

    if LOG_ALL_CODE:
        log.debug("Status: %s", res.status)
        log.debug("Stdout: %s", res.stdout)
        log.debug("Stderr: %s", res.stderr)

    if res.status != 0:
        raise SafeExecException(
            ("Couldn't execute jailed code: stdout: {res.stdout!r}, "
             "stderr: {res.stderr!r} with status code: {res.status}").format(
                 res=res))
    globals_dict.update(json.loads(res.stdout.decode('utf-8')))
示例#14
0
 def test_jail_code_functional_invocation(self):
     result = jail_code('python3', 'print("Huzzah")')
     self.assertEqual(result, JailResult(status=0, stdout='Huzzah\n', stderr=''))
示例#15
0
def jailpy(code=None, *args, **kwargs):  # pylint: disable=keyword-arg-before-vararg
    """Run `jail_code` on Python."""
    if code:
        code = textwrap.dedent(code)
    return jail_code("python", code, *args, **kwargs)
示例#16
0
def safe_exec(code, globals_dict, files=None, python_path=None, slug=None,
              extra_files=None, settings_code=None, extra_imports=None, initial_code=None):
    """
    Execute code as "exec" does, but safely.

    `code` is a string of Python code.  `globals_dict` is used as the globals
    during execution.  Modifications the code makes to `globals_dict` are
    reflected in the dictionary on return.

    `files` is a list of file paths, either files or directories.  They will be
    copied into the temp directory used for execution.  No attempt is made to
    determine whether the file is appropriate or safe to copy.  The caller must
    determine which files to provide to the code.

    `python_path` is a list of directory or file paths.  These names will be
    added to `sys.path` so that modules they contain can be imported.  Only
    directories and zip files are supported.  If the name is not provided in
    `extras_files`, it will be copied just as if it had been listed in `files`.

    `slug` is an arbitrary string, a description that's meaningful to the
    caller, that will be used in log messages.

    `extra_files` is a list of pairs, each pair is a filename and a bytestring
    of contents to write into that file.  These files will be created in the
    temp directory and cleaned up automatically.  No subdirectories are
    supported in the filename.

    Returns None.  Changes made by `code` are visible in `globals_dict`.  If
    the code raises an exception, this function will raise `SafeExecException`
    with the stderr of the sandbox process, which usually includes the original
    exception message and traceback.

    """
    the_code = []

    files = list(files or ())
    extra_files = extra_files or ()
    python_path = python_path or ()

    extra_names = set(name for name, contents in extra_files)
    if isinstance(extra_imports, str) and len(extra_imports) > 0:
        the_code.append(textwrap.dedent(extra_imports).strip())

    if isinstance(settings_code, str) and len(settings_code) > 0:
        the_code.append(textwrap.dedent(settings_code).strip())

    the_code.append(textwrap.dedent(
        """
        import sys, numpy, pandas, json, math, pickle, random, traceback, io, matplotlib;matplotlib.use('svg')
        """
        # Read the code and the globals from the stdin.
        """
        data = sys.stdin.buffer.read()
        initial_code, code, g_dict = pickle.loads(data)
        if type(g_dict) == str:
            g_dict = pickle.loads(g_dict)
        """))

    for pydir in python_path:
        pybase = os.path.basename(pydir)
        the_code.append("sys.path.append(%r)\n" % pybase)
        if pybase not in extra_names:
            files.append(pydir)

    the_code.append(textwrap.dedent(
        # Execute the sandboxed code.
        """
        try:
            random.seed(0);numpy.random.seed(0)
            exec(initial_code, g_dict)
        except Exception as err:
            try:
                print(traceback.format_exc(0).encode("ascii", "ignore"))
            except UnicodeEncodeError:
                print("Unknown Error")
            raise err

        try:
            import matplotlib.pyplot as plt;plt.clf();random.seed(0);numpy.random.seed(0)
            exec(code, g_dict)
        except Exception as err:
            try:
                print(traceback.format_exc(0).encode("ascii", "ignore"))
            except UnicodeEncodeError:
                print("Unknown Error")
            raise err
        """
        # Clean the globals for sending back as JSON over stdout.
        """
        answer_key = "{0}{1}".format(SANDBOX_CORRECT_PREFIX,"correct_context")
        check_func_key = "{0}{1}".format(SANDBOX_CORRECT_PREFIX, "check_code_run")
        check_status_key = "{0}{1}".format(SANDBOX_CORRECT_PREFIX, "check_status")

        okay_list = [check_status_key]
        if g_dict[SANDBOX_CHECK_VARS_NAME] is not None:
            okay_list += g_dict[SANDBOX_CHECK_VARS_NAME]

        bad_keys = ("__builtins__", SANDBOX_CHECK_VARS_NAME, answer_key, check_func_key, check_status_key)
        def pickleable(v):
            try:
                pickle.dumps(v, protocol=pickle.HIGHEST_PROTOCOL)
            except Exception:
                return False
            return True
        if ANSWER_MODE:
            p_dict = {
                k:v
                for k,v in g_dict.items()
                if pickleable(v) and k in okay_list
            }
        else:
            p_dict = {
                k:v
                for k,v in g_dict.items()
                if pickleable(v) and k not in bad_keys and not k.startswith(SANDBOX_CORRECT_PREFIX)
            }

        def jsonable(v):
            try:
                val = json.dumps(v)
            except Exception:
                return False
            if len(val) > 100:
                return False
            return True

        def stringable(v):
            try:
                m = str(v)
            except Exception:
                return False
            if len(m) > 0 and len(m) < 100:
                return True
            return False

        def typeable(v):
            try:
                m = str(type(v))
            except Exception:
                return False
            return True

        def jsonable_nolength(v):
            try:
                val = json.dumps(v)
            except Exception:
                return False
            return True

        def stringable_nolength(v):
            try:
                m = str(v)
            except Exception:
                return False
            return True

        v_dict = {}
        for k, v in g_dict.items():
            if k in bad_keys or k.startswith(SANDBOX_CORRECT_PREFIX):
                continue
            elif k.startswith(DATAQUEST_PLOT_PREFIX):
                v_dict[k] = v.getvalue()
            elif v is None or (isinstance(v, float) and math.isnan(v)):
                v_dict[k] = "None"
            elif jsonable(v):
                v_dict[k] = v
            elif stringable(v):
                v_dict[k] = str(v)
            elif typeable(v):
                v_dict[k] = str(type(v))

        def make_real_var(k, v, bad_keys):
            if k in bad_keys or k.startswith(SANDBOX_CORRECT_PREFIX):
                return None
            elif isinstance(v, io.StringIO):
                return v.getvalue()
            elif jsonable_nolength(v):
                return v
            elif stringable_nolength(v):
                return str(v)
            elif typeable(v):
                return str(type(v))
            return None

        real_vars = {}
        for k, v in g_dict.items():
            val = make_real_var(k, v, bad_keys)
            if val is not None:
                real_vars[k] = val

        plots = []
        for var in g_dict[SANDBOX_CHECK_VARS_NAME]:
            if var.startswith(DATAQUEST_PLOT_PREFIX):
                given_var = g_dict.get(var)
                if given_var is not None:
                    plots.append(given_var.getvalue().strip())

        check_status = False
        if g_dict.get(check_func_key) is not None:
            exec(g_dict.get(check_func_key), g_dict)
            check_status, hint = g_dict.get(check_status_key)

        incorrect_vars = {}
        correct_vars = {}
        if answer_key in g_dict:
            answer_g_dict = g_dict[answer_key]
            if type(answer_g_dict) == str:
                try:
                    answer_g_dict = pickle.loads(answer_g_dict)
                except Exception:
                    answer_g_dict = pickle.loads(eval(answer_g_dict))
            for var in g_dict[SANDBOX_CHECK_VARS_NAME]:
                given_var = g_dict.get(var)
                correct_var = answer_g_dict.get(var)
                val = make_real_var(var, correct_var, [])
                if val is not None:
                    correct_vars[var] = val
                variable_okay = given_var is not None and type(given_var) == type(correct_var)
                if isinstance(given_var, io.StringIO) and isinstance(correct_var, str):
                    variable_okay = True
                if variable_okay:
                    if isinstance(correct_var, numpy.ndarray):
                        equal = numpy.array_equal(given_var, correct_var)
                    elif isinstance(correct_var, pandas.DataFrame) or isinstance(correct_var, pandas.Series):
                        equal = given_var.equals(correct_var)
                    elif var.startswith(DATAQUEST_PLOT_PREFIX):
                        if isinstance(correct_var, io.StringIO):
                            new_val = correct_var.getvalue().strip()
                        else:
                            new_val = correct_var.strip()
                        equal = False
                        for p in plots:
                            similarity = 0
                            if len(p) != len(new_val):
                                continue
                            try:
                                for i, s in enumerate(p):
                                    if s == new_val[i]:
                                        similarity += 1
                                if similarity/len(new_val) > .7:
                                    equal = True
                            except Exception:
                                pass
                    elif isinstance(correct_var, float):
                        # .sum() methods on numpy arrays vs the builtin sum function, among others, can have slight rounding differences.
                        # Adding this tolerance helps ensure those don't get flagged as incorrect.
                        equal = (correct_var - .001) <= given_var <= (correct_var + .001)
                    else:
                        equal = given_var == correct_var
                    variable_okay = variable_okay and equal
                if not variable_okay:
                    incorrect_vars[var] = {
                        "given_type": str(type(given_var)),
                        "correct_type": str(type(correct_var))
                    }
        """
        # Write the globals back to the calling process.
        """
        print("PICKLE_DATA:")
        d = pickle.dumps(p_dict, protocol=2)
        print(d)
        print("PICKLE_DATA:")
        json.dump(v_dict, sys.__stdout__)
        print("PICKLE_DATA:")
        json.dump(real_vars, sys.__stdout__)
        print("PICKLE_DATA:")
        json.dump(incorrect_vars, sys.__stdout__)
        print("PICKLE_DATA:")
        json.dump(correct_vars, sys.__stdout__)
        print("PICKLE_DATA:")
        json.dump(check_status, sys.__stdout__)
        """
    ))
    if initial_code is None:
        initial_code = ""
    stdin = pickle.dumps([initial_code, code, globals_dict], protocol=pickle.HIGHEST_PROTOCOL)
    jailed_code = "".join(the_code)

    # Turn this on to see what's being executed.
    if LOG_ALL_CODE:        # pragma: no cover
        log.debug("Jailed code: %s", jailed_code)
        log.debug("Exec: %s", code)
        log.debug("Stdin: %s", stdin)

    res = jail_code.jail_code(
        "python", code=jailed_code, stdin=stdin, files=files, slug=slug,
        extra_files=extra_files,
    )
    if res.status != 0:
        log.error("Couldn't execute jailed code: %s" % res.stderr)
        output = res.stdout.decode("utf-8")
        if output is not None:
            output = output[:100000]
        display_vars = {}
        real_vars = {}
        incorrect_vars = {}
        correct_vars = {}
        data = ""
        error = True
        check_status = False
    else:
        output = res.stdout.decode("utf-8")
        output, data, display_vars, real_vars, incorrect_vars, correct_vars, check_status = output.split("PICKLE_DATA:\n")
        display_vars = json.loads(display_vars)
        real_vars = json.loads(real_vars)
        incorrect_vars = json.loads(incorrect_vars)
        correct_vars = json.loads(correct_vars)
        check_status = json.loads(check_status)
        error = False
    globals_dict = {"output": output, "data": data, "display_vars": display_vars, "real_vars": real_vars, "incorrect_vars": incorrect_vars, "error": error, "correct_vars": correct_vars, "check": check_status}
    return globals_dict
示例#17
0
stdin_contents = ''
with open(sys.argv[6], "r") as f:
  stdin_contents = f.read()
output_file = sys.argv[8]
print "Output file: %s" % output_file
unit_test_code = None
if len(sys.argv) >= 10:
  with open(sys.argv[9], "r") as f:
    unit_test_code = f.read()
  print "Unit test code len: %d" % len(unit_test_code)

jail_code.configure('python', python_path, sandbox_user)
jail_code.set_limit('CPU', max_cpu)
jail_code.set_limit('VMEM', max_memory)
jail_code.set_limit('REALTIME', max_real_time)
result = jail_code.jail_code('python', source_code, \
  None, None, stdin_contents, "codemarathon", unit_test_code)

cpu_time = result.res_data.ru_utime + result.res_data.ru_stime
memory_usage = result.res_data.ru_maxrss * resource.getpagesize() / 1024
status = result.status
error_message = result.stderr

with open(output_file, "w") as f:
  f.write(result.stdout)

with open("stat", "w") as f:
  f.write("Time: %f\n" % cpu_time)
  f.write("Memory: %d\n" % memory_usage)
  f.write("Status: %d\n" % status)
  f.write("==== STDERR contents BEGIN ====\n%s\n==== STDERR contents END ====\n" % error_message)