Opened 5 months ago
Last modified 4 weeks ago
#64902 new defect (bug)
wp_save_image() fatal error when wp_save_image_file() returns WP_Error
| Reported by: | notglossy | Owned by: | |
|---|---|---|---|
| Priority: | normal | Milestone: | Awaiting Review |
| Component: | Media | Version: | 6.9.4 |
| Severity: | normal | Keywords: | has-patch needs-testing has-test-info |
| Cc: | Focuses: |
Description
wp_save_image_file() has a return type of array|WP_Error|bool.
wp_save_image() checks the return value of wp_save_image_file() with if ( ! $saved_image ) (line1020), but WP_Error is truthy, so it passes through.
Line 1054 then accesses $saved_image['filesize'] which fatals with "Cannot use object of type WP_Error as array".
This is reproducible when any image editor's save() returns WP_Error (e.g., unsupported format, disk full, encoder failure)
Affects all editors (GD, Imagick, custom) since save() is documented as @return array|WP_Error
This bug was discovered when building a plugin which extends WP_Image_Editor to take advantage of a different graphics library.
Attachments (1)
Change History (9)
#3
follow-up:
↓ 4
@
4 months ago
I tested the bug on wordpress with environemnt:
WordPress: 6.9.4
PHP: 8.2
Local WP
The bug is not reproducing, I'm getting the message saying "Could not load the preview image. Please reload the page and try again." but is not allowing me to save it the button is grayed out.
#4
in reply to: ↑ 3
@
4 months ago
Yes, this is one of the symptoms on the front end since the whole process fails because WP_Error is not an array and returns a 500 error.
Replying to aytor:
I tested the bug on wordpress with environemnt:
WordPress: 6.9.4
PHP: 8.2
Local WP
The bug is not reproducing, I'm getting the message saying "Could not load the preview image. Please reload the page and try again." but is not allowing me to save it the button is grayed out.
#5
@
3 months ago
Test Report
Patch tested: attachment:64902.patch
Environment
- Reported version: 6.9.4
- Tested version: 7.1-alpha-62161-src
- PHP: 8.3.31
- Environment: wordpress-develop local Docker environment
- Test method: WP-CLI automated reproduction using
wp_save_image_editor_file - OS: macOS
Reproduction
I was able to confirm that the reported issue is still reproducible on current trunk.
The test creates an image attachment from tests/phpunit/data/images/test-image.jpg, sets up a scale operation for wp_save_image(), and uses the existing wp_save_image_editor_file filter to force wp_save_image_file() to return a WP_Error.
Clean trunk output:
attachment_id=10
source_size=50x50
request={"do":"scale","fwidth":25,"fheight":25,"target":"all"}
Fatal error: Uncaught Error: Cannot use object of type WP_Error as array
in /var/www/src/wp-admin/includes/image-edit.php:1054
This confirms that when wp_save_image_file() returns WP_Error, wp_save_image() continues as if it received an array and then fatals when reading $saved_image['filesize'].
Patch Result
After applying 64902.patch locally and running the same automated reproduction, the fatal error no longer occurs. wp_save_image() returns a normal error response:
attachment_id=11
source_size=50x50
request={"do":"scale","fwidth":25,"fheight":25,"target":"all"}
result={
"error": "Forced save failure for #64902 retest."
}
Tests
I also ran the related PHPUnit tests with the patch applied:
npm run test:php -- --group ajax --filter Tests_Ajax_wpAjaxImageEditor OK (4 tests, 9 assertions)
npm run test:php -- --filter Tests_Image_Functions OK (113 tests, 211 assertions)
Notes
The patch handles the WP_Error return from wp_save_image_file() before the code accesses $saved_image['filesize'], which prevents the fatal and returns a normal error response instead.
A focused PHPUnit test using the wp_save_image_editor_file filter to force a WP_Error return would be a useful follow-up for this patch.
#6
@
2 months ago
- Keywords has-test-info added
Tested against current trunk (7.1-alpha).
I was able to reproduce the fatal error by forcing wp_save_image_file() to return a WP_Error, matching the failure path described in the ticket.
After applying the patch, the fatal error no longer occurred and the WP_Error message was returned as the image edit error response.
I was unable to identify any regressions during testing.
Patch tests successfully for me.
#7
@
5 weeks ago
Hi everyone, just checking whether there is anything else needed from my side for this ticket. I'd be happy to update the patch or address any feedback if necessary. Thanks!
#8
@
4 weeks ago
Manual Test Report
I manually tested the proposed patch for ticket #64902.
Test environment
- WordPress: 7.0.1
- PHP: 8.3.30
- Local environment: Laragon
- Operating system: Windows
- Browser: Google Chrome
- Image format: PNG
Test method
I created a temporary must-use plugin using the
wp_save_image_editor_file filter to force the image-saving
operation to return a WP_Error.
I tested the image editor before and after manually applying the
proposed patch to wp-admin/includes/image-edit.php.
Before applying the patch
With the test must-use plugin active, the image editor continued
loading after clicking Save, and the image was not saved.
After applying the patch
With the test must-use plugin active, the save request completed
immediately instead of continuing to load, and the WP_Error was
handled without the previous failure.
I then disabled the temporary must-use plugin and confirmed that
normal image editing and saving worked successfully.
Result
The patch works as expected in my manual testing. I did not identify
any regression in the normal image-saving workflow.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)
Hi,
I’ve attached a patch to properly handle WP_Error returned by wp_save_image_file().
Currently, wp_save_image_file() may return a WP_Error, but wp_save_image() only checks for falsy values. Since WP_Error is a truthy object, execution continues and leads to a fatal error when accessing array keys like $saved_imagefilesize.
Proposed fix:
This prevents fatal errors and ensures graceful error handling consistent with WordPress coding standards.
Steps to reproduce:
Feedback welcome. Happy to iterate if needed.
Thanks!