mirror of
https://github.com/wagtail/wagtail.git
synced 2024-11-29 17:36:49 +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:
parent
2044b7e930
commit
f5654981c8
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
|
Loading…
Reference in New Issue
Block a user