Typically, if you try to access an image which doesn't exist, you would get a 404 error response.
If you try to access the same missing image through a custom image-styles URL, the image module gives a 500 server error instead.

This makes it harder to diagnose issues with missing images (you can't tell if it's a missing image, an image that can't be handled by the image toolkit, or some other software error).

Steps to reproduce

1. Create a base install of Drupal (with image module enabled).
2. Go to admin/config/media/image-styles/add and create a simple style (e.g. resize to 100x100 pixels).
3. Visit an image URL which doesn't exist: e.g. /sites/default/files/zzzzz.png - observe that the HTTP error code is 404.
4. Visit the same image URL through the image-styles handler: e.g. /sites/default/files/styles/my_custom_style/public/zzzzz.png - observe that the HTTP error code is 500.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

manarth’s picture

Status: Active » Needs review
FileSize
630 bytes

Patch for review.

Status: Needs review » Needs work

The last submitted patch, 1226512-image-check_source_image_exists.patch, failed testing.

manarth’s picture

Ah, testbot, like ye not p0? How about a p1 patch then? :-)

manarth’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 1226512-image-check_source_image_exists.patch, failed testing.

13rac1’s picture

Status: Needs work » Needs review
FileSize
648 bytes

Testbot wants git diff patches ;)

Status: Needs review » Needs work

The last submitted patch, source_image_exists-1226512-6.patch, failed testing.

marcingy’s picture

Status: Needs work » Postponed (maintainer needs more info)

Please update to 7.8.

13rac1’s picture

Version: 7.4 » 7.x-dev
Status: Postponed (maintainer needs more info) » Needs review

Blast! My patch was against HEAD.

13rac1’s picture

#6: source_image_exists-1226512-6.patch queued for re-testing.

marcingy’s picture

Status: Needs review » Reviewed & tested by the community

Makes sense to me.

sun’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/modules/image/image.module
@@ -709,6 +709,12 @@ function image_style_deliver($style, $scheme) {
+  if (!is_file($image_uri)) {

To my knowledge, file_exists() is way faster than is_file() and has way less unintended side-effects.

Overall, however, this patch could use some more eyes before getting RTBC again.

manarth’s picture

For me, is_file is more appropriate than file_exists, because file_exists will accept a directory, and of course a directory couldn't be handled by the image module.

I don't think the micro-optimisation of file_exists vs is_file is meaningful in this case, because it's a single call per request, but please chip in if you disagree :-)

oriol_e9g’s picture

Status: Needs work » Needs review

I'm with @manarth file_exists return true with directories and symbolic links

oriol_e9g’s picture

FileSize
0 bytes
1.05 KB

Only as a curiosity, IS_FILE is faster than FILE_EXISTS, if the file exists xD

IS_FILE versus FILE_EXISTS test - 10000 iterations.

FILE_EXISTS with a good file: 0.10488700866699 ms.
FILE_EXISTS with a bad file: 0.36173105239868 ms.
IS_FILE with a good file: 0.0040671825408936 ms.
IS_FILE with a bad file: 0.36448192596436 ms.

Attached the performance test files.

oriol_e9g’s picture

sun’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests

ok, checking whether the file is actually a file makes sense.

Two more things though:

1) I'm not sure I understand why this check happens that late in the request in a delivery callback? (which is pretty much one of the very last things being invoked during a request) I would have expected that a fundamental check like this happens at the very beginning of the request (in the page callback) instead. Perhaps this check even exists already, but doesn't work correctly?

2) It looks like this expectation can be easily asserted in a test.

3) Generating and rendering a full-blown 404 HTML page seems like a lot of overhead, given that in 99% of all cases, the output will not be visible (and the browser renders a red X for a missing image instead).

127356’s picture

Status: Needs work » Needs review
marianov’s picture

It clearly makes sense to issue a 404 instead of a 500 error when the file does not exists.
I also think a call to drupal_not_found() should be added when checking that the style defined and the scheme is valid. As it is right now you get a 200 OK status when you request /sites/default/files/styles/my_custom_style/zzzzz.png (an inexistant file).

onequad’s picture

Status: Needs review » Reviewed & tested by the community

The patch looks good and works as expected. Changing the drupal_not_found() to a lighter alternative could be useful as well (the same way status 500 is handled):

    //drupal_not_found();
    drupal_add_http_header('Status', '404 Not found');
    print t('Image not found.');
webchick’s picture

Version: 7.x-dev » 8.x-dev
Status: Reviewed & tested by the community » Needs work

Thanks! This looks like a sensible fix; however, as far as I can see:

1) We still need tests.
2) We need a fix in D8 before we backport to D7.

Marking needs work.

bas.hr’s picture

Status: Needs work » Closed (duplicate)