From bb37a4017eaf15622a01a4585a013c0f9f56aafd Mon Sep 17 00:00:00 2001 From: Rodrigo Butzke Date: Tue, 27 Jan 2026 15:51:55 -0300 Subject: [PATCH 1/7] Use wp_check_filetype to determine file extension Fix WP_Customize_Media_Control::to_json() extension validation. --- .../customize/class-wp-customize-media-control.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/customize/class-wp-customize-media-control.php b/src/wp-includes/customize/class-wp-customize-media-control.php index af137512c41f3..46572f3cea540 100644 --- a/src/wp-includes/customize/class-wp-customize-media-control.php +++ b/src/wp-includes/customize/class-wp-customize-media-control.php @@ -92,7 +92,9 @@ public function to_json() { * Fake an attachment model - needs all fields used by template. * Note that the default value must be a URL, NOT an attachment ID. */ - $ext = substr( $this->setting->default, -3 ); + $wp_filetype = wp_check_filetype( $this->setting->default ); + $ext = $wp_filetype['ext']; + $type = in_array( $ext, array( 'jpg', 'png', 'gif', 'bmp', 'webp', 'avif' ), true ) ? 'image' : 'document'; $default_attachment = array( From 96220597cf4d22e59a9cb9186808128f93eb737d Mon Sep 17 00:00:00 2001 From: Rodrigo Butzke Date: Tue, 27 Jan 2026 15:59:21 -0300 Subject: [PATCH 2/7] remove whitespace; --- src/wp-includes/customize/class-wp-customize-media-control.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/customize/class-wp-customize-media-control.php b/src/wp-includes/customize/class-wp-customize-media-control.php index 46572f3cea540..904e779ffb9f9 100644 --- a/src/wp-includes/customize/class-wp-customize-media-control.php +++ b/src/wp-includes/customize/class-wp-customize-media-control.php @@ -94,7 +94,7 @@ public function to_json() { */ $wp_filetype = wp_check_filetype( $this->setting->default ); $ext = $wp_filetype['ext']; - + $type = in_array( $ext, array( 'jpg', 'png', 'gif', 'bmp', 'webp', 'avif' ), true ) ? 'image' : 'document'; $default_attachment = array( From d7ad3d62d654174ebb00b15523c07c62db4949d8 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Thu, 29 Jan 2026 12:08:55 -0800 Subject: [PATCH 3/7] Refactor file type check to eliminate redundant variable --- .../customize/class-wp-customize-media-control.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/wp-includes/customize/class-wp-customize-media-control.php b/src/wp-includes/customize/class-wp-customize-media-control.php index 904e779ffb9f9..30eed65599696 100644 --- a/src/wp-includes/customize/class-wp-customize-media-control.php +++ b/src/wp-includes/customize/class-wp-customize-media-control.php @@ -92,9 +92,7 @@ public function to_json() { * Fake an attachment model - needs all fields used by template. * Note that the default value must be a URL, NOT an attachment ID. */ - $wp_filetype = wp_check_filetype( $this->setting->default ); - $ext = $wp_filetype['ext']; - + $ext = wp_check_filetype( $this->setting->default )['ext']; $type = in_array( $ext, array( 'jpg', 'png', 'gif', 'bmp', 'webp', 'avif' ), true ) ? 'image' : 'document'; $default_attachment = array( From 3aa310d25014ff629f2350c9b76d85ec3b7a7e54 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sun, 1 Feb 2026 21:10:45 -0800 Subject: [PATCH 4/7] Add 'jpeg' to the image types --- src/wp-includes/customize/class-wp-customize-media-control.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/customize/class-wp-customize-media-control.php b/src/wp-includes/customize/class-wp-customize-media-control.php index 30eed65599696..6795b5e4bb332 100644 --- a/src/wp-includes/customize/class-wp-customize-media-control.php +++ b/src/wp-includes/customize/class-wp-customize-media-control.php @@ -93,7 +93,7 @@ public function to_json() { * Note that the default value must be a URL, NOT an attachment ID. */ $ext = wp_check_filetype( $this->setting->default )['ext']; - $type = in_array( $ext, array( 'jpg', 'png', 'gif', 'bmp', 'webp', 'avif' ), true ) ? 'image' : 'document'; + $type = in_array( $ext, array( 'jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'avif' ), true ) ? 'image' : 'document'; $default_attachment = array( 'id' => 1, From 428972aea9b07a352a7398bb5297b820f2e19ebe Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sun, 1 Feb 2026 21:30:10 -0800 Subject: [PATCH 5/7] Add test case --- .../phpunit/tests/customize/media-control.php | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 tests/phpunit/tests/customize/media-control.php diff --git a/tests/phpunit/tests/customize/media-control.php b/tests/phpunit/tests/customize/media-control.php new file mode 100644 index 0000000000000..17a1dc941deba --- /dev/null +++ b/tests/phpunit/tests/customize/media-control.php @@ -0,0 +1,77 @@ +wp_customize = $GLOBALS['wp_customize']; + } + + /** + * @ticket 64557 + * + * @covers ::to_json + */ + public function test_to_json() { + $this->wp_customize->add_setting( + 'some_jpg', + array( + 'default' => 'https://example.com/image.jpg', + ) + ); + $this->wp_customize->add_setting( + 'some_avif', + array( + 'default' => 'https://example.com/image.avif', + ) + ); + $this->wp_customize->add_setting( + 'some_pdf', + array( + 'default' => 'https://example.com/image.pdf', + ) + ); + $this->wp_customize->add_setting( 'no_default' ); + + $some_jpg_control = $this->wp_customize->add_control( new WP_Customize_Media_Control( $this->wp_customize, 'some_jpg' ) ); + $some_avif_control = $this->wp_customize->add_control( new WP_Customize_Media_Control( $this->wp_customize, 'some_avif' ) ); + $some_pdf_control = $this->wp_customize->add_control( new WP_Customize_Media_Control( $this->wp_customize, 'some_pdf' ) ); + $no_default_control = $this->wp_customize->add_control( new WP_Customize_Media_Control( $this->wp_customize, 'no_default' ) ); + + $some_jpg_control_json = $some_jpg_control->json(); + $some_avif_control_json = $some_avif_control->json(); + $some_pdf_control_json = $some_pdf_control->json(); + + $this->assertSame( 'image', $some_jpg_control_json['defaultAttachment']['type'] ); + $this->assertSame( 'image', $some_avif_control_json['defaultAttachment']['type'] ); + $this->assertSame( 'document', $some_pdf_control_json['defaultAttachment']['type'] ); + $this->assertArrayNotHasKey( 'defaultAttachment', $no_default_control->json() ); + } + + /** + * Tear down. + */ + public function tear_down() { + $this->wp_customize = null; + unset( $GLOBALS['wp_customize'] ); + parent::tear_down(); + } +} From a0bf0b7ef3f4b92de135abe2824e8b90090b085d Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sun, 1 Feb 2026 21:35:06 -0800 Subject: [PATCH 6/7] Reuse wp_get_ext_types() in favor of hard-coding list of extensions --- .../customize/class-wp-customize-media-control.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/customize/class-wp-customize-media-control.php b/src/wp-includes/customize/class-wp-customize-media-control.php index 6795b5e4bb332..40d644ca84e5e 100644 --- a/src/wp-includes/customize/class-wp-customize-media-control.php +++ b/src/wp-includes/customize/class-wp-customize-media-control.php @@ -92,8 +92,9 @@ public function to_json() { * Fake an attachment model - needs all fields used by template. * Note that the default value must be a URL, NOT an attachment ID. */ - $ext = wp_check_filetype( $this->setting->default )['ext']; - $type = in_array( $ext, array( 'jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'avif' ), true ) ? 'image' : 'document'; + $ext = wp_check_filetype( $this->setting->default )['ext']; + $ext_types = wp_get_ext_types(); + $type = isset( $ext_types['image'] ) && in_array( $ext, $ext_types['image'], true ) ? 'image' : 'document'; $default_attachment = array( 'id' => 1, From 8b4741cc0672b5727f390349e03355c138f89d19 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sun, 1 Feb 2026 21:37:40 -0800 Subject: [PATCH 7/7] Remove needless global override in test --- .../phpunit/tests/customize/media-control.php | 34 ++++++------------- 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/tests/phpunit/tests/customize/media-control.php b/tests/phpunit/tests/customize/media-control.php index 17a1dc941deba..3a2056f96baa6 100644 --- a/tests/phpunit/tests/customize/media-control.php +++ b/tests/phpunit/tests/customize/media-control.php @@ -10,19 +10,12 @@ */ class Test_WP_Customize_Media_Control extends WP_UnitTestCase { - /** - * Manager. - */ - public ?WP_Customize_Manager $wp_customize; - /** * Set up. */ public function set_up() { parent::set_up(); require_once ABSPATH . WPINC . '/class-wp-customize-manager.php'; - $GLOBALS['wp_customize'] = new WP_Customize_Manager(); - $this->wp_customize = $GLOBALS['wp_customize']; } /** @@ -31,30 +24,32 @@ public function set_up() { * @covers ::to_json */ public function test_to_json() { - $this->wp_customize->add_setting( + $manager = new WP_Customize_Manager(); + + $manager->add_setting( 'some_jpg', array( 'default' => 'https://example.com/image.jpg', ) ); - $this->wp_customize->add_setting( + $manager->add_setting( 'some_avif', array( 'default' => 'https://example.com/image.avif', ) ); - $this->wp_customize->add_setting( + $manager->add_setting( 'some_pdf', array( 'default' => 'https://example.com/image.pdf', ) ); - $this->wp_customize->add_setting( 'no_default' ); + $manager->add_setting( 'no_default' ); - $some_jpg_control = $this->wp_customize->add_control( new WP_Customize_Media_Control( $this->wp_customize, 'some_jpg' ) ); - $some_avif_control = $this->wp_customize->add_control( new WP_Customize_Media_Control( $this->wp_customize, 'some_avif' ) ); - $some_pdf_control = $this->wp_customize->add_control( new WP_Customize_Media_Control( $this->wp_customize, 'some_pdf' ) ); - $no_default_control = $this->wp_customize->add_control( new WP_Customize_Media_Control( $this->wp_customize, 'no_default' ) ); + $some_jpg_control = $manager->add_control( new WP_Customize_Media_Control( $manager, 'some_jpg' ) ); + $some_avif_control = $manager->add_control( new WP_Customize_Media_Control( $manager, 'some_avif' ) ); + $some_pdf_control = $manager->add_control( new WP_Customize_Media_Control( $manager, 'some_pdf' ) ); + $no_default_control = $manager->add_control( new WP_Customize_Media_Control( $manager, 'no_default' ) ); $some_jpg_control_json = $some_jpg_control->json(); $some_avif_control_json = $some_avif_control->json(); @@ -65,13 +60,4 @@ public function test_to_json() { $this->assertSame( 'document', $some_pdf_control_json['defaultAttachment']['type'] ); $this->assertArrayNotHasKey( 'defaultAttachment', $no_default_control->json() ); } - - /** - * Tear down. - */ - public function tear_down() { - $this->wp_customize = null; - unset( $GLOBALS['wp_customize'] ); - parent::tear_down(); - } }