From 0890e0c9d157c0af109fb2ac34b45ecc4e68bf99 Mon Sep 17 00:00:00 2001 From: Joseph Scott Date: Mon, 14 Sep 2026 14:03:23 -0600 Subject: [PATCH] Fatal error in wp_insert_term() when the term name is not a string https://core.trac.wordpress.org/ticket/66108 --- src/wp-includes/class-wp-xmlrpc-server.php | 4 ++ src/wp-includes/taxonomy.php | 3 +- tests/phpunit/tests/term/wpInsertTerm.php | 56 ++++++++++++++++++++++ tests/phpunit/tests/xmlrpc/wp/newPost.php | 37 ++++++++++++++ 4 files changed, 99 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/class-wp-xmlrpc-server.php b/src/wp-includes/class-wp-xmlrpc-server.php index dcb2636d7a726..d4b073bc001e8 100644 --- a/src/wp-includes/class-wp-xmlrpc-server.php +++ b/src/wp-includes/class-wp-xmlrpc-server.php @@ -1666,6 +1666,10 @@ protected function _insert_post( $user, $content_struct ) { $term_names = $post_data['terms_names'][ $taxonomy ]; foreach ( $term_names as $term_name ) { + if ( ! is_string( $term_name ) ) { + return new IXR_Error( 403, __( 'Invalid term name.' ) ); + } + if ( in_array( $term_name, $ambiguous_terms, true ) ) { return new IXR_Error( 401, __( 'Ambiguous term name used in a hierarchical taxonomy. Please use term ID instead.' ) ); } diff --git a/src/wp-includes/taxonomy.php b/src/wp-includes/taxonomy.php index 6dbc336395f74..0242b3a98a92c 100644 --- a/src/wp-includes/taxonomy.php +++ b/src/wp-includes/taxonomy.php @@ -2501,6 +2501,7 @@ function wp_get_object_terms( $object_ids, $taxonomies, $args = array() ) { * @global wpdb $wpdb WordPress database abstraction object. * * @since 2.3.0 + * @since 7.2.0 A non-scalar `$term` now returns a WP_Error instead of causing a fatal error. * * @param string $term The term name to add. * @param string $taxonomy The taxonomy to which to add the term. @@ -2558,7 +2559,7 @@ function wp_insert_term( $term, $taxonomy, $args = array() ) { return new WP_Error( 'invalid_term_id', __( 'Invalid term ID.' ) ); } - if ( '' === trim( $term ) ) { + if ( ! is_scalar( $term ) || '' === trim( $term ) ) { return new WP_Error( 'empty_term_name', __( 'A name is required for this term.' ) ); } diff --git a/tests/phpunit/tests/term/wpInsertTerm.php b/tests/phpunit/tests/term/wpInsertTerm.php index 39754652e3f46..31c7a60d92979 100644 --- a/tests/phpunit/tests/term/wpInsertTerm.php +++ b/tests/phpunit/tests/term/wpInsertTerm.php @@ -76,6 +76,62 @@ public function test_wp_insert_term_term_trims_to_empty_string() { $this->assertSame( 'empty_term_name', $found->get_error_code() ); } + /** + * Tests that a non-scalar term name returns a WP_Error instead of causing a fatal error. + * + * @ticket 66108 + * + * @dataProvider data_wp_insert_term_non_scalar_term_name + * + * @param mixed $term The term name to insert. + */ + public function test_wp_insert_term_non_scalar_term_name( $term ): void { + $found = wp_insert_term( $term, 'post_tag' ); + + $this->assertWPError( $found ); + $this->assertSame( 'empty_term_name', $found->get_error_code() ); + } + + /** + * Data provider. + * + * @return array + */ + public function data_wp_insert_term_non_scalar_term_name(): array { + return array( + 'array' => array( array( 'foo', 'bar' ) ), + 'object' => array( new stdClass() ), + ); + } + + /** + * Tests that a numeric term name is inserted and stored as its string form. + * + * @ticket 66108 + * + * @dataProvider data_wp_insert_term_numeric_term_name + * + * @param int|float $term The term name to insert. + */ + public function test_wp_insert_term_numeric_term_name( $term ): void { + $found = wp_insert_term( $term, 'post_tag' ); + + $this->assertNotWPError( $found ); + $this->assertSame( (string) $term, get_term( $found['term_id'], 'post_tag' )->name ); + } + + /** + * Data provider. + * + * @return array + */ + public function data_wp_insert_term_numeric_term_name(): array { + return array( + 'integer' => array( 2024 ), + 'float' => array( 1.5 ), + ); + } + public function test_wp_insert_term_parent_does_not_exist() { $found = wp_insert_term( 'foo', diff --git a/tests/phpunit/tests/xmlrpc/wp/newPost.php b/tests/phpunit/tests/xmlrpc/wp/newPost.php index c6386a1f23d5b..73fa61a4d26c9 100644 --- a/tests/phpunit/tests/xmlrpc/wp/newPost.php +++ b/tests/phpunit/tests/xmlrpc/wp/newPost.php @@ -345,6 +345,43 @@ public function test_terms_names() { $this->assertSame( 401, $result2->code ); } + /** + * Tests that a non-string term name in `terms_names` returns an error instead of causing a fatal error. + * + * @ticket 66108 + * + * @dataProvider data_terms_names_non_string_term_name + * + * @param mixed $term_name The term name to send. + */ + public function test_terms_names_non_string_term_name( $term_name ): void { + $this->make_user_by_role( 'editor' ); + + $post = array( + 'post_title' => 'Test', + 'terms_names' => array( + 'post_tag' => array( $term_name ), + ), + ); + $result = $this->myxmlrpcserver->wp_newPost( array( 1, 'editor', 'editor', $post ) ); + + $this->assertIXRError( $result ); + $this->assertSame( 403, $result->code ); + $this->assertSame( 'Invalid term name.', $result->message ); + } + + /** + * Data provider. + * + * @return array + */ + public function data_terms_names_non_string_term_name(): array { + return array( + 'array' => array( array( 'foo', 'bar' ) ), + 'integer' => array( 123 ), + ); + } + /** * @ticket 28601 */