Exemplo n.º 1
0
def execute_cpp(untrusted_code, input_values, limits):
    result = []
    with epicbox.working_directory() as workdir:
        value = epicbox.run(
            "gcc_compile",
            "g++ -pipe -O2 -static -o main main.cpp",
            files=[{
                "name": "main.cpp",
                "content": untrusted_code
            }],
            workdir=workdir,
        )
        if value["stderr"]:
            return [value]

        for val in input_values:
            result.append(
                epicbox.run(
                    "gcc_run",
                    "./main",
                    stdin=val,
                    limits=limits,
                    workdir=workdir,
                ))
    return result
Exemplo n.º 2
0
    def processCompileAndRun(self):
        with epicbox.working_directory() as working_dir:
            self.pingMessage(
                {"success": "CMPL", "message": "Compiling your code"})
            compile_result = self.compiler.compile(
                working_dir, self.untrusted_code)
            if(compile_result["exit_code"] != 0):
                return self.pingMessage({"error": "CE", "message": compile_result["stderr"]})
            self.pingMessage(
                {"success": "CMPLS", "message": "Compilation Success"})

            testcase_number = 0
            for input in self.inputs:
                testcase_number = testcase_number + 1

                self.pingMessage(
                    {"success": "RUN", "message": "Running on testcase #" + str(testcase_number)})
                run_result = self.compiler.run(working_dir, input)

                if(run_result["oom_killed"] or run_result["timeout"] or run_result["exit_code"]):
                    return self.pingRunError(run_result, testcase_number)

                print(run_result)
                eval_result = self.matchOutput(
                    run_result["stdout"], self.outputs[testcase_number - 1])
                if(eval_result == False):
                    return self.pingMessage({"error": "WA", "message": "Wrong answer on testcase #" + str(testcase_number)})

                self.pingMessage(
                    {"success": "ACS", "message": "Correct on testcase #" + str(testcase_number)})

            return self.pingMessage({"success": "AC", "message": "Accepted Solution"})
Exemplo n.º 3
0
def execute_java(untrusted_code, input_values, limits):
    result = []
    with epicbox.working_directory() as workdir:
        text = untrusted_code.decode("UTF-8")
        text = text.split()
        name_of_class = text[text.index("class") + 1].replace("{", "")
        files = [{"name": f"{name_of_class}.java", "content": untrusted_code}]

        value = epicbox.run(
            "java",
            f"javac {name_of_class}.java",
            files=files,
            workdir=workdir,
            limits=limits,
        )
        if value["stderr"]:
            return [value]

        for val in input_values:
            result.append(
                epicbox.run(
                    "java",
                    f"java {name_of_class}",
                    files=files,
                    workdir=workdir,
                    stdin=val,
                    limits=limits,
                ))
    return result
Exemplo n.º 4
0
    def check(self, reply, clue):
        studio_files = [{
            'name': 'main.qrs',
            'content': attachment_content(reply)
        }]
        with epicbox.working_directory() as workdir:
            # noinspection PyAttributeOutsideInit
            self.log = logger.bind(workdir=workdir)
            if self.source.fields_archive:
                # TODO: extract all xmls from archive and upload using one epicbox run
                fields_files = [{
                    'name': 'fields.zip',
                    'content': attachment_content(self.source.fields_archive[0])
                }]
                self.log.info("Uploading and unpacking fields archive")
                command = 'mkdir -p fields/main && unzip fields.zip -d fields/main'
                result = epicbox.run('trik', command=command, files=fields_files,
                                     limits=UNARCHIVE_LIMITS, workdir=workdir)
                if result['exit_code'] != 0:
                    raise PluginError("Failed to extract fields from the archive")

            self.log.info("Starting trik sandbox")
            result = epicbox.run('trik', files=studio_files,
                                 limits=EPICBOX_TRIK_LIMITS, workdir=workdir)
            return self._process_checker_result(result, workdir)
Exemplo n.º 5
0
def sandbox_asm64(code, stdins=[""], callback=print):
    files = [{'name': 'main.asm', 'content': code.encode()}]
    compile_limits = {'cputime': 3, 'memory': 128}
    run_limits = {'cputime': 1, 'memory': 64}

    with epicbox.working_directory() as workdir:
        result = epicbox.run('asm64_compile',
                             'nasm -f elf64 -g main.asm',
                             files=files,
                             limits=compile_limits,
                             workdir=workdir)
        result['type'] = 'compile'
        callback(result)

        if result["exit_code"] == 0:
            result = epicbox.run('asm64_compile',
                                 'gcc -m64 -no-pie main.o -o main',
                                 files=files,
                                 limits=compile_limits,
                                 workdir=workdir)
            result['type'] = 'compile'
            callback(result)

            if result["exit_code"] == 0:
                for stdin in stdins:
                    result = epicbox.run('asm64_run',
                                         './main',
                                         files=files,
                                         limits=run_limits,
                                         workdir=workdir,
                                         stdin=stdin)
                    result['type'] = 'run'
                    callback(result)
