def __init__(self, path, original_filename=None): self.filename = original_filename or path if self.filename.lower().endswith('.tar.gz'): ext = '.tar.gz' else: ext = os.path.splitext(self.filename)[1] self.archive = Archive(path, ext) self.config = None self.problem = None self.main_problem_instance = None self.rootdir = None self.short_name = None self.env = None self.package = None self.time_limits = None self.memory_limits = None self.statement_memory_limit = None self.prog_archive = None self.extra_compilation_args = { 'c': C_EXTRA_ARGS, 'cpp': C_EXTRA_ARGS, 'pas': PAS_EXTRA_ARGS, } self.use_make = settings.USE_SINOLPACK_MAKEFILES self.use_sandboxes = not settings.USE_UNSAFE_EXEC self.restrict_html = (settings.SINOLPACK_RESTRICT_HTML and not settings.USE_SINOLPACK_MAKEFILES)
def validate_zip(file): if file.name.upper().endswith(".ZIP"): archive = Archive(file, '.zip') if len(archive.filenames()) != 1: raise ValidationError( _("Archive should have only 1 file inside.") ) if (archive.extracted_size() > self.get_testrun_unzipped_input_limit()): raise ValidationError( _("Uncompressed archive is too big to be" " considered safe.") ) # Extraction is safe, see: # https://docs.python.org/2/library/zipfile.html#zipfile.ZipFile.extract tmpdir = tempfile.mkdtemp() try: # The simplest way to check validity # All other are kinda lazy and don't check everything archive.extract(tmpdir) # Zipfile has some undocumented exception types, we shouldn't # rely on those, thus we better catch all except Exception: raise ValidationError(_("Archive seems to be corrupted.")) finally: shutil.rmtree(tmpdir)
def _extract_makefiles(self): sinol_makefiles_tgz = os.path.join(os.path.dirname(__file__), 'files', 'sinol-makefiles.tgz') Archive(sinol_makefiles_tgz).extract(to_path=self.rootdir) makefile_in = os.path.join(self.rootdir, 'makefile.in') if not os.path.exists(makefile_in): with open(makefile_in, 'w') as f: f.write('MODE=wer\n') f.write('ID=%s\n' % (self.short_name, )) f.write('SIG=xxxx000\n')
def __init__(self, path, original_filename=None): self.filename = original_filename or path if self.filename.lower().endswith('.tar.gz'): ext = '.tar.gz' else: ext = os.path.splitext(self.filename)[1] self.archive = Archive(path, ext) self.config = None self.problem = None self.rootdir = None self.short_name = self._find_main_folder()
def download_problem_package_file_view(request, package_id, file_name): package = _get_package(request, package_id, 'contests.contest_admin') archive = Archive(package.package_file) dir_path = tempfile.mkdtemp(dir=tempfile.gettempdir()) try: archive.extract(to_path=dir_path) filepath = os.path.join(dir_path, file_name) if os.path.isfile(filepath): return stream_file(File(open(filepath)), os.path.basename(os.path.normpath(file_name))) finally: shutil.rmtree(dir_path)
def problem_site_package_download_file(request, problem): original_package = OriginalPackage.objects.get(problem=problem) problem = original_package.problem package = original_package.problem_package contest = problem.contest archive = Archive(package.package_file) file_names = archive.filenames() if request.method == 'POST': form = PackageFileReuploadForm(file_names, contest, request.POST) if form.is_valid(): if 'upload_button' in request.POST: package_name = file_names[0].split(os.path.sep, 1)[0] package_archive, tmpdir = \ _prepare_changed_package(request, form, archive, package_name) if package_archive is not None: package_file = File(open(package_archive, 'rb'), os.path.basename(package_archive)) original_filename = package_file.name file_manager = uploaded_file_name(package_file) source = UploadedPackageSource() try: source.process_package(request, file_manager, request.user, contest, existing_problem=problem, original_filename=original_filename, visibility=problem.visibility) except Exception as e: logger.error("Error processing package", exc_info=True, extra={'omit_sentry': True}) form._errors['__all__'] = form.error_class([smart_str(e)]) finally: shutil.rmtree(tmpdir) return source._redirect_response(request) elif 'download_button' in request.POST: file_name = request.POST.get('file_name', None) if file_name is None: form.add_error('file_name', _('No file selected')) else: return redirect('download_package_file', package_id=package.id, file_name=file_name) else: form = PackageFileReuploadForm(file_names, contest) return TemplateResponse(request, 'problems/manage-problem-package-files.html', {'form': form, 'can_reupload': _problem_can_be_reuploaded(request, problem)})
def test_archive_submission(self): self.assertTrue(self.client.login(username='******')) kwargs = {'contest_id': Contest.objects.get().id} url = reverse('testrun_submit', kwargs=kwargs) base_dir = os.path.join(os.path.dirname(__file__), 'files') testruns_before = Submission.objects.filter(kind='TESTRUN').count() for bad_archive in ['over_limit.zip', 'two_files.zip', 'evil.zip']: filename = os.path.join(base_dir, bad_archive) with open(filename, 'rb') as input_file: data = { 'problem_instance_id': ProblemInstance.objects.get().id, 'file': ContentFile(b'a', name='x.cpp'), 'input': input_file } response = self.client.post(url, data, follow=True) self.assertEqual(response.status_code, 200) self.assertEqual( Submission.objects.filter(kind='TESTRUN').count(), testruns_before) with open(os.path.join(base_dir, "single_file.zip"), 'rb') as input_file: data = { 'problem_instance_id': ProblemInstance.objects.get().id, 'file': ContentFile(b'a', name='x.cpp'), 'input': input_file, } response = self.client.post(url, data, follow=True) self.assertEqual(response.status_code, 200) self.assertEqual( Submission.objects.filter(kind='TESTRUN').count(), testruns_before + 1) submission = TestRunProgramSubmission.objects.latest('pk') self.assertEqual(submission.kind, 'TESTRUN') self.assertEqual(submission.source_file.read().strip(), b'a') archive = Archive(submission.input_file, '.zip') self.assertEqual(len(archive.filenames()), 1)