Problem/Motivation

In Drupal\Core\Image\Image::construct(), filesize() is being used to determine the size of file, but if for example files are on s3, filesize() returns FALSE and there is a warning that can't be suppressed.

Also, \Drupal\Core\Image\ImageInterface::getFileSize() expects this to be NULL not FALSE if the file is invalid, so we should handle that too.

Proposed resolution

We should suppress the warning, and check if @filesize() returns FALSE.

Remaining tasks

  1. Review MR
  2. Merge

User interface changes

N/A

API changes

N/A

Data model changes

N/A

CommentFileSizeAuthor
#31 2831320-filesize-over-s3-file.png117.56 KBvidorado

Issue fork drupal-2831320

Command icon 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

joshi.rohit100 created an issue. See original summary.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

kim.pepper made their first commit to this issue’s fork.

kim.pepper’s picture

Status: Active » Needs review

We should suppress the warning, and check if @filesize() returns FALSE. Also \Drupal\Core\Image\ImageInterface::getFileSize() expects this to be NULL not FALSE if the file is invalid, so we should handle that too.

kim.pepper’s picture

Issue summary: View changes
Issue tags: +Needs issue summary update
pameeela’s picture

Title: No error handling for filesize() in Drupal\Core\Image\Image » Handling of filesize() returning false in Drupal\Core\Image\Image
Issue summary: View changes
Issue tags: -Needs issue summary update +Bug Smash Initiative

Issue summary updated. I can't really provide steps to reproduce as it requires a custom architecture to host files on s3.

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: +Needs Review Queue Initiative, +Needs tests

Possible to add test coverage for when it is NULL?

vidorado made their first commit to this issue’s fork.

vidorado’s picture

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

I've added a couple of tests and attempted to simulate an S3 filesystem where filesize() returns FALSE, even though the toolkit returns TRUE in parseFile()

kim.pepper’s picture

Status: Needs review » Reviewed & tested by the community

Good test coverage. I ran the test-only pipeline and it fails as expected. The current docblock already says it should return int|null so there is no API breaks afaik, and we don't need a change record for a bug fix. I think we are safe to RTBC.

vidorado’s picture

Thanks for the review @kim.pepper!

Mind the "null" in the @return of the docblock was added in this issue, it wasn´t already there: https://git.drupalcode.org/project/drupal/-/merge_requests/7217/diffs?co...

I believe that in the cases where a false was taken into account, it would have been with a simple truthy evaluation if($value). I think it's rare that anyone could have used if(FALSE === $value), so the NULL is probably not harming.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

We need to add a comment about why we're suppressing errors here.

vidorado’s picture

Status: Needs work » Needs review

Done @alexpott! :)

kim.pepper’s picture

Status: Needs review » Reviewed & tested by the community

Feedback resolved. Back to RTBC

mondrake’s picture

Looking at the motivation, I am not sure about this. The file must have a size, but we cannot get it so we hide the problem. BTW possibly the image cannot be loaded by GD either. IMHO the right solution here would be to download the file from S3 to local storage, get its stats and use it for manipulation. IIRC the ImageMagick toolkit does something similar since it does not support stream wrappers.

mfb’s picture

Status: Reviewed & tested by the community » Needs work

filesize() can return zero for empty files; in this case, zero should be returned, not NULL

vidorado’s picture

Status: Needs work » Needs review

I agree with you @mfb. I took that into account, but that's an imposible case, since the toolkit will never validate an image as valid if the file is zero size.

vidorado’s picture

Status: Needs review » Needs work

Sorry, I didn't see @mondrake's comment. I agree that returning NULL is hiding the problem in the case of a VALID image. However, I stand by saying that zero should never be returned by getFileSize(), since its docblock states this:

/**
   * Returns the size of the image file.
   *
   * @return int|null
   *   The size of the file in bytes, or NULL if the image is invalid.
   */
  public function getFileSize();

A zero size image would never be valid, so a NULL must be returned. But in case of a valid image that we can't retrieve easily with filesize()... returning NULL is wrong, that seems clear.

I will take a look at the ImageMagick toolkit to get ideas about how to download and parse the file from S3.

Thanks all for the fedback! :)

mfb’s picture

Ok, sounds reasonable to not worry about the zero size case then (would only happen in edge cases like buggy toolkit, file getting truncated by another process etc.)

vidorado’s picture

Issue summary: View changes
Status: Needs work » Needs review
StatusFileSize
new117.56 KB

I've installed an AWS S3 mock with Localstack and amazon-ec2-metadata-mock.

Then, I've been able to check that filesize() works well with a s3:// stream.

filesize() returning a correct value

Perhaps this is not longer an issue? I don't have a real S3 bucket, maybe someone could do a real test.

vidorado’s picture

Issue summary: View changes
smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

Believe feedback has been addressed for this one.

catch’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs issue summary update

It looks like #31 needs to be answered here and the issue summary updated based on the results.

If the file is actually invalid, then I don't think we need to suppress the error in that case - it's correctly informing people about the invalid file. We could convert the FALSE to NULL though but that's not the only thing the MR does.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.