forked from raylu/sbot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
code_eval.py
112 lines (105 loc) · 3.94 KB
/
code_eval.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
from os import path
import subprocess
chroot_dir = path.join(path.dirname(path.abspath(__file__)), 'chroot')
MB = 1024 * 1024
def nodejs(cmd):
args = ['../nsjail/nsjail', '-Mo', '--rlimit_as', '700', '--chroot', chroot_dir,
'-R/usr', '-R/lib', '-R/lib64', '--user', 'nobody', '--group', 'nogroup',
'--time_limit', '2', '--disable_proc', '--iface_no_lo',
'--cgroup_mem_max', str(50 * MB), '--cgroup_pids_max', '6', '--quiet', '--',
'/usr/bin/nodejs', '--print', prep_input(cmd.args)]
proc = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, universal_newlines=True)
stdout, stderr = proc.communicate()
if proc.returncode == 0:
output = stdout
elif proc.returncode == 109:
output = 'timed out'
else:
split = stderr.split('\n', 5)
try:
output = split[4]
except IndexError:
if split[0].startswith('FATAL ERROR:'):
output = split[0]
else:
output = 'unknown error'
reply(cmd, output)
def ruby(cmd):
args = ['../nsjail/nsjail', '-Mo', '--chroot', chroot_dir,
'-R/usr', '-R/lib', '-R/lib64', '--user', 'nobody', '--group', 'nogroup',
'--time_limit', '2', '--disable_proc', '--iface_no_lo',
'--cgroup_mem_max', str(50 * MB), '--cgroup_pids_max', '2', '--quiet', '--',
'/usr/bin/ruby', '-Ue', prep_input(cmd.args)]
proc = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, universal_newlines=True)
stdout, stderr = proc.communicate()
if proc.returncode == 109:
output = 'timed out or memory limit exceeded'
else:
output = stdout
if stderr:
output += '\n' + stderr
reply(cmd, output)
def python2(cmd):
args = ['../nsjail/nsjail', '-Mo', '--chroot', chroot_dir, '-E', 'LANG=en_US.UTF-8',
'-R/usr', '-R/lib', '-R/lib64', '--user', 'nobody', '--group', 'nogroup',
'--time_limit', '2', '--disable_proc', '--iface_no_lo',
'--cgroup_mem_max', str(50 * MB), '--cgroup_pids_max', '1', '--quiet', '--',
'/usr/bin/python2', '-ESs', '/run.py']
proc = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, universal_newlines=True)
stdout, stderr = proc.communicate(prep_input(cmd.args))
if proc.returncode == 0:
output = stdout
elif proc.returncode == 1:
try:
output = stderr.split('\n')[-2]
except IndexError:
output = ''
elif proc.returncode == 109:
output = 'timed out or memory limit exceeded'
else:
output = 'unknown error'
reply(cmd, output)
def python3(cmd):
args = ['../nsjail/nsjail', '-Mo', '--chroot', chroot_dir, '-E', 'LANG=en_US.UTF-8',
'-R/usr', '-R/lib', '-R/lib64', '--user', 'nobody', '--group', 'nogroup',
'--time_limit', '2', '--disable_proc', '--iface_no_lo',
'--cgroup_mem_max', str(50 * MB), '--cgroup_pids_max', '1', '--quiet', '--',
'/usr/bin/python3', '-ISq', '/run.py']
proc = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, universal_newlines=True)
stdout, stderr = proc.communicate(prep_input(cmd.args))
if proc.returncode == 0:
output = stdout
elif proc.returncode == 1:
try:
output = stderr.split('\n')[-2]
except IndexError:
output = ''
elif proc.returncode == 109:
output = 'timed out or memory limit exceeded'
else:
output = 'unknown error'
reply(cmd, output)
def prep_input(args):
args = args.lstrip()
if args.startswith('```') and args.endswith('```'):
split = args[3:].split('\n', 1)
if len(split) == 2:
language, other_lines = args[3:].split('\n', 1)
if language in ['python', 'py', 'javascript', 'js', 'ruby', 'rb']:
return other_lines[:-3]
# otherwise, after backticks was code, not language: '```print(1)```'
return args.strip('`').strip()
def reply(cmd, output):
split = output.split('\n', 10)
output = '\n'.join(split[:10])
output = output[:500]
if len(split) == 11:
output += '\n(too many output lines)'
message = cmd.sender['username'] + ':'
output = '`%s`' % output.replace('`', r'\`')
embed = {'description': output}
cmd.reply(message, embed)