diff --git a/src/wp-includes/class-wp-xmlrpc-server.php b/src/wp-includes/class-wp-xmlrpc-server.php index 1fff1bba65adf..8b1ed095aff42 100644 --- a/src/wp-includes/class-wp-xmlrpc-server.php +++ b/src/wp-includes/class-wp-xmlrpc-server.php @@ -6448,7 +6448,11 @@ 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.' ) ); + } $name = sanitize_file_name( $data['name'] ); $type = $data['type']; diff --git a/tests/phpunit/tests/xmlrpc/wp/uploadFile.php b/tests/phpunit/tests/xmlrpc/wp/uploadFile.php index 00cb601b28f3d..7b466c1993b1b 100644 --- a/tests/phpunit/tests/xmlrpc/wp/uploadFile.php +++ b/tests/phpunit/tests/xmlrpc/wp/uploadFile.php @@ -34,4 +34,37 @@ 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() { + $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.' ); + } + + /** + * 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.' ); + } }