Make WordPress Core

Changeset 61405


Ignore:
Timestamp:
12/24/2025 06:46:29 AM (8 weeks ago)
Author:
westonruter
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].

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

Location:
trunk
Files:
2 edited

Legend:

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

    r61369 r61405  
    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 );
  • trunk/tests/phpunit/tests/admin/exportWp.php

    r61369 r61405  
    324324        $this->assertCount( $comment_count, $comment_tags, 'Export should include all comments when not filtered.' );
    325325    }
     326
     327    /**
     328     * Tests that export handles posts with NULL postmeta values without fatal errors.
     329     *
     330     * @ticket 64347
     331     */
     332    public function test_export_with_null_postmeta_values() {
     333        global $wpdb;
     334
     335        $post_id = self::factory()->post->create(
     336            array(
     337                'post_title'   => 'Test Post with NULL Meta',
     338                'post_content' => 'Test content',
     339                'post_type'    => 'post',
     340            )
     341        );
     342
     343        // Add multiple types of postmeta values.
     344        add_post_meta( $post_id, 'string_meta', 'normal string' );
     345        add_post_meta( $post_id, 'numeric_string_meta', 123 );
     346        add_post_meta( $post_id, 'empty_string_meta', '' );
     347        add_post_meta(
     348            $post_id,
     349            'array_meta',
     350            array(
     351                'key' => 'value',
     352            )
     353        );
     354
     355        // Directly insert NULL and non-string values into postmeta.
     356        $wpdb->insert(
     357            $wpdb->postmeta,
     358            array(
     359                'post_id'    => $post_id,
     360                'meta_key'   => 'null_meta',
     361                'meta_value' => null,
     362            ),
     363            array( '%d', '%s', '%s' )
     364        );
     365
     366        $xml = $this->get_the_export(
     367            array(
     368                'content' => 'post',
     369            )
     370        );
     371
     372        $this->assertNotFalse( $xml, 'Export should not fail with NULL postmeta values' );
     373        $this->assertGreaterThan( 0, count( $xml->channel->item ), 'Export should contain items' );
     374
     375        // Post should be present in export.
     376        $found_post = false;
     377        foreach ( $xml->channel->item as $item ) {
     378            $wp_item = $item->children( 'wp', true );
     379            if ( (int) $wp_item->post_id === $post_id ) {
     380                $found_post = true;
     381                break;
     382            }
     383        }
     384
     385        $this->assertTrue( $found_post, 'Post with NULL metadata should be included in export' );
     386    }
     387
     388    /**
     389     * Tests that export handles comments with NULL values without fatal errors.
     390     *
     391     * @ticket 64347
     392     */
     393    public function test_export_with_null_comment_values() {
     394        global $wpdb;
     395
     396        $post_id = self::factory()->post->create(
     397            array(
     398                'post_title' => 'Test Post for Comments',
     399                'post_type'  => 'post',
     400            )
     401        );
     402
     403        $comment_id = self::factory()->comment->create(
     404            array(
     405                'comment_post_ID' => $post_id,
     406                'comment_content' => 'Test comment',
     407            )
     408        );
     409
     410        // Insert NULL comment meta.
     411        $wpdb->insert(
     412            $wpdb->commentmeta,
     413            array(
     414                'comment_id' => $comment_id,
     415                'meta_key'   => 'null_comment_meta',
     416                'meta_value' => null,
     417            ),
     418            array( '%d', '%s', '%s' )
     419        );
     420
     421        $xml = $this->get_the_export(
     422            array(
     423                'content' => 'post',
     424            )
     425        );
     426
     427        $this->assertNotFalse( $xml, 'Export should not fail with NULL comment meta values' );
     428        $this->assertGreaterThan( 0, count( $xml->channel->item ), 'Export should contain items' );
     429    }
     430
     431    /**
     432     * Tests that export handles term meta with NULL values without fatal errors.
     433     *
     434     * @ticket 64347
     435     */
     436    public function test_export_with_null_term_meta_values() {
     437        global $wpdb;
     438
     439        // Create term.
     440        $term = self::factory()->term->create(
     441            array(
     442                'taxonomy' => 'category',
     443                'name'     => 'Test Category',
     444            )
     445        );
     446
     447        $post_id = self::factory()->post->create(
     448            array(
     449                'post_title'  => 'Test Post with Category',
     450                'post_type'   => 'post',
     451                'post_status' => 'publish',
     452            )
     453        );
     454
     455        wp_set_object_terms( $post_id, $term, 'category' );
     456
     457        // Insert NULL term meta.
     458        $wpdb->insert(
     459            $wpdb->termmeta,
     460            array(
     461                'term_id'    => $term,
     462                'meta_key'   => 'null_term_meta',
     463                'meta_value' => null,
     464            ),
     465            array( '%d', '%s', '%s' )
     466        );
     467
     468        $xml = $this->get_the_export(
     469            array(
     470                'content' => 'all',
     471            )
     472        );
     473
     474        $this->assertNotFalse( $xml, 'Export should not fail with NULL term meta values' );
     475        $this->assertGreaterThan( 0, count( $xml->channel->item ), 'Export should contain items' );
     476    }
    326477}
Note: See TracChangeset for help on using the changeset viewer.