Changeset 63002 for trunk/tests/phpunit/tests/ajax/wpAjaxImageEditor.php
- Timestamp:
- 08/04/2026 01:56:04 AM (2 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/tests/phpunit/tests/ajax/wpAjaxImageEditor.php
r59202 r63002 195 195 $this->assertSameSetsWithIndex( $pre_file_sizes, $post_restore_file_sizes, 'Filesize should have restored after restoring the original image.' ); 196 196 } 197 198 /** 199 * Ensure editing an image does not fatal when the attachment metadata has no usable `sizes` data. 200 * 201 * Attachment metadata is not guaranteed to contain a `sizes` array. It can be missing when 202 * sub-size generation never ran or failed (for example `wp_create_image_subsizes()` returns an 203 * empty array when the file cannot be parsed), or when it is removed by a plugin filtering 204 * `wp_get_attachment_metadata`. `wp_save_image()` only validates that the metadata itself is an 205 * array, then passes `$meta['sizes']` straight to `array_merge()`. 206 * 207 * @ticket 65748 208 * 209 * @covers ::wp_save_image 210 * 211 * @dataProvider data_save_image_with_unusable_sizes_metadata 212 * 213 * @param array{ sizes?: mixed } $meta Attachment metadata to store before editing, minus the file-specific keys. 214 */ 215 public function test_save_image_with_unusable_sizes_metadata( array $meta ) { 216 require_once ABSPATH . 'wp-admin/includes/image-edit.php'; 217 218 $filename = DIR_TESTDATA . '/images/canola.jpg'; 219 $contents = file_get_contents( $filename ); 220 $this->assertIsString( $contents ); 221 222 $upload = wp_upload_bits( wp_basename( $filename ), null, $contents ); 223 $id = $this->_make_attachment( $upload ); 224 $this->assertIsInt( $id ); 225 226 $original_meta = wp_get_attachment_metadata( $id ); 227 $this->assertIsArray( $original_meta ); 228 229 // Keep the real file/dimension data, only make `sizes` unusable. 230 $meta = array_merge( 231 wp_array_slice_assoc( $original_meta, array( 'width', 'height', 'file', 'filesize' ) ), 232 $meta 233 ); 234 235 wp_update_attachment_metadata( $id, $meta ); 236 237 $_REQUEST['action'] = 'image-editor'; 238 $_REQUEST['context'] = 'edit-attachment'; 239 $_REQUEST['postid'] = $id; 240 $_REQUEST['target'] = 'all'; 241 $_REQUEST['do'] = 'save'; 242 $_REQUEST['history'] = '[{"c":{"x":5,"y":8,"w":289,"h":322}}]'; 243 244 $ret = wp_save_image( $id ); 245 246 $this->assertObjectNotHasProperty( 'error', $ret, 'Saving the image should not have returned an error.' ); 247 248 $saved_meta = wp_get_attachment_metadata( $id ); 249 250 $this->assertIsArray( $saved_meta, 'The saved attachment metadata should be an array.' ); 251 $this->assertArrayHasKey( 'sizes', $saved_meta ); 252 $this->assertIsArray( $saved_meta['sizes'], 'The saved attachment metadata should contain a `sizes` array.' ); 253 $this->assertArrayHasKey( 'thumbnail', $saved_meta['sizes'], 'The edited image should have regenerated the thumbnail size.' ); 254 } 255 256 /** 257 * Ensure restoring an image does not fatal when the attachment metadata has no usable `sizes` data. 258 * 259 * `wp_restore_image()` writes each backed up size with `$meta['sizes'][ $default_size ] = $data` 260 * without ever checking that `$meta['sizes']` is an array. A scalar value raises 261 * "Cannot use a scalar value as an array", and `false` is deprecated as of PHP 8.1 and 262 * an error as of PHP 9. The same metadata that fatals `wp_save_image()` reaches this code. 263 * 264 * @ticket 65748 265 * 266 * @covers ::wp_restore_image 267 * 268 * @dataProvider data_save_image_with_unusable_sizes_metadata 269 * 270 * @param array{ sizes?: mixed } $meta Replacement `sizes` metadata to store before restoring. 271 */ 272 public function test_restore_image_with_unusable_sizes_metadata( array $meta ) { 273 require_once ABSPATH . 'wp-admin/includes/image-edit.php'; 274 275 $filename = DIR_TESTDATA . '/images/canola.jpg'; 276 $contents = file_get_contents( $filename ); 277 $this->assertIsString( $contents ); 278 279 $upload = wp_upload_bits( wp_basename( $filename ), null, $contents ); 280 $id = $this->_make_attachment( $upload ); 281 $this->assertIsInt( $id ); 282 283 $_REQUEST['action'] = 'image-editor'; 284 $_REQUEST['context'] = 'edit-attachment'; 285 $_REQUEST['postid'] = $id; 286 $_REQUEST['target'] = 'all'; 287 $_REQUEST['do'] = 'save'; 288 $_REQUEST['history'] = '[{"c":{"x":5,"y":8,"w":289,"h":322}}]'; 289 290 // Edit the image first so that `_wp_attachment_backup_sizes` holds the original sizes. 291 wp_save_image( $id ); 292 293 $this->assertNotEmpty( 294 get_post_meta( $id, '_wp_attachment_backup_sizes', true ), 295 'The image edit should have stored backup sizes to restore from.' 296 ); 297 298 // Keep the metadata written by the edit, only make `sizes` unusable. 299 $edited_meta = wp_get_attachment_metadata( $id ); 300 $this->assertIsArray( $edited_meta ); 301 unset( $edited_meta['sizes'] ); 302 303 wp_update_attachment_metadata( $id, array_merge( $edited_meta, $meta ) ); 304 305 wp_restore_image( $id ); 306 307 $restored_meta = wp_get_attachment_metadata( $id ); 308 $this->assertIsArray( $restored_meta ); 309 310 $this->assertArrayHasKey( 'sizes', $restored_meta ); 311 $this->assertIsArray( $restored_meta['sizes'], 'The restored attachment metadata should contain a `sizes` array.' ); 312 $this->assertArrayHasKey( 'thumbnail', $restored_meta['sizes'], 'The restored image should have the thumbnail size restored from the backup sizes.' ); 313 } 314 315 /** 316 * Data provider. 317 * 318 * @return array<non-empty-string, array{ 0: array{ sizes?: mixed } }> 319 */ 320 public function data_save_image_with_unusable_sizes_metadata(): array { 321 return array( 322 'no sizes key' => array( array() ), 323 'null sizes' => array( array( 'sizes' => null ) ), 324 'empty string' => array( array( 'sizes' => '' ) ), 325 'string sizes' => array( array( 'sizes' => 'not-an-array' ) ), 326 'boolean sizes' => array( array( 'sizes' => false ) ), 327 ); 328 } 197 329 }
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)