Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix allowed zipfile upload size #361

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions src/solutions/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ class Meta:
def clean_file(self):
data = self.cleaned_data['file']
task = self.cleaned_data['solution'].task
max_file_size_kb = task.max_file_size
max_file_size = 1024 * max_file_size_kb
max_file_size_kib = task.max_file_size
max_file_size = 1024 * max_file_size_kib
supported_types_re = re.compile(task.supported_file_types)
if data:
contenttype = mimetypes.guess_type(data.name)[0] # don't rely on the browser: data.content_type could be wrong or empty
Expand All @@ -47,7 +47,9 @@ def clean_file(self):
zip = zipfile.ZipFile(data)
if zip.testzip():
raise forms.ValidationError(_('The zip file seems to be corrupt.'))
if sum(fileinfo.file_size for fileinfo in zip.infolist()) > 1000000:
if sum(fileinfo.file_size for fileinfo in zip.infolist()) > ( max_file_size * len(zip.infolist()) ) :
# Protect against zip bombs
# but allow that a zip-file can be the same size like the sum of all file sizes would be, if files would have been uploaded seperately.
raise forms.ValidationError(_('The zip file is too big.'))
for fileinfo in zip.infolist():
filename = fileinfo.filename
Expand All @@ -61,15 +63,15 @@ def clean_file(self):
raise forms.ValidationError(_("The plain text file '%(file)s' in this zip file contains a NUL character, which is not supported." %{'file':filename}))
# check whole zip instead of contained files
#if fileinfo.file_size > max_file_size:
# raise forms.ValidationError(_("The file '%(file)s' is bigger than %(size)KiB which is not suported." %{'file':fileinfo.filename, 'size':max_file_size_kb}))
# raise forms.ValidationError(_("The file '%(file)s' is bigger than %(size)KiB which is not suported." %{'file':fileinfo.filename, 'size':max_file_size_kib}))
except forms.ValidationError:
raise
except:
raise forms.ValidationError(_('Uhoh - something unexpected happened.'))
elif tartype_re.match(contenttype):
raise forms.ValidationError(_('Tar files are not supported, please upload the files individually or use a zip file.'))
if data.size > max_file_size:
raise forms.ValidationError(_("The file '%(file)s' is bigger than %(size)KiB which is not suported." %{'file':data.name, 'size':max_file_size_kb}))
raise forms.ValidationError(_("The file '%(file)s' is bigger than %(size)d KiB which is not supported." %{'file':data.name, 'size':max_file_size_kib}))
return data

class MyBaseInlineFormSet(BaseInlineFormSet):
Expand Down
15 changes: 15 additions & 0 deletions src/tasks/migrations/0010_max_file_size.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from django.db import migrations, models

class Migration(migrations.Migration):

dependencies = [
('tasks', '0009_Task_dynamic_upload_waiting_time_Python3_Python2'),
]

operations = [
migrations.AlterField(
model_name='task',
name='max_file_size',
field=models.IntegerField(default=1000, help_text='The maximum size of an uploaded solution file in kibibyte.'),
),
]
2 changes: 1 addition & 1 deletion src/tasks/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class Task(models.Model):
submission_maxpossible = models.IntegerField(default=-1,help_text=_("Number of uploads a user can submit for the same task. Value -1 means unlimited"))

supported_file_types = models.CharField(max_length=1000, default ="^(text/.*|image/.*|application/pdf)$", help_text = _("Regular Expression describing the mime types of solution files that the user is allowed to upload."))
max_file_size = models.IntegerField(default=1000, help_text = _("The maximum size of an uploaded solution file in kilobyte."))
max_file_size = models.IntegerField(default=1000, help_text = _("The maximum size of an uploaded solution file in kibibyte."))
model_solution = models.ForeignKey('solutions.Solution', on_delete=models.SET_NULL, blank=True, null=True, related_name='model_solution_task')
all_checker_finished = models.BooleanField(default=False, editable=False, help_text = _("Indicates whether the checker which don't run immediately on submission have been executed."))
final_grade_rating_scale = models.ForeignKey('attestation.RatingScale', on_delete=models.SET_NULL, null=True, help_text = _("The scale used to mark the whole solution."))
Expand Down