Open jenlampton opened 4 years ago
I've filed a pr at https://github.com/backdrop/backdrop/pull/3222 that fixes this problem on my site.
I tried to reproduce this on a vanilla installation (our demo sandboxes), but I was able to see the problematic image in step 4 π€· ...do we have another way to reproduce this?
OK, here's a trick to reproduce this:
SQLSTATE[HY000]: General error: 1366 Incorrect integer value: '' for column field_image_width' at row 1`
create a txt file, add some dummy content in it (so that it's not 0 bytes), and also save it as .jpg
upload this new dummy file to a new post node.
try to save the node -> same error π
duplicate an existing, valid .jpg image, open it in a text editor, delete all its content, or replace it with some dummy content, then save it.
upload this new dummy file to a new post node.
try to save the node -> same error π
Try the above in the sandbox of @jenlampton's PR -> no errors π
Now the question is: should we be allowing this, or should we be throwing errors/warnings after the "faulty" image has been uploaded to the field?
I could also reproduce it (with a text file with jpg extension). I can confirm that the PR fixes the Exception. (I've left comments at the PR).
the question is: should we be allowing this, or should we be throwing errors/warnings after the "faulty" image
I second that! If we allow uploading broken/faulty images, we only create follow-up problems.
Here's an alternate PR which strikes earlier.
I realized that core already has a handy verification function for images: file_validate_is_image For whatever reason the image module uses that function only for verifying the default image, but not yet for the actual image fields. I guess, this has been an oversight, my PR adds this validator to the actual image field upload, too.
How to test:
Create a "broken" image file, for instance by changing the extension of a text file to jpg. (Linux users can do touch notanimage.jpg
)
Then upload that "notanimage.jpg" into an image field. Instead of the Exception you get a form error message (which could get improved a bit): "Only JPEG, PNG and GIF images are allowed."
@klonos have you already been able to test my alternative PR? It prevents uploading of broken/faulty images (anything gd can't handle), just as you suggested.
@klonos have you already been able to test my alternative PR?
Just did, and I prefer it over @jenlampton's π
you get a form error message (which could get improved a bit)
Yup. Please see my PR against yours: https://github.com/indigoxela/backdrop/pull/1
Please see my PR against yours: indigoxela/backdrop#1
Many thanks for that. Please see my question regarding your change in function file_validate_is_image().
Replied @indigoxela
@klonos discovered that image files with a wrong extension (e.g. bmp or webp with a jpg extension) are also broken after upload. These need a slightly different form error message. His code provides that. This Issue is ready for review.
@indigoxela yet another simple PR, to fix the failing test: https://github.com/indigoxela/backdrop/pull/2
I can't tell from the recent comments if this also addresses the original problem: when images are uploaded that are perfectly fine (but GD still can't handle them).
If you read the original Drupal issues, you can see that the 'faulty' images there were generated in exactly the same way as the images that worked, but for some reason GD chokes on some of them and not on others. GD has a lot of known issues like this, so we should be careful that we don't end up using GD to determine whether an image is 'faulty' or not.
...images are uploaded that are perfectly fine (but GD still can't handle them)
We'd need example test images and/or GD versions that allow reproducing this. We cannot fix what cannot be reproduced π€· ...this PR does improve the handling and error messages thrown with known/reproducible problems.
this PR does improve the handling and error messages thrown with known/reproducible problems.'
But it also introduces a new problem: not being able to upload images that are perfectly fine. Since we already know that GD has this problem (even if we can't reproduce it here) it would be silly to introduce known bugs.
That said, I'll see if I can collect some of the logos off the site that is suffering from these issues.
We cannot fix what cannot be reproduced
But we cross-port the same fix Drupal includes. :)
it also introduces a new problem: not being able to upload images that are perfectly fine
@jenlampton are you referring to the "Problem.jpg" you provided? That image is corrupted, but I still can upload it to an image field and gd (2.2.5) handles it fine, it gets displayed and derivatives get created without problem.
Here's a "second opinion" from Imagemagic (identify):
Problem.jpg JPEG 300x173 300x173+0+0 8-bit sRGB 60773B 0.000u 0:00.010
identify: Corrupt JPEG data: 4769 extraneous bytes before marker 0xee `Problem.jpg' @ warning/jpeg.c/JPEGWarningHandler/365.
I agree with @klonos - We cannot fix what cannot be reproduced. We do fix reproducible errors with our PR.
But we are introducing new ones too. Please read the related Drupal issues :)
On Mon, Aug 17, 2020, 11:34 PM indigoxela notifications@github.com wrote:
it also introduces a new problem: not being able to upload images that are perfectly fine
@jenlampton https://github.com/jenlampton are you referring to the "Problem.jpg" you provided? That image is corrupted, but I still can upload it to an image field and gd (2.2.5) handles it fine, it gets displayed and derivatives get created without problem.
Here's a "second opinion" from Imagemagic (identify):
Problem.jpg JPEG 300x173 300x173+0+0 8-bit sRGB 60773B 0.000u 0:00.010 identify: Corrupt JPEG data: 4769 extraneous bytes before marker 0xee `Problem.jpg' @ warning/jpeg.c/JPEGWarningHandler/365.
I agree with @klonos https://github.com/klonos - We cannot fix what cannot be reproduced. We do fix reproducible errors with our PR.
β You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/backdrop/backdrop-issues/issues/4526#issuecomment-675284125, or unsubscribe https://github.com/notifications/unsubscribe-auth/AADBERYXP57UYXOVKFJZP23SBIOHLANCNFSM4PYEV62A .
But we are introducing new ones too
@jenlampton sometimes I wish your comments provided more details. :wink:
The situation:
Currently if gd can not extract essential information we get an Exception - a bad thing. Just catching that Exception does not really solve the problem. The image still won't display and no derivatives get created - gd can't handle the file.
But the Exception only appears with non-image files (like text) or severely broken images, not just "a little corrupt". The first commit of our PR fixes that.
We also prevent images with wrong extensions to get uploaded even if gd could handle them technically, but they're not of type jpg/gif/png. For instance a file with jpg extension that's actually a webp or bmp can't get uploaded. Files that are actually png, gif or jpg, but with wrong extension still work - as they do currently. No change in that.
A webp or bmp file with jpg extension does currently not work as expected. We can upload stuff like that, no Exception on saving, but the image won't ever display.
Please also note that images that don't display also cause dblog messages: "Unable to generate the derived image located at public://styles/..." On every page call - I'm pretty sure we should prevent that - the base problem, not the message.
Do I get your concerns right that you suggest we should allow uploading of images that have wrong extensions?
Finally regarding the patch on drupal.org - it introduces a brand new function that does the same as file_validate_is_image(), which already exists in both, D7 and Backdrop. Using the already existing function makes more sense.
NOTE: I updated the comment to rectify the description of handling png/gif/jpeg with wrong extension - they still do work.
Here's a quick tip to create a severely broken "image": put the first ten bytes of a valid jpg to a new file.
On Linux head -c 10 real.jpg > firstjpgegbytes.jpg
This (sort of) simulates an interrupted upload or local disk corruption.
This file causes an Exception on current Backdrops but upload is refused with our PR:
"The specified file firstjpgegbytes.jpg could not be uploaded. The uploaded file is either corrupt or not an image."
@jenlampton sometimes I wish your comments provided more details.
Sorry, I thought I'd already stated everything as clearly as I could, and that maybe the Drupal issues would do a better job than I could, hence me deferring to them instead. I'll try to do better :)
Currently if gd can not extract essential information we get an Exception - a bad thing. Just catching that Exception does not really solve the problem. The image still won't display and no derivatives get created - gd can't handle the file.
that's not my use-case for a this ticket.
The use-case for this ticket is for images that are perfectly fine. They render well in a browser, and they get resized without an issue. In some cases, GD still chokes on getting a width and height for these images, and that can cause an exception.
From an end-user perspective, I don't care if GD can't read the width and height of those images. If they display fine, and they resize fine, I should be allowed to upload them to my site and/or save pages that already have them.
In my case, I have a site with 100s of logos (some are very old -- the site was upgraded from Drupal 6) and in most cases my client does not have a choice in the image they were given. They can't go back to their client and say "My CMS doesn't like this logo" -- their client will think they are nuts if the logo works for everyone else (or, worked on this site before this change).
Do I get your concerns right that you suggest we should allow uploading of images that have wrong extensions?
The Images with the wrong extensions
bit was something that @klonos added in a later comment but has nothing to do with the problem I am facing.
The use-case for this ticket is for images that are perfectly fine. They render well in a browser, and they get resized without an issue. In some cases, GD still chokes on getting a width and height for these images, and that can cause an exception.
@jenlampton can you please provide a few of these images, so we can test?
I've updated the first post in this thread in an attempt to state the problem more clearly. I've included more of the text from the Drupal 7 issue (and less from the Drupal 8 issue) for a closer parallel to what I was facing.
I've also split the Proposed resolution
section into two parts -- a) is the problem I was attempting to fix with the database write, and b) is the problem @klonos is attempting to fix for Images with the wrong extensions
. That is also being addressed in #2345695: Users are able to upload 0-byte images.
(I'm currently working on new STR with more/better image examples.)
@jenlampton I'd suggest that I open a new Issue for the upload validation of image fields. And you move on with your own PR here. Is that OK for you? Mixing these two items here makes things complicated.
To further narrow down the problem with images that display but still cause an Exception it would be essential to also know the full php and gd version of your affected site(s) - admin/reports/status/php.
There must be a reason why your site chokes on it, but @klonos and me were not able to reproduce the error with "Problem_3.jpg". Or if you can't reproduce it with Problem_3.jpg either but with other images, getting those images would be cool.
I'd suggest that I open a new Issue for the upload validation of image fields. And you move on with your own PR here. Is that OK for you? Mixing these two items here makes things complicated.
I'm supportive of this π
Or if you can't reproduce it with Problem_3.jpg either but with other images, getting those images would be cool.
Yup, @jenlampton can you please:
Problem_3.jpg
from the d.org issue is also problematic on those sites of yours that are throwing those PDOException errors?Too much has changed in core's image handling, so I closed my outdated PR - there hasn't been any feedback for years, anyway.
Too much has changed in core's image handling ...
Indeed ππΌ
...in the meantime, things have also progressed in the Drupal issues referenced in the issue summary:
image_get_supported_extensions()
etc.).So here's a PR that takes all that into account: https://github.com/backdrop/backdrop/pull/4807
The PR does the following:
file_validate_is_image()
.ImageFieldValidateTestCase::testValid()
test, with 2 intentionally broken images in the test files provided by Simpletest:
image_is_webp()
function, to match image_is_svg()
image_is_webp_supported()
function, which uses the IMAGETYPE_WEBP
predefined constant (available as of PHP 7.1.0) instead of version_compare()
/PHP_VERSION
$type
support in BackdropWebTestCase::backdropGetTestFiles()
to allow 'webp'
, which then loads any .webp test files (previously in the image module tests - see previous point)ImageFieldValidateTestCase::testValid()
test to:
BackdropWebTestCase::backdropGetTestFiles()
)@jenlampton do you still experience the problem you mentioned where valid images are reported as broken/corrupt or not properly handled by GD? If so, then can you provide a couple of these files as samples and let us know versions of PHP and GD on these servers?
Some images do not return integer values for width and height values from GD. These images often render normally, and can even be resized by GD without an issue.
However, when the record for the image is being added to the respective database table, an exception is thrown because the
width
andheight
columns require integer values, and what is passed into the query is not valid.PDOException: SQLSTATE[HY000]: General error: 1366 Incorrect integer value: '' for column 'field_[field name here]' at row 1...
From the Drupal issue:
Description of the bug
With a clean install, I can upload certain .jpg images and drupal will throw the following error:
This is one we inherited from Drupal. See This Drupal 8 issue and This drupal 7 issue, that got marked as dupe.
Steps To Reproduce
To reproduce the behavior:
Upload
button, vs the nodeSubmit
button to see if there is a differenceProposed resolution
This issue has two parts:
width
andheight
-- (can no longer be reproduced in Drupal 9)The resolution below attempts to fix only the first part -- saving valid values to the database.
Placeholder 6 is not an integer and is not NULL. There is some code in the function (lines 433-435 of field_sql_storage.module) that attempts to handle this:
but for some reason this is not sufficient to convert these non-values to NULL before sending them to the database. I replaced this with the following:
and that has resolved the problem.
PHP version: is Version: 7.4.2 GD: bundled (2.1.0 compatible)