def compile_it(solution): """ 编译指定提交 """ result = { 'result': 'AC', 'compilation_info': '', } language = solution['language'] code = solution['code'] language_config = CONFIG['language'][language] # 写入代码文件 with open(language_config['filename'], 'w') as fw: fw.write(code) cmd = language_config['compile'].split() jl = JudgeLight( cmd[0], cmd, output_file_path='compile_stdout.txt', error_file_path='compile_stderr.txt', output_size_limit=655350, time_limit=5000, real_time_limit=10000, trace=False, ) stats = jl.run() # 判断编译错误 if stats['signum'] != 0: result['result'] = 'CE' # 写入编译错误信息 with open('compile_stderr.txt') as fr: result['compilation_info'] = fr.read() return result
def test_output_size_limit(self): code = ''' # include <stdio.h> int main() { for (int i = 0; i < 1000000; i++) { printf("Hello World!\\n"); } return 0; } ''' compile_it(code) jl = JudgeLight('./a.out', output_size_limit=10240, output_file_path='output.txt') stats = jl.run() self.assertEqual(stats['re_flag'], 1) with open('output.txt') as fr: l = len(fr.read()) self.assertTrue(l == 10240) clear_it() os.remove('output.txt')
def spj_check(): """ 评测 Special Judge 的答案 """ """ 对 SPJ 的题目,采用类似 testlib 的规范,即:SPJ 程序必须接收三个命令行参数 `./spj.exe <input-file> <output-file> <answer-file>` 规定 SPJ 程序必须命名为 `spj.exe`,如果有这个文件即为 SPJ 评测,否则为标准评测 """ cmd = 'spj.exe data.in output.txt data.out'.split() os.chmod('spj.exe', 500) jl = JudgeLight( cmd[0], cmd, output_file_path='spj_stdout.txt', error_file_path='spj_stderr.txt', output_size_limit=655350, time_limit=5000, real_time_limit=10000, trace=False, ) stats = jl.run() code = stats['signum'] if stats['re_flag'] != 0: return 'SE' if code == 0: return 'AC' elif code == 1: return 'WA' elif code == 2: return 'PE' return 'SE'
def test_a_add_b(self): code = ''' #include <stdio.h> int main() { int a, b; scanf("%d %d", &a, &b); printf("%d\\n", a + b); return 0; } ''' compile_it(code) in_data = '1 2' with open('input.txt', 'w') as fw: fw.write(in_data) jl = JudgeLight('./a.out', input_file_path='input.txt', output_file_path='output.txt') jl.run() with open('output.txt') as fr: self.assertEqual(fr.read().strip(), '3') clear_it() os.remove('input.txt') os.remove('output.txt')
def test_bigexe(self): # https://github.com/vijos/malicious-code/blob/master/bigexe.c code = ''' #include <stdio.h> char magic[1024 * 1024 * 1024] = { '\n' }; int main() { printf("hello, world"); printf(magic); return 0; } ''' with open('code.c', 'w') as fw: fw.write(code) jl = JudgeLight('/usr/bin/gcc', exec_args=['/usr/bin/gcc', 'code.c'], time_limit=5000, output_size_limit=1024000, trace=False, error_file_path='error.txt') stats = jl.run() self.assertEqual(stats['signum'], 1) os.remove('error.txt')
def compile_it(code, output_name='a.out'): with open('code.cpp', 'w') as fw: fw.write(code) jl = JudgeLight('/usr/bin/g++', exec_args=['/usr/bin/g++', 'code.cpp', '-o', output_name], trace=False, error_file_path='error.txt') jl.run() os.remove('error.txt')
def test_echo(self): jl = JudgeLight('/bin/echo', exec_args=['/bin/echo', 'Hello', 'World'], output_file_path='output.txt') stats = jl.run() self.assertEqual(stats['signum'], 0) self.assertEqual(stats['re_flag'], 0) with open('output.txt') as fr: self.assertEqual(fr.read().strip(), 'Hello World') os.remove('output.txt')
def test_requests(self): # nopass code = 'import requests' with open('code.py', 'w') as fw: fw.write(code) jl = JudgeLight('/usr/bin/python3', exec_args=['/usr/bin/python3', 'code.py'], allow_system_calls_rule='python') stats = jl.run() self.assertEqual(stats['re_flag'], 1) self.assertTrue(stats['re_syscall'] != 0 and stats['re_syscall'] != -1) os.remove('code.py')
def judge_one(solution, data, is_spj): """ 评测一组数据 """ # 复制数据文件到评测目录 shutil.copyfile(data['in'], 'data.in') time_limit = solution['time_limit'] memory_limit = solution['memory_limit'] language = solution['language'] result = {} language_config = CONFIG['language'][language] cmd = language_config['run'].split() jl = JudgeLight( cmd[0], cmd, time_limit=time_limit, memory_limit=memory_limit, real_time_limit=time_limit * 2 + 5000, output_size_limit=65535000, input_file_path='data.in', output_file_path='output.txt', error_file_path='error.txt', allow_system_calls_rule='default', ) stats = jl.run() result.update(stats) result['syscall'] = result.pop('re_syscall') shutil.copyfile(data['out'], 'data.out') # 判断该组状态 if stats['time_used'] > time_limit: result['result'] = 'TLE' elif stats['memory_used'] > memory_limit: result['result'] = 'MLE' elif stats['re_flag'] != 0: result['result'] = 'RTE' else: # 对答案进行判断 if is_spj: result['result'] = spj_check() else: result['result'] = std_check() # 删除本组文件 os.remove('data.in') os.remove('data.out') return result
def test_re(self): code = ''' #include <stdio.h> int main() { int a = 0 / 0; } ''' compile_it(code) jl = JudgeLight('./a.out') stats = jl.run() self.assertEqual(stats['re_flag'], 1) clear_it()
def test_signum(self): code = ''' #include <stdio.h> int main() { return 1; } ''' compile_it(code) jl = JudgeLight('./a.out') stats = jl.run() self.assertEqual(stats['signum'], 1) clear_it()
def test_cpu_time_limit(self): code = ''' int main() { while (1); } ''' compile_it(code) jl = JudgeLight('./a.out', time_limit=1000) stats = jl.run() self.assertEqual(stats['re_flag'], 1) # CPU 时间限制只能精确到秒,因此这里放宽限制 self.assertTrue(1000 <= stats['time_used'] <= 3000) clear_it()
def test_16g(self): # https://github.com/vijos/malicious-code/blob/master/16g.c code = 'main[-1u]={1};' with open('code.c', 'w') as fw: fw.write(code) jl = JudgeLight('/usr/bin/gcc', exec_args=['/usr/bin/gcc', 'code.c'], time_limit=5000, output_size_limit=1024000, trace=False, error_file_path='error.txt') stats = jl.run() self.assertEqual(stats['signum'], 1) os.remove('error.txt')
def test_real_time_limit(self): code = ''' # include <unistd.h> int main() { sleep(10); } ''' compile_it(code) jl = JudgeLight('./a.out', real_time_limit=1000) stats = jl.run() self.assertEqual(stats['re_flag'], 1) self.assertTrue(1000 <= stats['real_time_used'] <= 1500) clear_it()
def test_fork(self): # nopass code = ''' #include <unistd.h> int main() { int pid = fork(); return 0; } ''' compile_it(code) jl = JudgeLight('./a.out', allow_system_calls_rule='default') stats = jl.run() self.assertEqual(stats['re_flag'], 1) self.assertTrue(stats['re_syscall'] != 0 and stats['re_syscall'] != -1) clear_it()
def test_new(self): # pass code = ''' #include <iostream> using namespace std; int main() { int *a = new int; *a = 2; return *a; } ''' compile_it(code) jl = JudgeLight('./a.out', allow_system_calls_rule='default') stats = jl.run() self.assertEqual(stats['re_flag'], 0) clear_it()
def test_ctle(self): code = ''' #include </dev/random> ''' with open('code.c', 'w') as fw: fw.write(code) jl = JudgeLight('/usr/bin/gcc', exec_args=['/usr/bin/gcc', 'code.c'], time_limit=1000, real_time_limit=1000, output_size_limit=1024000, trace=False, error_file_path='error.txt') stats = jl.run() self.assertEqual(stats['re_flag'], 1) os.remove('error.txt') os.remove('code.c')
def test_malloc(self): # pass code = ''' #include <stdio.h> #include <stdlib.h> int main() { int *a = (int *) malloc(sizeof(int)); *a = 1; return *a; } ''' compile_it(code) jl = JudgeLight('./a.out', allow_system_calls_rule='default') stats = jl.run() self.assertEqual(stats['re_flag'], 0) clear_it()
def test_openat(self): # nopass code = ''' #include <fcntl.h> int main() { openat(0, "~/JudgeLight/tests/input.txt", O_CREAT | O_RDWR); return 0; } ''' compile_it(code) jl = JudgeLight('./a.out', allow_system_calls_rule='default') stats = jl.run() self.assertEqual(stats['re_flag'], 1) self.assertTrue(stats['re_syscall'] != 0 and stats['re_syscall'] != -1) clear_it()
def test_exec(self): # nopass code = ''' #include <unistd.h> int main() { char *const args[] = {"echo", "Hello", NULL}; execvp("echo", args); return 0; } ''' compile_it(code) jl = JudgeLight('./a.out', allow_system_calls_rule='default') stats = jl.run() self.assertEqual(stats['re_flag'], 1) self.assertTrue(stats['re_syscall'] != 0 and stats['re_syscall'] != -1) clear_it()
def test_ctle2(self): # https://github.com/vijos/malicious-code/blob/master/ctle2.cpp code = ''' struct x struct z<x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(y,x(y><y*,x(y*w>v<y*,w,x{} ''' with open('code.c', 'w') as fw: fw.write(code) jl = JudgeLight('/usr/bin/gcc', exec_args=['/usr/bin/gcc', 'code.c'], time_limit=1000, real_time_limit=1000, output_size_limit=1024000, trace=False, error_file_path='error.txt') stats = jl.run() self.assertEqual(stats['signum'], 1) os.remove('error.txt') os.remove('code.c')
def test_system(self): # nopass code = ''' #include <stdlib.h> int main() { system("echo Hello World"); } ''' compile_it(code) jl = JudgeLight('./a.out', allow_system_calls_rule='default', output_file_path='output.txt') stats = jl.run() self.assertEqual(stats['re_flag'], 1) with open('output.txt') as fr: self.assertEqual(fr.read().strip(), '') clear_it() os.remove('output.txt')
def test_hello(self): # pass code = ''' #include <stdio.h> int main() { printf("Hello World!\\n"); return 0; } ''' compile_it(code) jl = JudgeLight('./a.out', allow_system_calls_rule='default', output_file_path='output.txt') stats = jl.run() self.assertEqual(stats['re_flag'], 0) with open('output.txt') as fr: self.assertEqual(fr.read().strip(), 'Hello World!') clear_it() os.remove('output.txt')
def test_memory_limit(self): code = ''' # include <stdio.h> # include <stdlib.h> # define MAX 2000000 int *a[MAX]; int main(){ for (int i = 0; i < MAX; i++) { a[i] = (int *) malloc(sizeof(int)); } for (int i = 0; i < MAX; i++) { *a[i] = i; } int ans = 0; for (int i = 0; i < MAX; i++) { ans ^= *a[i]; } printf("%d\\n", ans); return 0; } ''' compile_it(code) jl = JudgeLight('./a.out', output_file_path='output.txt', memory_limit=4096, trace=False) stats = jl.run() self.assertEqual(stats['re_flag'], 1) clear_it() os.remove('output.txt')