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
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"})
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
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)
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)
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
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
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
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)
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)
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
def start(): """ Call this in a with statement to retrieve the executor object """ with epicbox.working_directory() as workdir: yield _Executor(workdir)
'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,