从数据库中取出的数据必须写入本地文件中才能进行编译。
写入成功后就进行下一阶段的代码安全性检测。
成功就行下一阶段的代码编辑。
将数据写入本地文件:
def get_code(solution_id, problem_id, language):
'''从数据库获取代码并写入work目录下对应的文件'''
file_name = {
"c": "main.c",
"c++": "main.cpp",
"java": "Main.java",
'ruby': "main.rb",
"perl": "main.pl",
"pascal": "main.pas",
"go": "main.go",
"lua": "main.lua",
'python': 'main.py',
'python3': 'main.py',
"haskell": "main.hs"
}
select_code_sql = "select submit_code_text from judgeOL_submitcode where id = " + str(solution_id)
feh = run_sql(select_code_sql)
if feh is not None:
try:
code = feh[0][0]
except:
logging.info("1 cannot get code of runid %s" % solution_id)
return False
else:
logging.info("2 cannot get code of runid %s" % solution_id)
return False
try:
work_path = os.path.join(config.work_dir, str(solution_id))
#low_level()
os.mkdir(work_path)
except OSError as e:
if str(e).find("exist") > 0: # 文件夹已经存在
pass
else:
logging.info(e)
return False
try:
if file_name[language]:
logging.info("The language is : "+file_name[language])
else:
logging.info("Wrong language name")
real_path = os.path.join(
work_path,
file_name[language])
except KeyError as e:
logging.info(e)
return False
try:
#low_level()
f = codecs.open(real_path, 'w')
try:
f.write(code)
except:
logging.info("%s not write code to file" % solution_id)
f.close()
return False
f.close()
except OSError as e:
logging.info(e)
return False
return True
进行代码安全性检测:
def check_dangerous_code(solution_id, language):
if language in ['python2', 'python3']:
dir_work = os.path.join(config.work_dir, str(solution_id),"main.py")
code = file(dir_work).readlines()
support_modules = [
're', # 正则表达式
'sys', # sys.stdin
'string', # 字符串处理
'scanf', # 格式化输入
'math', # 数学库
'cmath', # 复数数学库
'decimal', # 数学库,浮点数
'numbers', # 抽象基类
'fractions', # 有理数
'random', # 随机数
'itertools', # 迭代函数
'functools',
#Higher order functions and operations on callable objects
'operator', # 函数操作
'readline', # 读文件
'json', # 解析json
'array', # 数组
'sets', # 集合
'queue', # 队列
'types', # 判断类型
]
for line in code:
if line.find('import') >= 0:
words = line.split()
tag = 0
for w in words:
if w in support_modules:
tag = 1
break
if tag == 0:
return False
return True
if language in ['gcc', 'g++']:
try:
dir_work = os.path.join(config.work_dir, str(solution_id),"main.c")
code = file(dir_work).read()
except:
dir_work = os.path.join(config.work_dir, str(solution_id),"main.cpp")
code = file(dir_work).read()
if code.find('system') >= 0:
return False
return True
if language == 'java':
dir_work = os.path.join(config.work_dir, str(solution_id),"Main.java")
code = file(dir_work).read()
if code.find('Runtime.')>=0:
return False
return True
if language == 'go':
dir_work = os.path.join(config.work_dir, str(solution_id),"main.go")
code = file(dir_work).read()
danger_package = [
'os', 'path', 'net', 'sql', 'syslog', 'http', 'mail', 'rpc', 'smtp', 'exec', 'user',
]
for item in danger_package:
if code.find('"%s"' % item) >= 0:
return False
return True