Exemplo n.º 6
0
 def __init__(self, config, source, limits=None):
     self.source = source
     self.limits = limits
     self.filename = config.get('filename', self.filename)
     self.profile = config.get('profile', self.profile)
     self.command = config.get('command', self.command)
     self.workdir = None
     self._workdir_context_manager = epicbox.working_directory()
     self._is_source_saved = False
Exemplo n.º 7
0
 def __init__(self, config, source, limits=None):
     self.source = source
     self.limits = limits
     self.filename = config.get('filename', self.filename)
     self.profile = config.get('profile', self.profile)
     self.command = config.get('command', self.command)
     self.workdir = None
     self._workdir_context_manager = epicbox.working_directory()
     self._is_source_saved = False
Exemplo n.º 8
0
def cpp(code: str, testcase_dir: str) -> SubmissionResult:
    files = [{'name': 'main.cpp', 'content': code}]

    result = SubmissionResult()

    PROFILES = {
        'gcc_compile': {
            'docker_image': 'stepik/epicbox-gcc:6.3.0',
            'user': '******',
        },
        'gcc_run': {
            'docker_image': 'stepik/epicbox-gcc:6.3.0',
            # It's safer to run untrusted code as a non-root user (even in a container)
            'user': '******',
            'read_only': True,
            'network_disabled': True,
        }
    }

    epicbox.configure(profiles=PROFILES)

    test_no = 0
    with epicbox.working_directory() as workdir:
        compilation_output = epicbox.run('gcc_compile',
                                         'g++ -std=c++14 -O2 -o main main.cpp',
                                         files=files,
                                         workdir=workdir)

        if compilation_output['exit_code'] != 0:
            result.add_testcase_verdict(test_no, False,
                                        Verdict.COMPILATION_ERROR, 0)
            result.add_log(compilation_output['stderr'])
            return result

        while test_no < MAX_NUMBER_OF_TESTCASES:
            stdin, expected = get_input_expected_output(testcase_dir, test_no)

            if stdin == None or expected == None:
                break

            output = epicbox.run('gcc_run',
                                 './main',
                                 stdin=stdin,
                                 limits=limits['cpp'],
                                 workdir=workdir)

            process_output(test_no, output, expected, result)

            test_no += 1

    return result
Exemplo n.º 9
0
def execute_python(untrusted_code, input_values, limits):
    result = []
    with epicbox.working_directory() as workdir:
        files = [{"name": "main.py", "content": untrusted_code}]
        for val in input_values:
            result.append(
                epicbox.run(
                    "python",
                    "python3 main.py",
                    files=files,
                    workdir=workdir,
                    stdin=val,
                    limits=limits,
                ))
    return result
def run(code, lang):
    epicbox.configure(profiles=PROFILES)

    with epicbox.working_directory() as workdir:

        if lang == 'python':
            result = epicbox.run(
                'python',
                'python3 main.py',
                files=[{
                    'name': 'main.py',
                    'content': code
                }],
                limits=LIMITS,
                workdir=workdir,
            )

        elif lang == 'text/x-java':
            compile_result = epicbox.run(
                'java_compile',
                'javac Main.java',
                files=[{
                    'name': 'Main.java',
                    'content': code
                }],
                limits=LIMITS,
                workdir=workdir,
            )
            if compile_result['exit_code'] != 0:
                return compile_result
            else:
                result = epicbox.run(
                    'java_run',
                    'java Main',
                    files=[{
                        'name': 'Main.java',
                        'content': code
                    }],
                    limits=LIMITS,
                    workdir=workdir,
                )

        else:
            return 'FATAL: Language Unsupported'

        return result
Exemplo n.º 11
0
def build_tests(workdir):
    config = validate_work_config(workdir)
    if config['language'] == 'c':
        compiler = 'gcc'
    else:
        compiler = 'g++'
    with epicbox.working_directory() as wd:
        epicbox.configure(profiles=PROFILES)
        if config['type'] == 'multiple':
            for exercise in config['exercises']:
                if 'reference' in exercise['tests']:
                    build_each(exercise, compiler, wd)
        else:
            if 'reference' not in config['tests']:
                print('REFERENCE IS NOT DEFINED FOR CONFIG')
            else:
                build_each(config, compiler, wd)
