修复部分情况下解析lrun输出结果失败的问题
因为lrun的输出也是重定向到stderr的,程序也可能向这里面输出,造成解析错误和潜在的伪造输出结果的问题。
This commit is contained in:
@@ -84,12 +84,26 @@ class JudgeClient(object):
|
|||||||
|
|
||||||
command += (" " +
|
command += (" " +
|
||||||
execute_command +
|
execute_command +
|
||||||
|
# 0就是stdin
|
||||||
" 0<" + self._test_case_dir + str(test_case_id) + ".in" +
|
" 0<" + self._test_case_dir + str(test_case_id) + ".in" +
|
||||||
|
# 1就是stdout
|
||||||
" 1>" + judger_workspace + str(test_case_id) + ".out" +
|
" 1>" + judger_workspace + str(test_case_id) + ".out" +
|
||||||
|
# 3是stderr,包含lrun的输出和程序的异常输出
|
||||||
" 3>&2")
|
" 3>&2")
|
||||||
return command
|
return command
|
||||||
|
|
||||||
def _parse_lrun_output(self, output):
|
def _parse_lrun_output(self, output):
|
||||||
|
# 要注意的是 lrun把结果输出到了stderr,所以有些情况下lrun的输出可能与程序的一些错误输出的混合的,要先分离一下
|
||||||
|
error = None
|
||||||
|
# 倒序找到MEMORY的位置
|
||||||
|
output_start = output.rfind("MEMORY")
|
||||||
|
if output_start == -1:
|
||||||
|
raise JudgeClientException("Lrun result parse error")
|
||||||
|
# 如果不是0,说明lrun输出前面有输出,也就是程序的stderr有内容
|
||||||
|
if output_start != 0:
|
||||||
|
error = output[0:output_start]
|
||||||
|
# 分离出lrun的输出
|
||||||
|
output = output[output_start:]
|
||||||
lines = output.split("\n")
|
lines = output.split("\n")
|
||||||
if len(lines) != 7:
|
if len(lines) != 7:
|
||||||
raise JudgeClientException("Lrun result parse error")
|
raise JudgeClientException("Lrun result parse error")
|
||||||
@@ -124,7 +138,7 @@ class JudgeClient(object):
|
|||||||
result[translate[name]] = None
|
result[translate[name]] = None
|
||||||
else:
|
else:
|
||||||
result[translate[name]] = translate[value]
|
result[translate[name]] = translate[value]
|
||||||
return result
|
return error, result
|
||||||
|
|
||||||
def _compare_output(self, test_case_id):
|
def _compare_output(self, test_case_id):
|
||||||
test_case_md5 = self._test_case_info["test_cases"][str(test_case_id)]["output_md5"]
|
test_case_md5 = self._test_case_info["test_cases"][str(test_case_id)]["output_md5"]
|
||||||
@@ -154,12 +168,12 @@ class JudgeClient(object):
|
|||||||
status_code, output = commands.getstatusoutput(command)
|
status_code, output = commands.getstatusoutput(command)
|
||||||
if status_code:
|
if status_code:
|
||||||
raise JudgeClientException(output)
|
raise JudgeClientException(output)
|
||||||
run_result = self._parse_lrun_output(output)
|
error, run_result = self._parse_lrun_output(output)
|
||||||
|
|
||||||
run_result["test_case_id"] = test_case_id
|
run_result["test_case_id"] = test_case_id
|
||||||
|
|
||||||
# 如果返回值非0 或者信号量不是0 代表非正常结束
|
# 如果返回值非0 或者信号量不是0 或者程序的stderr有输出 代表非正常结束
|
||||||
if run_result["exit_code"] or run_result["term_sig"] or run_result["siginaled"]:
|
if run_result["exit_code"] or run_result["term_sig"] or run_result["siginaled"] or error:
|
||||||
run_result["result"] = result["runtime_error"]
|
run_result["result"] = result["runtime_error"]
|
||||||
return run_result
|
return run_result
|
||||||
|
|
||||||
@@ -209,20 +223,53 @@ class JudgeClient(object):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
c_src = """
|
c_src = r"""
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
printf("Hello world");
|
FILE *fp;
|
||||||
|
|
||||||
|
fp = NULL;
|
||||||
|
fprintf(fp, "This is testing for fprintf...\n");
|
||||||
|
fputs("This is testing for fputs...\n", fp);
|
||||||
|
fclose(fp);
|
||||||
|
printf("111111");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
cpp_src = r"""
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int a,b;
|
||||||
|
cin >> a >> b;
|
||||||
|
cout << a+b;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
java_src = """
|
java_src = r"""
|
||||||
public class Main {
|
import java.io.*;
|
||||||
public static void main(String[] args) {
|
import java.util.*;
|
||||||
System.out.print("Hello world");
|
|
||||||
}
|
public class Main
|
||||||
|
{
|
||||||
|
public static void main(String[] args)
|
||||||
|
{
|
||||||
|
Scanner in = new Scanner(System.in);
|
||||||
|
PrintWriter out = new PrintWriter(System.out);
|
||||||
|
|
||||||
|
int a = in.nextInt();
|
||||||
|
int b = in.nextInt();
|
||||||
|
out.print(a + b);
|
||||||
|
throw new EmptyStackException();
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
def judge(languege_code, source_string):
|
def judge(languege_code, source_string):
|
||||||
@@ -243,4 +290,5 @@ def judge(languege_code, source_string):
|
|||||||
print client.run()
|
print client.run()
|
||||||
|
|
||||||
judge(1, c_src)
|
judge(1, c_src)
|
||||||
|
judge(2, cpp_src)
|
||||||
judge(3, java_src)
|
judge(3, java_src)
|
||||||
Reference in New Issue
Block a user