From aa8a5a14517127997cdabd448252385e044a5c44 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Thu, 13 Aug 2026 16:17:09 +0530 Subject: [PATCH] Media: Guard the image size lookup in `image_constrain_size_for_editor()`. [63177] replaced `in_array( $size, array_keys( $_wp_additional_image_sizes ), true )` with `isset( $_wp_additional_image_sizes[ $size ] )`. The two are not equivalent when `$size` is not a valid array key type: `in_array()` accepts any value and returns `false`, while using the same value as an array offset emits a diagnostic. On PHP 8.5, a `null` size now emits "Using null as an array offset is deprecated", a float emits an implicit conversion notice, and an object throws a `TypeError`. All three were silent before [63177]. `$size` reaches this line unfiltered from public API, via `wp_get_attachment_image_url()`, `wp_get_attachment_image_src()` and `image_downsize()`. Only `is_array()` is handled earlier in the function. This checks that `$size` is a valid array key type before performing the lookup, which restores the previous behaviour while keeping the constant-time lookup. Follow-up to [63177]. See #65842. Co-Authored-By: Claude Opus 5 --- src/wp-includes/media.php | 2 +- tests/phpunit/tests/image/size.php | 58 ++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/media.php b/src/wp-includes/media.php index 075ca04700489..87bea16dbe74e 100644 --- a/src/wp-includes/media.php +++ b/src/wp-includes/media.php @@ -114,7 +114,7 @@ function image_constrain_size_for_editor( $width, $height, $size = 'medium', $co if ( (int) $content_width > 0 ) { $max_width = min( (int) $content_width, $max_width ); } - } elseif ( isset( $_wp_additional_image_sizes[ $size ] ) ) { + } elseif ( ( is_string( $size ) || is_int( $size ) ) && isset( $_wp_additional_image_sizes[ $size ] ) ) { $max_width = (int) $_wp_additional_image_sizes[ $size ]['width']; $max_height = (int) $_wp_additional_image_sizes[ $size ]['height']; // Only in admin. Assume that theme authors know what they're doing. diff --git a/tests/phpunit/tests/image/size.php b/tests/phpunit/tests/image/size.php index c8c6234b23742..eaa83b08f1f47 100644 --- a/tests/phpunit/tests/image/size.php +++ b/tests/phpunit/tests/image/size.php @@ -208,4 +208,62 @@ public function test_constrain_size_for_editor_full() { $content_width = $_content_width; } + + /** + * Tests that an additional image size registered via add_image_size() is used + * to constrain the dimensions. + * + * @ticket 65842 + */ + public function test_constrain_size_for_editor_additional_image_size() { + add_image_size( 'test-size', 300, 200 ); + + $out = image_constrain_size_for_editor( 600, 400, 'test-size' ); + + remove_image_size( 'test-size' ); + + $this->assertSame( array( 300, 200 ), $out ); + } + + /** + * Tests that a size which is not a valid array key does not cause a PHP error. + * + * A size that does not match a registered image size should fall through to + * the unconstrained branch, without being used as an array offset. + * + * On PHP 8.5, using null as an array offset emits a deprecation notice, and + * using an object or a float emits a TypeError or a deprecation notice + * respectively. The test suite converts these into test failures. + * + * @ticket 65842 + * + * @dataProvider data_constrain_size_for_editor_invalid_size + * + * @param mixed $size Requested image size. + */ + public function test_constrain_size_for_editor_invalid_size( $size ) { + add_image_size( 'test-size', 300, 200 ); + + $out = image_constrain_size_for_editor( 600, 400, $size ); + + remove_image_size( 'test-size' ); + + $this->assertSame( array( 600, 400 ), $out ); + } + + /** + * Data provider. + * + * @return array[] + */ + public function data_constrain_size_for_editor_invalid_size() { + return array( + 'null' => array( null ), + 'false' => array( false ), + 'empty string' => array( '' ), + 'integer zero' => array( 0 ), + 'a float' => array( 1.5 ), + 'an object' => array( new stdClass() ), + ); + } }