Opened 3 months ago
Closed 2 months ago
#65748 closed defect (bug) (fixed)
Image editor: fatal error when attachment metadata has no `sizes` array
| Reported by: | josephscott | Owned by: | westonruter |
|---|---|---|---|
| Priority: | normal | Milestone: | 7.1 |
| Component: | Media | Version: | |
| Severity: | normal | Keywords: | has-patch has-unit-tests |
| Cc: | Focuses: |
Description
I noticed some fatal errors in wp_save_image() on a site recently.
Uncaught TypeError: array_merge(): Argument #1 must be of type array, null given
That came from this line - https://github.com/WordPress/wordpress-develop/blame/trunk/src/wp-admin/includes/image-edit.php#L1132
$meta['sizes'] = array_merge( $meta['sizes'], $img->multi_resize( $_sizes ) );
While I suspect this is something wrong or a mistake with the image, after looking at the code WordPress needs to make sure that $meta['sizes'] exists before using it.
There is a similar issue with wp_restore_image().
Change History (6)
This ticket was mentioned in PR #12744 on WordPress/wordpress-develop by @josephscott.
3 months ago
#1
- Keywords has-patch has-unit-tests added
nazmulasif commented on PR #12744:
3 months ago
#3
## Test Report
Patch tested: https://github.com/WordPress/wordpress-develop/pull/12744
### Environment
- WordPress: 7.1-beta3-20260728.201755
- Subdirectory: No
- PHP: 7.4.33
- Server: PHP.wasm
- Database: WP_SQLite_Driver (Server: 8.0.38 / Client: 3.51.0)
- Browser: Chrome 150.0.0.0
- OS: macOS
- Theme: Twenty Twenty-Five 1.5
- MU Plugins: None activated
- Plugins:
- Test Reports 1.3.0
### Steps taken
- Launched the WordPress Playground instance built from PR #12744.
- Navigated to Media → Library and uploaded a test image.
- Clicked Edit Image to open the core image editor interface.
- Performed Crop and Scale operations, then saved the modifications.
- Clicked Restore Original Image to revert the image back to its original state.
- Verified that no PHP fatal errors or warnings occurred during the process.
- ✅ Patch is solving the problem
### Expected result
- Image saving, cropping, scaling, and restoring operations should execute successfully without throwing PHP type errors or fatal errors when processing attachment metadata.
### Additional Notes
- Tested via WordPress Playground instance. Crop, scale, and restore functionalities work as expected without any errors.
### Screenshots/Screencast with results
- Screenshot/Screencast before: N/A
- Screenshot/Screencast after: N/A
### Support Content
This ticket was mentioned in Slack in #core-test by noruzzaman. View the logs.
3 months ago
#5
@
2 months ago
Test Report
Patch tested: https://github.com/WordPress/wordpress-develop/pull/12744
Ticket: https://core.trac.wordpress.org/ticket/65748
Environment
- WordPress: 7.0
- Subdirectory: No
- PHP: 8.5.8
- Server: PHP built-in server (WP-CLI
wp server) - Database: SQLite (Studio)
- Browser: Chromium (Playwright)
- OS: macOS
- Theme: Twenty Twenty-Five 1.5
- MU Plugins: 99-studio-loader (Studio)
- Plugins:
- Test Reports 1.3.0
Steps taken
1.Uploaded a JPEG to the Media Library, then removed the sizes key from its
attachment metadata (reproducing the reported "no sizes array" state).
2.On UNPATCHED core: opened the attachment → Edit Image → Rotate 90° left →
Save Edits. → admin-ajax image-editor (do=save) returned HTTP 500
"There has been a critical error on this website."
The editor froze mid-save. Root cause: TypeError, array_merge() at image-edit.php:1127.
3.Applied the patch (guards in wp_save_image() + wp_restore_image()); confirmed php -l reports no syntax errors and both guards are present.
4.Reset the attachment metadata back to "no sizes", reloaded the editor, and
repeated the exact same edit (Rotate 90° left → Save Edits).
→ the identical request now returns {"success":true,"msg":"Image saved"}; the "Image saved" notice shows and the rotated image is displayed.
5.Additionally verified via WP-CLI against all 5 metadata variants from the PR's data provider — missing key / null / / 'not-an-array' / false — for BOTH wp_save_image() and wp_restore_image(), plus the non-array-metadata guard and the normal valid-metadata path.
✅ Patch is solving the problem
Expected result
- When an attachment's metadata has no usable
sizesarray, saving or restoring an image in the editor should NOT throw a fatal. The functions should normalize the missing/invalidsizesto an empty array and complete the edit (regenerating sub-sizes), or return a graceful "Cannot load image metadata." message when the metadata itself is unusable — never a TypeError.
Additional Notes
- Pre-fix: wp_save_image() fatals for ALL five variants at array_merge()
(image-edit.php:1127). wp_restore_image() fatals for scalar-string
sizesat :878; on PHP 8.5, null/false/missing happen to auto-vivify into an array, but the guard is still needed — writing to afalseoffset is deprecated as of PHP 8.1 and an error as of PHP 9, so those cases become fatals on newer runtimes. - Post-fix: 10/10 cases pass (2 functions × 5 variants); non-array metadata returns a graceful error; the normal valid-metadata path is unchanged (no regression).
- Verified through the actual browser image-editor UI AND via WP-CLI for full, deterministic variant coverage.
- The core file was backed up and restored to its original checksum after testing; the disposable admin user and test attachment were deleted.
Screenshots/Screencast with results
- Before (unpatched):https://i.postimg.cc/9MsZDXdy/before.png
Editor frozen mid-save; admin-ajax
image-editor→ HTTP 500, response: "There has been a critical error on this website." - After (patched):https://i.postimg.cc/3Jf7myyj/after.png "Image saved" success notice; rotated image rendered correctly.
Support Content
- Reproduce the "no sizes array" state (WP-CLI):
wp eval '
require_once ABSPATH."wp-admin/includes/image.php";
$up = wp_upload_bits("demo.jpg", null, file_get_contents("/path/to/any.jpg"));
$id = wp_insert_attachment(
array("post_mime_type"=>"image/jpeg","post_status"=>"inherit"),
$upfile
);
$meta = wp_generate_attachment_metadata($id, $upfile);
unset($metasizes); <-- the bug trigger
wp_update_attachment_metadata($id, $meta);
echo "Attachment ID: $id\n";
'
# Then: Media → edit this attachment → Edit Image → Rotate → Save Edits.
- The patch (src/wp-admin/includes/image-edit.php):
wp_restore_image(), after the $backup_sizes check:
if ( ! is_array( $meta ) ) {
$msg->error = ( 'Cannot load image metadata.' );
return $msg;
}
if ( ! isset( $metasizes ) ! is_array( $metasizes ) ) { $metasizes = array();
}
wp_save_image(), before the array_merge():
if ( ! isset( $metasizes ) ! is_array( $metasizes ) ) { $metasizes = array();
}
- Data-provider variants exercised (both functions): 'no sizes key' | 'null' | 'empty string' | 'string' | 'boolean(false)'
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)
https://core.trac.wordpress.org/ticket/65748
AI assistance: Yes
Tool(s): Claude
Model(s): Opus 5
Used for: Writing the tests