Problem/Motivation
EasyLqpImagesFormatter::viewElements() derives an aspect ratio
from the image item's stored dimensions:
$original_width = $elements[$delta]['#item_attributes']['width']->value(); $original_height = $elements[$delta]['#item_attributes']['height']->value(); $aspect_ratio = $original_width / $original_height; $width = $elements[$delta]['#srcset'][0]['width']; $height = floor($width / $aspect_ratio);
Those values come from the image field item, via
$element['#item']->getValue()['height'] ?? NULL earlier in the
same method. An image item with no stored height yields 0 or
NULL, and the division then throws:
DivisionByZeroError: Division by zero in Drupal\easy_lqp\Plugin\Field\FieldFormatter\EasyLqpImagesFormatter->viewElements() (line 234 of modules/contrib/easy_lqp/src/Plugin/Field/FieldFormatter/EasyLqpImagesFormatter.php)
This is an uncaught error rather than a warning, so it fatals the render of
the page containing the image.
Image items can legitimately lack stored dimensions — for example when a file
was attached by a migration or programmatically without the width and height
columns being populated, or when the referenced file is missing from the file
system at the time the item was saved.
Steps to reproduce
- Configure an image field display to use the "Easy LQP Images" formatter with
the "Scale" image handling option. - Ensure an image field item exists whose stored
heightis
0orNULL. - View a page rendering that item. The request fatals with
DivisionByZeroError.
Proposed resolution
Guard the calculation and leave the height unset when either dimension is
missing, so the resizer JavaScript still supplies the final dimensions:
$original_width = $elements[$delta]['#item_attributes']['width']->value();
$original_height = $elements[$delta]['#item_attributes']['height']->value();
$width = $elements[$delta]['#srcset'][0]['width'];
// An image item with no stored dimensions yields a zero height, which
// would make the aspect ratio calculation divide by zero.
if (empty($original_height) || empty($original_width)) {
$height = NULL;
}
else {
$height = floor($width / ($original_width / $original_height));
}
The subsequent lines already overwrite width and height with the original
values for the low quality placeholder, so nothing downstream depends on the
intermediate $height when it cannot be computed.
Remaining tasks
- Review the merge request
- Commit and tag a release
User interface changes
None.
API changes
None.
Data model changes
None.
Issue fork easy_lqp-3614306
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #3
shiraz dindarComment #6
paulsheldrake commented