From 508064c13931933a3f7f90eba9178faa2c63fb45 Mon Sep 17 00:00:00 2001 From: Joseph Scott Date: Fri, 10 Jul 2026 16:17:56 -0600 Subject: [PATCH 1/3] XML-RPC: mw_newMediaObject, check 4th arg is an array https://core.trac.wordpress.org/ticket/65611 --- src/wp-includes/class-wp-xmlrpc-server.php | 4 ++++ tests/phpunit/tests/xmlrpc/wp/uploadFile.php | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/wp-includes/class-wp-xmlrpc-server.php b/src/wp-includes/class-wp-xmlrpc-server.php index 1fff1bba65adf..b1262f0eb2e47 100644 --- a/src/wp-includes/class-wp-xmlrpc-server.php +++ b/src/wp-includes/class-wp-xmlrpc-server.php @@ -6450,6 +6450,10 @@ public function mw_newMediaObject( $args ) { $password = $this->escape( $args[2] ); $data = $args[3]; + if ( ! is_array( $data ) ) { + return new IXR_Error( 400, __( 'Invalid attachment data.' ) ); + } + $name = sanitize_file_name( $data['name'] ); $type = $data['type']; $bits = $data['bits']; diff --git a/tests/phpunit/tests/xmlrpc/wp/uploadFile.php b/tests/phpunit/tests/xmlrpc/wp/uploadFile.php index 00cb601b28f3d..a766fc907d6f7 100644 --- a/tests/phpunit/tests/xmlrpc/wp/uploadFile.php +++ b/tests/phpunit/tests/xmlrpc/wp/uploadFile.php @@ -34,4 +34,22 @@ public function test_valid_attachment() { $this->assertIsString( $result['url'] ); $this->assertIsString( $result['type'] ); } + + /** + * Tests that a non-array data argument returns an error instead of + * triggering a fatal error. + * + * The data argument (the fourth parameter) is expected to be a struct, + * which is passed to the method as an array. When it is any other type, + * the method must return an IXR_Error rather than attempting to access + * array offsets on a non-array value. + * + * @ticket 65611 + */ + public function test_invalid_attachment_data_should_return_error() { + $result = $this->myxmlrpcserver->mw_newMediaObject( array( 0, 'anyuser', 'anypass', 'not-a-struct' ) ); + + $this->assertIXRError( $result, 'A non-array data argument should return an IXR_Error.' ); + $this->assertSame( 400, $result->code, 'The error code should be 400.' ); + } } From 6953c899b401aa26debd5deed7f7e71ec565dc09 Mon Sep 17 00:00:00 2001 From: Joseph Scott Date: Mon, 13 Jul 2026 13:46:53 -0600 Subject: [PATCH 2/3] Create user for test Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- tests/phpunit/tests/xmlrpc/wp/uploadFile.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/phpunit/tests/xmlrpc/wp/uploadFile.php b/tests/phpunit/tests/xmlrpc/wp/uploadFile.php index a766fc907d6f7..6c521046c6e5e 100644 --- a/tests/phpunit/tests/xmlrpc/wp/uploadFile.php +++ b/tests/phpunit/tests/xmlrpc/wp/uploadFile.php @@ -47,8 +47,9 @@ public function test_valid_attachment() { * @ticket 65611 */ public function test_invalid_attachment_data_should_return_error() { - $result = $this->myxmlrpcserver->mw_newMediaObject( array( 0, 'anyuser', 'anypass', 'not-a-struct' ) ); + $this->make_user_by_role( 'editor' ); + $result = $this->myxmlrpcserver->mw_newMediaObject( array( 0, 'editor', 'editor', 'not-a-struct' ) ); $this->assertIXRError( $result, 'A non-array data argument should return an IXR_Error.' ); $this->assertSame( 400, $result->code, 'The error code should be 400.' ); } From 2a88ccb7f3370f213d7a76e9bc0f470a9440832e Mon Sep 17 00:00:00 2001 From: Joseph Scott Date: Mon, 13 Jul 2026 15:14:59 -0600 Subject: [PATCH 3/3] Check if $args[3] exists and add tests for that. --- src/wp-includes/class-wp-xmlrpc-server.php | 2 +- tests/phpunit/tests/xmlrpc/wp/uploadFile.php | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/class-wp-xmlrpc-server.php b/src/wp-includes/class-wp-xmlrpc-server.php index b1262f0eb2e47..8b1ed095aff42 100644 --- a/src/wp-includes/class-wp-xmlrpc-server.php +++ b/src/wp-includes/class-wp-xmlrpc-server.php @@ -6448,7 +6448,7 @@ public function mw_getCategories( $args ) { public function mw_newMediaObject( $args ) { $username = $this->escape( $args[1] ); $password = $this->escape( $args[2] ); - $data = $args[3]; + $data = $args[3] ?? null; if ( ! is_array( $data ) ) { return new IXR_Error( 400, __( 'Invalid attachment data.' ) ); diff --git a/tests/phpunit/tests/xmlrpc/wp/uploadFile.php b/tests/phpunit/tests/xmlrpc/wp/uploadFile.php index 6c521046c6e5e..7b466c1993b1b 100644 --- a/tests/phpunit/tests/xmlrpc/wp/uploadFile.php +++ b/tests/phpunit/tests/xmlrpc/wp/uploadFile.php @@ -53,4 +53,18 @@ public function test_invalid_attachment_data_should_return_error() { $this->assertIXRError( $result, 'A non-array data argument should return an IXR_Error.' ); $this->assertSame( 400, $result->code, 'The error code should be 400.' ); } + + /** + * Tests that a missing data argument returns an error instead of + * emitting a PHP notice for the undefined argument. + * + * @ticket 65611 + */ + public function test_missing_attachment_data_should_return_error() { + $this->make_user_by_role( 'editor' ); + + $result = $this->myxmlrpcserver->mw_newMediaObject( array( 0, 'editor', 'editor' ) ); + $this->assertIXRError( $result, 'A missing data argument should return an IXR_Error.' ); + $this->assertSame( 400, $result->code, 'The error code should be 400.' ); + } }