def do_ingrep(self, cmd): """ usage: ingrep <task> <pattern> <filepath> Tries to grep through the specified ASCII file using .incbin directive. """ brutejudge.cheats.cheating(self) cmd = shlex.split(cmd) if len(cmd) != 3: return self.do_help('ingrep') task, pattern, file = cmd tasks = task_list(self.url, self.cookie) try: task_id = tasks.index(task) except ValueError: raise BruteError("No such task.") out = io.StringIO() incat(self, task, task_id, file, out, '''\ istringstream sin(included_s); string s2; string l; while (getline(sin, l)) { if (l.find("'''+pattern.replace('\\', '\\\\').replace('"', '\\"')+'''") != l.npos) { s2 += l; s2 += '\\n'; } } included_s = s2; ''') print(out.getvalue())
def format_scoreboard(aug=lambda y, x: x): url, cookie = force_session() with bj.may_cache(url, cookie): try: data = bj.scoreboard(url, cookie) except BruteError as e: bottle.response.status = 500 return aug(True, '<pre>' + html.escape(str(e)) + '</pre>') except: bottle.response.status = 500 return aug(True, '<pre>Internal server error</pre>') tasks = bj.task_list(url, cookie) task = pkgutil.get_data('ejui', 'scoreboard_task.html').decode('utf-8') tasks = ''.join(task.format(name=html.escape(i)) for i in tasks) contestant = pkgutil.get_data('ejui', 'contestant.html').decode('utf-8') contestant_task = pkgutil.get_data('ejui', 'contestant_task.html').decode('utf-8') contestants = [] for index, (data, scores) in enumerate(data): cur_tasks = ''.join( '<td></td>' if i == None else contestant_task. format(kind=(('ok' if i['attempts'] >= 0 else 'fail' ) if 'attempts' in i else 'unknown'), score=sb_format_single(i)) for i in scores) contestants.append( contestant.format(index=index + 1, nickname=data['name'], tasks=cur_tasks)) return aug( False, pkgutil.get_data('ejui', 'scoreboard.html').decode('utf-8').format( tasks=tasks, contestants=''.join(contestants)))
def format_page(page, text, tl=None, subms=None, clars=None): url, cookie = force_session() if tl == None: tl = bj.task_list(url, cookie) if clars == None: clars = list(zip(*bj.clars(url, cookie))) if subms == None: subms = format_submissions(None)[2] data = [('main', '', '/', '<b>ejui</b>')] for i, j in enumerate(tl): data.append(('task%d' % i, '', '/task/%d' % i, html.escape(j))) data2 = [('error', '', '', '<div id="error_btn">!</div>'), ('subms', '', '/submissions', 'Submissions'), ('scoreboard', '', '/scoreboard', 'Scoreboard'), ('logout', 'toolbar_icon', '/logout', '<img src="/logout.png" alt="Log out" />')] if clars or page == 'clars': data2.insert(3, ('clars', 'toolbar_icon', '/clars', '<img src="/mail.png" alt="Clarifications" />')) head = '' for a, b, c, d in data: if a == page: b += ' selected' head += '<a id="toolbar_item_' + a + '" class="' + b + '" href="' + c + '" onclick="ajax_load(this); return false"' head += '>' + d + '</a>' head += '</td><td align=right>' for a, b, c, d in data2: head += '<a id="' + a + '" class="' + b + '" href="' + c + '" onclick="ajax_load(this); return false"' if a == page: head += ' class=selected' head += '>' + d + '</a>' head += '' if page.startswith('task'): curr_task = repr(tl[int(page[4:])]) else: curr_task = 'null' return pkgutil.get_data('ejui', 'skel.html').decode('utf-8').format( task=curr_task, subm_preload=json.dumps(subms), head=head, body=text)
def task_page(task): task = int(task) url, cookie = force_session() with bj.may_cache(url, cookie): tl = bj.task_list(url, cookie) td = task_data(task, tl=tl) t1 = pkgutil.get_data('ejui', 'task.html').decode('utf-8') t2 = pkgutil.get_data('ejui', 'compiler.html').decode('utf-8') subms, any_subms, json_subms = format_submissions(td['name']) if any_subms: subms = pkgutil.get_data( 'ejui', 'task_subms.html').decode('utf-8').format(subms=subms) else: subms = '' compilers = '' for a, b, c in td['compilers']: compilers += t2.format(id=a, short_name=html.escape(b), long_name=html.escape(c)) if td['compilers']: compilers = pkgutil.get_data( 'ejui', 'compilers.html').decode('utf-8').format(data=compilers) return format_page('task%d' % task, t1.format(id=task, name=html.escape(td['name']), subms=subms, compilers=compilers), tl=tl, subms=json_subms)
def clar_form(task): task = int(task) url, cookie = force_session() tl = bj.task_list(url, cookie) if task not in range(len(tl)): abort(404) name = tl[task] return format_page( 'clars', pkgutil.get_data('ejui', 'submit_clar.html').decode('utf-8').format( id=task, name=html.escape(name)))
def easy_incat(self, task, filepath, custom_include=None, binary=True): try: task_id = task_list(self.url, self.cookie).index(task) except ValueError: raise BruteError("No such task.") x = io.StringIO() incat(self, task, task_id, filepath, x, filter=(base64_filter if binary else ''), custom_include=custom_include) x.seek(0) ans = x.read() if binary: ans = base64.b64decode(ans.encode('ascii')) return ans
def do_brute(self, cmd): """ usage: brute <task> <reader> [dump_path] [max_count] Tries to retrieve the test cases using binary search. """ brutejudge.cheats.cheating(self) sp = cmd.split() if len(sp) not in range(2, 5): return self.do_help('brute') tasks = task_list(self.url, self.cookie) try: task_id = tasks.index(sp[0]) except ValueError: raise BruteError("No such task.") try: with open(sp[1]) as file: code = file.read() except FileNotFoundError: raise BruteError("File not found.") srch = Searcher(self.url, self.cookie, task_id, input_file=getattr(self, 'input_file', None), output_file=getattr(self, 'output_file', None)) max_tests = -1 if len(sp) == 4: try: max_tests = int(sp[3]) except ValueError: raise BruteError("max_tests must be a number") srch.execute(code, max_tests) if len(sp) == 2 or sp[2] == '-': from sys import stdout as file do_close = False else: try: file = open(sp[2], "a") except IOError as e: raise BruteError("Error creating output file: " + str(e)) do_close = True for i, t in enumerate(srch.tests): print("---------- test #", i, sep='', file=file) print(t, file=file)
def task_data(task, tl=None): task = int(task) url, cookie = force_session() with bj.may_cache(url, cookie): if tl == None: tl = bj.task_list(url, cookie) if task not in range(len(tl)): abort(404) name = tl[task] tids = bj.task_ids(url, cookie) try: tid = tids[task] except IndexError: compilers = [] else: try: compilers = bj.compiler_list(url, cookie, tid) except BruteError: compilers = [] return {'name': name, 'compilers': compilers}
def format_page(page, text, tl=None, subms=None, clars=None, status=None, scores=None, jjs_devmode=None): url, cookie = force_session() with bj.may_cache(url, cookie): if tl == None: tl = bj.task_list(url, cookie) if clars == None: try: clars = list(zip(*bj.clars(url, cookie))) except: clars = [] if status == None: try: status = bj.status(url, cookie) except: status = {} if scores == None: try: scores = bj.scores(url, cookie) except: scores = {} if subms == None: subms = format_submissions(None)[2] if jjs_devmode == None: jjs_devmode = get_contest_info(url, cookie)[2].get( 'jjs_devmode', False) data = [('main', '', '/', '<b>ejui</b>', '')] dyn_style = '' for i, j in enumerate(tl): if status.get(j, None) != None or scores.get(j, None) != None: st = status.get(j, 'True') sc = scores.get(j, 0) c1 = get_submission_color(st, sc, 1) c2 = get_submission_color(st, sc, 2) c = 'data-color1="%s" data-color2="%s" data-taskid="%s"' % ( c1, c2, html.escape(j)) dyn_style += '#toolbar_item_task%d\n{\n background: %s !important;\n}\n\n' % ( i, c2 if page == 'task%d' % i else c1) else: c = 'data-taskid="%s"' % html.escape(j) data.append(('task%d' % i, '', '/task/%d' % i, html.escape(j), c)) if dyn_style: dyn_style = '<style id="dyn_style">\n' + dyn_style.strip( ) + '\n</style>' data2 = [('error', '', '', '<div id="error_btn">!</div>', ''), ('subms', '', '/submissions', 'Submissions', ''), ('scoreboard', '', '/scoreboard', 'Scoreboard', ''), ('logout', 'toolbar_icon', '/logout', '<img src="/logout.png" alt="Log out" />', '')] if clars or page == 'clars': data2.insert(3, ('clars', 'toolbar_icon', '/clars', '<img src="/mail.png" alt="Clarifications" />', '')) head = '' for a, b, c, d, e in data: if a == page: b += ' selected' head += '<a id="toolbar_item_' + a + '" class="' + b + '" href="' + c + '" onclick="ajax_load(this); return false"' if e: head += ' ' + e head += '>' + d + '</a>' head += '</td><td align=right>' for a, b, c, d, e in data2: head += '<a id="toolbar_item_' + a + '" class="' + b + '" href="' + c + '" onclick="ajax_load(this); return false"' if a == page: head += ' class=selected' if e: head += ' ' + e head += '>' + d + '</a>' head += '' if page.startswith('task'): curr_task = repr(tl[int(page[4:])]) else: curr_task = 'null' return pkgutil.get_data('ejui', 'skel.html').decode('utf-8').format( body_style=(' style="background: url(/jjs_devmode.svg)"' if jjs_devmode else ''), task=curr_task, subm_preload=json.dumps(subms), dynamic_styles=dyn_style, head=head, body=text)
def do_score100(self, cmd): """ usage: score100 <task> <test_cnt> || score100 <subm_id> || score100 <task> <start-end> Submit a solution that will get a score of 100. If `task` and `test_cnt` are supplied, will submit a solution for task `task` that will pass `test_cnt` tests. If `subm_id` is supplied, `task` and `test_cnt` will be taken from that. If `start` and `end` are supplied, the task is assumed to have from `start` to `end` tests, the exact number will be retrieved using binary search. """ brutejudge.cheats.cheating(self) sp = cmd.split() if len(sp) not in (1, 2): return self.do_help('score100') if not isinstance(self.url, Ejudge): raise BruteError("score100 only works on ejudge.") lx, ly = submission_list(self.url, self.cookie) if len(sp) == 1: if not sp[0].isnumeric(): raise BruteError("Submission ID must be a number.") subm_id = int(sp[0]) try: sp[0] = ly[lx.index(subm_id)].strip() except (ValueError, IndexError): raise BruteError("No such submission.") x, y = submission_results(self.url, self.cookie, subm_id) sp.append(str(len(x))) tasks = task_list(self.url, self.cookie) if sp[0] not in tasks: raise BruteError("No such task.") task_id = tasks.index(sp[0]) try: if '-' in sp[1]: spa, spb = sp[1].split('-', 1) test_cnt_low = int(spa) test_cnt_high = int(spb) + 1 else: test_cnt_low = test_cnt_high = int(sp[1]) test_cnt_low -= 1 test_cnt_high += 1 except ValueError: raise BruteError("test_cnt must be a number or a pair of numbers. (e.g. 1 or 1-2)") contest_id = self.url.contest_id code0 = ('//random: %r\n#define EXECUTE_FLAGS 08\n#include "'+'../'*16+'home/judges/%06d/problems/%s/Makefile"\n')%(random.random(), contest_id, sp[0]) lang_id = get_possible_lang_id(self, ('g++', 'g++-32', 'gcc', 'gcc-32'), task_id) submit(self.url, self.cookie, task_id, lang_id, code0) lx2, ly2 = submission_list(self.url, self.cookie) if len(lx2) == len(lx): raise BruteError("Error while sending.") while still_running(submission_status(self.url, self.cookie, lx2[0])): pass tailcode = get_tailcode(self, lx2[0], 'Makefile') tp = '%02d' cp = '%02d.a' for l in tailcode.split('\n'): if l.startswith('EXECUTE_FLAGS = '): tp = l.split('--test-pattern=', 1)[1].split()[0] cp = l.split('--corr-pattern=', 1)[1].split()[0] while test_cnt_high - test_cnt_low > 1: test_cnt = (test_cnt_high + test_cnt_low) // 2 code = '' for i in range(test_cnt): code += ('asm("test_%d:\\n.incbin \\"'+'../'*16+'home/judges/%06d/problems/%s/tests/'+tp+'\\"\\n.byte 0");\n')%(i, contest_id, sp[0], i + 1) code += ('asm("ans_%d:\\n.incbin \\"'+'../'*16+'home/judges/%06d/problems/%s/tests/'+cp+'\\"\\n.byte 0");\n')%(i, contest_id, sp[0], i + 1) code += 'extern char test_%d[];\n'%i code += 'extern char ans_%d[];\n'%i code += '\n//random: %r\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\nint main()\n{'%random.random()+r''' int buf_sz = 1; void* buf = (void*)0; while (1) { buf = realloc(buf, buf_sz); int bytes_read = fread((void*)(((char*)buf)+buf_sz/2), 1, (buf_sz+1)/2, stdin); if (bytes_read < (buf_sz+1)/2) { *(((char*)buf)+buf_sz/2+bytes_read) = 0; break; } buf_sz *= 2; } fprintf(stderr, "%s", (char*)buf); ''' for i in range(test_cnt): code += ' if (!strcmp((char*)buf, test_%d)) {\n'%i code += ' printf("%%s", ans_%d);\n'%i code += ' return 0;\n }\n' code += ' printf("Sorry, I don\'t know the answer!\\n");\n' code += ' return 0;\n}\n' submit(self.url, self.cookie, task_id, lang_id, code) lx3, ly3 = submission_list(self.url, self.cookie) if len(lx2) == len(lx3): raise BruteError("Error while sending.") lx2, ly2 = lx3, ly3 while True: status = submission_status(self.url, self.cookie, lx2[0]) if not still_running(status): break if status == 'OK': return elif status == ('Compilation error', 'Compiler failed'): test_cnt_high = test_cnt else: test_cnt_low = test_cnt raise BruteError("Unknown failure, probably an interactive task.")