0
0
mirror of https://github.com/wagtail/wagtail.git synced 2024-11-30 01:46:24 +01:00

Add limit image upload size by number of pixels (#5097)

* Add test for Image pixel size

* add pixel size check and update test to match

using djangos get_image_dimensions this maybe a internal function
but the commit adding it is over 9 years old

* Update docs and CHANGELOG

* fix typos
This commit is contained in:
tomedelliott 2019-02-23 14:13:00 +00:00 committed by Karl Hobley
parent 2044b7e930
commit f5654981c8
4 changed files with 49 additions and 0 deletions

View File

@ -11,6 +11,7 @@ Changelog
* Highlight broken links to pages and missing documents in rich text (Brady Moe)
* Preserve links when copy-pasting rich text content from Wagtail to other tools (Thibaud Colas)
* Rich text to contentstate conversion now prioritises more specific rules, to accommodate `<p>` and `<br>` elements with attributes (Matt Westcott)
* Added limit image upload size by number of pixels (Thomas Elliott)
* Fix: Set `SERVER_PORT` to 443 in `Page.dummy_request()` for HTTPS sites (Sergey Fedoseev)
* Fix: Include port number in `Host` header of `Page.dummy_request()` (Sergey Fedoseev)
* Fix: Validation error messages in `InlinePanel` no longer count towards `max_num` when disabling the 'add' button (Todd Dembrey, Thibaud Colas)

View File

@ -255,6 +255,12 @@ This setting lets you provide your own image model for use in Wagtail, which mig
This setting lets you override the maximum upload size for images (in bytes). If omitted, Wagtail will fall back to using its 10MB default value.
.. code-block:: python
WAGTAILIMAGES_MAX_IMAGE_PIXELS = 128000000 # i.e. 128 megapixels
This setting lets you override the maximum number of pixels an image can have. If omitted, Wagtail will fall back to using its 128 megapixels default value.
.. code-block:: python
WAGTAILIMAGES_FEATURE_DETECTION_ENABLED = True

View File

@ -2,6 +2,7 @@ import os
from django.conf import settings
from django.core.exceptions import ValidationError
from django.core.files.images import get_image_dimensions
from django.forms.fields import ImageField
from django.template.defaultfilters import filesizeformat
from django.utils.translation import ugettext_lazy as _
@ -16,6 +17,7 @@ class WagtailImageField(ImageField):
# Get max upload size from settings
self.max_upload_size = getattr(settings, 'WAGTAILIMAGES_MAX_UPLOAD_SIZE', 10 * 1024 * 1024)
self.max_image_pixels = getattr(settings, 'WAGTAILIMAGES_MAX_IMAGE_PIXELS', 128 * 1000000)
max_upload_size_text = filesizeformat(self.max_upload_size)
# Help text
@ -46,6 +48,10 @@ class WagtailImageField(ImageField):
"This file is too big (%%s). Maximum filesize %s."
) % max_upload_size_text
self.error_messages['file_too_many_pixels'] = _(
"This file has too many pixels (%%s). Maximum pixels %s."
) % self.max_image_pixels
self.error_messages['file_too_large_unknown_size'] = _(
"This file is too big. Maximum filesize %s."
) % max_upload_size_text
@ -83,11 +89,28 @@ class WagtailImageField(ImageField):
filesizeformat(f.size),
), code='file_too_large')
def check_image_pixel_size(self, f):
# Upload pixel size checking can be disabled by setting max upload pixel to None
if self.max_image_pixels is None:
return
# Check the pixel size
dimensions = get_image_dimensions(f)
if dimensions == (None, None):
return
pixel_size = dimensions[0] * dimensions[1]
if pixel_size > self.max_image_pixels:
raise ValidationError(self.error_messages['file_too_many_pixels'] % (
pixel_size
), code='file_too_many_pixels')
def to_python(self, data):
f = super().to_python(data)
if f is not None:
self.check_image_file_size(f)
self.check_image_file_format(f)
self.check_image_pixel_size(f)
return f

View File

@ -192,6 +192,25 @@ class TestImageAddView(TestCase, WagtailTestUtils):
)
)
@override_settings(WAGTAILIMAGES_MAX_IMAGE_PIXELS=1)
def test_add_too_many_pixels(self):
file_content = get_test_image_file().file.getvalue()
response = self.post({
'title': "Test image",
'file': SimpleUploadedFile('test.png', file_content),
})
# Shouldn't redirect anywhere
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'wagtailimages/images/add.html')
# The form should have an error
self.assertFormError(
response, 'form', 'file',
'This file has too many pixels (307200). Maximum pixels 1.'
)
def test_add_with_collections(self):
root_collection = Collection.get_first_root_node()
evil_plans_collection = root_collection.add_child(name="Evil plans")