Make WordPress Core

Changeset 61540 for branches/6.9


Ignore:
Timestamp:
01/27/2026 10:12:40 PM (8 months ago)
Author:
jorbin
Message:

Export: Fix fatal error when passing null to wxr_cdata() by casting passed value to string.

This ensures that wp_is_valid_utf8() does not cause a type error since it only accepts strings.

Developed in ​https://github.com/WordPress/wordpress-develop/pull/10595

Follow-up to [60630].

Reviewed-by jorbin.
Merges [61405] to the 6.9 branch.

Props hbhalodia, westonruter, desrosj, albigdd, jorbin.
See #38044.
Fixes #64347.

Location:
branches/6.9
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/6.9/src/wp-admin/includes/export.php

    r60632 r61540  
    240240         * @since 2.1.0
    241241         *
    242          * @param string $str String to wrap in XML CDATA tag.
     242         * @param string|null $str String to wrap in XML CDATA tag. May be null.
    243243         * @return string
    244244         */
    245245        function wxr_cdata( $str ) {
     246                $str = (string) $str;
     247
    246248                if ( ! wp_is_valid_utf8( $str ) ) {
    247249                        $str = utf8_encode( $str );
  • branches/6.9/tests/phpunit/tests/admin/exportWp.php

    r57681 r61540  
    291291                $args['author'] = self::$post_ids[ $post_ids_key ]['post_author'];
    292292        }
     293
     294        /**
     295         * Tests that export handles posts with NULL postmeta values without fatal errors.
     296         *
     297         * @ticket 64347
     298         */
     299        public function test_export_with_null_postmeta_values() {
     300                global $wpdb;
     301
     302                $post_id = self::factory()->post->create(
     303                        array(
     304                                'post_title'   => 'Test Post with NULL Meta',
     305                                'post_content' => 'Test content',
     306                                'post_type'    => 'post',
     307                        )
     308                );
     309
     310                // Add multiple types of postmeta values.
     311                add_post_meta( $post_id, 'string_meta', 'normal string' );
     312                add_post_meta( $post_id, 'numeric_string_meta', 123 );
     313                add_post_meta( $post_id, 'empty_string_meta', '' );
     314                add_post_meta(
     315                        $post_id,
     316                        'array_meta',
     317                        array(
     318                                'key' => 'value',
     319                        )
     320                );
     321
     322                // Directly insert NULL and non-string values into postmeta.
     323                $wpdb->insert(
     324                        $wpdb->postmeta,
     325                        array(
     326                                'post_id'    => $post_id,
     327                                'meta_key'   => 'null_meta',
     328                                'meta_value' => null,
     329                        ),
     330                        array( '%d', '%s', '%s' )
     331                );
     332
     333                $xml = $this->get_the_export(
     334                        array(
     335                                'content' => 'post',
     336                        )
     337                );
     338
     339                $this->assertNotFalse( $xml, 'Export should not fail with NULL postmeta values' );
     340                $this->assertGreaterThan( 0, count( $xml->channel->item ), 'Export should contain items' );
     341
     342                // Post should be present in export.
     343                $found_post = false;
     344                foreach ( $xml->channel->item as $item ) {
     345                        $wp_item = $item->children( 'wp', true );
     346                        if ( (int) $wp_item->post_id === $post_id ) {
     347                                $found_post = true;
     348                                break;
     349                        }
     350                }
     351
     352                $this->assertTrue( $found_post, 'Post with NULL metadata should be included in export' );
     353        }
     354
     355        /**
     356         * Tests that export handles comments with NULL values without fatal errors.
     357         *
     358         * @ticket 64347
     359         */
     360        public function test_export_with_null_comment_values() {
     361                global $wpdb;
     362
     363                $post_id = self::factory()->post->create(
     364                        array(
     365                                'post_title' => 'Test Post for Comments',
     366                                'post_type'  => 'post',
     367                        )
     368                );
     369
     370                $comment_id = self::factory()->comment->create(
     371                        array(
     372                                'comment_post_ID' => $post_id,
     373                                'comment_content' => 'Test comment',
     374                        )
     375                );
     376
     377                // Insert NULL comment meta.
     378                $wpdb->insert(
     379                        $wpdb->commentmeta,
     380                        array(
     381                                'comment_id' => $comment_id,
     382                                'meta_key'   => 'null_comment_meta',
     383                                'meta_value' => null,
     384                        ),
     385                        array( '%d', '%s', '%s' )
     386                );
     387
     388                $xml = $this->get_the_export(
     389                        array(
     390                                'content' => 'post',
     391                        )
     392                );
     393
     394                $this->assertNotFalse( $xml, 'Export should not fail with NULL comment meta values' );
     395                $this->assertGreaterThan( 0, count( $xml->channel->item ), 'Export should contain items' );
     396        }
     397
     398        /**
     399         * Tests that export handles term meta with NULL values without fatal errors.
     400         *
     401         * @ticket 64347
     402         */
     403        public function test_export_with_null_term_meta_values() {
     404                global $wpdb;
     405
     406                // Create term.
     407                $term = self::factory()->term->create(
     408                        array(
     409                                'taxonomy' => 'category',
     410                                'name'     => 'Test Category',
     411                        )
     412                );
     413
     414                $post_id = self::factory()->post->create(
     415                        array(
     416                                'post_title'  => 'Test Post with Category',
     417                                'post_type'   => 'post',
     418                                'post_status' => 'publish',
     419                        )
     420                );
     421
     422                wp_set_object_terms( $post_id, $term, 'category' );
     423
     424                // Insert NULL term meta.
     425                $wpdb->insert(
     426                        $wpdb->termmeta,
     427                        array(
     428                                'term_id'    => $term,
     429                                'meta_key'   => 'null_term_meta',
     430                                'meta_value' => null,
     431                        ),
     432                        array( '%d', '%s', '%s' )
     433                );
     434
     435                $xml = $this->get_the_export(
     436                        array(
     437                                'content' => 'all',
     438                        )
     439                );
     440
     441                $this->assertNotFalse( $xml, 'Export should not fail with NULL term meta values' );
     442                $this->assertGreaterThan( 0, count( $xml->channel->item ), 'Export should contain items' );
     443        }
    293444}
Note: See TracChangeset for help on using the changeset viewer.