Exemplo n.º 12
0
def sandbox_csharp(code, stdins=[""], callback=print):
    files = [{'name': 'main.cs', 'content': code.encode()}]
    compile_limits = {'cputime': 3, 'memory': 128}
    run_limits = {'cputime': 1, 'memory': 64}

    with epicbox.working_directory() as workdir:
        result = epicbox.run('mono_compile',
                             'csc main.cs',
                             files=files,
                             limits=compile_limits,
                             workdir=workdir)
        result['type'] = 'compile'
        callback(result)

        if result["exit_code"] == 0:
            for stdin in stdins:
                result = epicbox.run('mono_run',
                                     'mono main.exe',
                                     files=files,
                                     limits=run_limits,
                                     workdir=workdir,
                                     stdin=stdin)
                result['type'] = 'run'
                callback(result)
Exemplo n.º 13
0
def grade_epicbox(
    compiler: str,
    prepared_files: dict,
    tests: list,
    flags: str,
    docker_limits: dict,
    stop_if_fails: bool,
    memcheck: bool,
) -> list:
    """
    Running grading script in a separate Docker container.
    https://github.com/StepicOrg/epicbox

    :param submission: Student submission received from message broker.
    :param script_name: Name of the grading script.
    :param prepared_files: List of files and their paths.
    :param docker_profile: Epicbox profile.
    :param docker_limits: Docker container limits.
    :return: Results of grading.
    """
    logger: Logger = get_logger("process_answer")
    PROFILES = {
        'test_code': {
            'docker_image': 'test',
            'user': '******',
            'read_only': False,
            'network_disabled': True,
        }
    }
    epicbox.configure(profiles=PROFILES)
    with epicbox.working_directory() as wd:

        comp = compile_code(compiler, flags, prepared_files, wd)
        if comp['exit_code'] != 0:
            return [{'status': 'CE', 'log': comp['stderr'].decode()}]
        test_results = []
        for test in tests:
            test_case = epicbox.run('test_code',
                                    './main',
                                    stdin=test['input'],
                                    limits=docker_limits,
                                    workdir=wd)
            test_case['stdout'] = test_case['stdout'].decode()
            test_case['stderr'] = test_case['stderr'].decode()
            if test_case['timeout']:
                result = {'status': 'TL', 'test_name': test['test_name'], 'input': test['input'], \
                                            'correct_output': test['output'], 'answer': test_case}
            elif test_case['oom_killed']:
                result = {'status': 'ML', 'test_name': test['test_name'], 'input': test['input'], \
                                            'correct_output': test['output'], 'answer': test_case}
            elif test_case['stdout'] != test['output']:
                result = {'status': 'WA', 'test_name': test['test_name'], 'input': test['input'], \
                                            'correct_output': test['output'], 'answer': test_case}
            else:
                result = {'status': 'OK', 'test_name': test['test_name'], 'input': test['input'], \
                                            'correct_output': test['output'], 'answer': test_case}
            if stop_if_fails == True and result['status'] != 'OK':
                test_results.append(result)
                break
            if memcheck == True and result['status'] == 'OK':
                memory_check = check_valgrind(test_input, limits, wd)
                if memory_check['exitcode'] != 0:
                    result['memcheck'] = {
                        'memcheck': 'ERROR',
                        'log': memory_check['stderr'].decode()
                    }
                else:
                    result['memcheck'] = {'memcheck': 'OK'}
            test_results.append(result)
    logger.debug("Result: %s", result)

    return test_results
Exemplo n.º 14
0
def start():
    """
        Call this in a with statement to retrieve the executor object
    """
    with epicbox.working_directory() as workdir:
        yield _Executor(workdir)
Exemplo n.º 15
0
    'valgrind_check': {
        'docker_image': 'test',
        'user': '******',
        'read_only': False,
        'network_disabled': True,
    },
}

epicbox.configure(profiles=PROFILES)

untrusted_code = ''
with open('main.c', 'r') as f:
    untrusted_code = f.read().encode()

FILES = [{'name': 'main.c', 'content': untrusted_code}]
with epicbox.working_directory() as wd:
    epicbox.run('gcc_compile', 'gcc main.c -o main', files=FILES, workdir=wd)
    res = epicbox.run('gcc_run',
                      './main',
                      limits={
                          'cputime': 1,
                          'memory': 64
                      },
                      workdir=wd)
    with open('leakcheck.py', 'r') as mem:
        FILES += [{'name': 'memcheck.py', 'content': mem.read().encode()}]
    leakcheck = epicbox.run('valgrind_check',
                            'python3 memcheck.py',
                            files=FILES,
                            limits={
                                'cputime': 5,