Fix image resizing failing on slim images

Image operations sometimes calculate a target width or height of zero, which
make Willow raise a ValueError.

If an user uploads one such image it's possible to break the whole Wagtail
image manager/picker/uploader for all users.

The fix is to use a minimum of 1 pixel for either the target height or the
width. The image might lose some aspect ratio, but it's better than an
exception.
pull/5896/head
Fidel Ramos 2020-03-10 23:15:41 +00:00 zatwierdzone przez Matt Westcott
rodzic 526649008d
commit 0ccfe9568f
4 zmienionych plików z 38 dodań i 0 usunięć

Wyświetl plik

@ -30,6 +30,7 @@ Changelog
* Fix: `{% image ... as var %}` now clears the context variable when passed None as an image (Maylon Pedroso)
* Fix: `refresh_index` method on Elasticsearch no longer fails (Lars van de Kerkhof)
* Fix: Document tags no longer fail to update when replacing the document file at the same time (Matt Westcott)
* Fix: Prevent error from very tall / wide images being resized to 0 pixels (Fidel Ramos)
2.8 (03.02.2020)

Wyświetl plik

@ -48,6 +48,7 @@ Bug fixes
* ``{% image ... as var %}`` now clears the context variable when passed None as an image (Maylon Pedroso)
* ``refresh_index`` method on Elasticsearch no longer fails (Lars van de Kerkhof)
* Document tags no longer fail to update when replacing the document file at the same time (Matt Westcott)
* Prevent error from very tall / wide images being resized to 0 pixels (Fidel Ramos)
Upgrade considerations

Wyświetl plik

@ -182,6 +182,10 @@ class MinMaxOperation(Operation):
# Unknown method
return
# prevent zero width or height, it causes a ValueError on willow.resize
width = width if width > 0 else 1
height = height if height > 0 else 1
return willow.resize((width, height))
@ -214,6 +218,10 @@ class WidthHeightOperation(Operation):
# Unknown method
return
# prevent zero width or height, it causes a ValueError on willow.resize
width = width if width > 0 else 1
height = height if height > 0 else 1
return willow.resize((width, height))
@ -228,6 +236,10 @@ class ScaleOperation(Operation):
width = int(image_width * scale)
height = int(image_height * scale)
# prevent zero width or height, it causes a ValueError on willow.resize
width = width if width > 0 else 1
height = height if height > 0 else 1
return willow.resize((width, height))

Wyświetl plik

@ -361,6 +361,14 @@ class TestMinMaxOperation(ImageOperationTestCase):
('max-800x600', dict(width=1000, height=1000), [
('resize', ((600, 600), ), {}),
]),
# Resize doesn't try to set zero height
('max-400x400', dict(width=1000, height=1), [
('resize', ((400, 1), ), {}),
]),
# Resize doesn't try to set zero width
('max-400x400', dict(width=1, height=1000), [
('resize', ((1, 400), ), {}),
]),
]
@ -391,6 +399,14 @@ class TestWidthHeightOperation(ImageOperationTestCase):
('height-400', dict(width=1000, height=500), [
('resize', ((800, 400), ), {}),
]),
# Resize doesn't try to set zero height
('width-400', dict(width=1000, height=1), [
('resize', ((400, 1), ), {}),
]),
# Resize doesn't try to set zero width
('height-400', dict(width=1, height=800), [
('resize', ((1, 400), ), {}),
]),
]
@ -425,6 +441,14 @@ class TestScaleOperation(ImageOperationTestCase):
('scale-83.0322', dict(width=1000, height=500), [
('resize', ((int(1000 * 0.830322), int(500 * 0.830322)), ), {}),
]),
# Resize doesn't try to set zero height
('scale-50', dict(width=1000, height=1), [
('resize', ((500, 1), ), {}),
]),
# Resize doesn't try to set zero width
('scale-50', dict(width=1, height=500), [
('resize', ((1, 250), ), {}),
]),
]