Skip to content

Commit

Permalink
fix: Allow Image.MAX_IMAGE_PIXELS to be None (#1475)
Browse files Browse the repository at this point in the history
* Fix #1377

* fix: `Image.MAX_IMAGE_SIZE = None` allowed.

* Improve warning message

* Add test.
  • Loading branch information
fsbraun authored Aug 7, 2024
1 parent 4d8de83 commit cce13d2
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 5 deletions.
26 changes: 21 additions & 5 deletions filer/models/abstract.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import logging

Check failure on line 1 in filer/models/abstract.py

View workflow job for this annotation

GitHub Actions / isort

Imports are incorrectly sorted and/or formatted.

from django.conf import settings
from django.core.checks import Warning, register as register_check
from django.core.exceptions import ValidationError
from django.db import models
from django.utils.functional import cached_property
from django.utils.translation import gettext_lazy as _


import easy_thumbnails.utils
from easy_thumbnails.VIL import Image as VILImage
from PIL.Image import MAX_IMAGE_PIXELS
Expand All @@ -24,10 +26,24 @@
# as if we allow it, it will fail while thumbnailing (first in the admin thumbnails
# and then in the page itself.
# Refer this https://github.com/python-pillow/Pillow/blob/b723e9e62e4706a85f7e44cb42b3d838dae5e546/src/PIL/Image.py#L3148
FILER_MAX_IMAGE_PIXELS = min(
getattr(settings, "FILER_MAX_IMAGE_PIXELS", MAX_IMAGE_PIXELS),
MAX_IMAGE_PIXELS,
)
FILER_MAX_IMAGE_PIXELS = getattr(settings, "FILER_MAX_IMAGE_PIXELS", MAX_IMAGE_PIXELS)
if MAX_IMAGE_PIXELS is not None:
FILER_MAX_IMAGE_PIXELS = min(FILER_MAX_IMAGE_PIXELS, MAX_IMAGE_PIXELS)


@register_check()
def max_pixel_setting_check(app_configs, **kwargs):
if not FILER_MAX_IMAGE_PIXELS:
return [
Warning(
"Both settings.FILER_MAX_IMAGE_PIXELS and PIL.Image.MAX_IMAGE_PIXELS are not set.",
hint="Set FILER_MAX_IMAGE_PIXELS to a positive integer value in your settings.py. "
"This setting is used to limit the maximum number of pixels an image can have "
"to protect your site from memory bombs.",
obj=settings,
)
]
return []


class BaseImage(File):
Expand Down Expand Up @@ -130,7 +146,7 @@ def clean(self):
# the image gets attached to a folder and saved. We also
# send the error msg in the JSON and also post the message
# so that they know what is wrong with the image they uploaded
if not self.file:
if not self.file or not FILER_MAX_IMAGE_PIXELS:
return

if self._width is None or self._height is None:
Expand Down
27 changes: 27 additions & 0 deletions tests/test_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,33 @@ def test_filer_ajax_decompression_bomb(self):

abstract.FILER_MAX_IMAGE_PIXELS = DEFAULT_MAX_IMAGE_PIXELS

def test_filer_max_pixel_deactivation(self):
from django.core.checks import Warning

DEFAULT_MAX_IMAGE_PIXELS = abstract.FILER_MAX_IMAGE_PIXELS
abstract.FILER_MAX_IMAGE_PIXELS = None # Deactivate

self.assertEqual(Image.objects.count(), 0)
folder = Folder.objects.create(name='foo')
with open(self.filename, 'rb') as fh:
file_obj = django.core.files.File(fh)
url = reverse(
'admin:filer-ajax_upload',
kwargs={'folder_id': folder.pk}
) + '?filename=%s' % self.image_name
self.client.post(
url,
data=file_obj.read(),
content_type='image/jpeg',
**{'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest'}
)
self.assertEqual(Image.objects.count(), 1) # Success
check_result = abstract.max_pixel_setting_check(None)
self.assertEqual(len(check_result), 1)
self.assertIsInstance(check_result[0], Warning)

abstract.FILER_MAX_IMAGE_PIXELS = DEFAULT_MAX_IMAGE_PIXELS

def test_filer_ajax_upload_file_using_content_type(self):
self.assertEqual(Image.objects.count(), 0)
folder = Folder.objects.create(name='foo')
Expand Down

0 comments on commit cce13d2

Please sign in to comment.