Make WordPress Core

Changeset 60973


Ignore:
Timestamp:
10/19/2025 12:19:27 AM (10 months ago)
Author:
westonruter
Message:

General: Improve parsing of sent HTTP Content-Type header to detect HTML response.

This improves adherence to the HTTP spec in extracting the header name and value.

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

Follow-up to [60936].

Props dmsnell, westonruter.
See #43258.

Location:
trunk
Files:
2 edited

Legend:

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

    r60944 r60973  
    927927        $html_content_types   = array( 'text/html', 'application/xhtml+xml' );
    928928        foreach ( headers_list() as $header ) {
    929                 $header_parts = preg_split( '/\s*[:;]\s*/', strtolower( $header ) );
     929                $header_parts = explode( ':', strtolower( $header ), 2 );
    930930                if (
    931                         is_array( $header_parts ) &&
    932                         count( $header_parts ) >= 2 &&
     931                        count( $header_parts ) === 2 &&
    933932                        'content-type' === $header_parts[0]
    934933                ) {
    935                         $is_html_content_type = in_array( $header_parts[1], $html_content_types, true );
     934                        /*
     935                         * This is looking for very specific content types, therefore it
     936                         * doesn’t need to fully parse the header’s value. Instead, it needs
     937                         * only assert that the content type is one of the static HTML types.
     938                         *
     939                         * Example:
     940                         *
     941                         *     Content-Type: text/html; charset=utf8
     942                         *     Content-Type: text/html  ;charset=latin4
     943                         *     Content-Type:application/xhtml+xml
     944                         */
     945                        $media_type           = trim( strtok( $header_parts[1], ';' ), " \t" );
     946                        $is_html_content_type = in_array( $media_type, $html_content_types, true );
    936947                        break; // PHP only sends the first Content-Type header in the list.
    937948                }
  • trunk/tests/phpunit/tests/template.php

    r60945 r60973  
    598598                );
    599599
     600                $this->assertCount( 0, headers_list(), 'Expected no headers to have been sent during unit tests.' );
     601                ini_set( 'default_mimetype', 'text/html' ); // Since sending a header won't work.
     602
    600603                $initial_ob_level = ob_get_level();
    601604                $this->assertTrue( wp_start_template_enhancement_output_buffer(), 'Expected wp_start_template_enhancement_output_buffer() to return true indicating the output buffer started.' );
     
    676679                        }
    677680                );
     681
     682                $this->assertCount( 0, headers_list(), 'Expected no headers to have been sent during unit tests.' );
     683                ini_set( 'default_mimetype', 'text/html' ); // Since sending a header won't work.
    678684
    679685                $initial_ob_level = ob_get_level();
     
    741747                );
    742748
     749                $this->assertCount( 0, headers_list(), 'Expected no headers to have been sent during unit tests.' );
     750                ini_set( 'default_mimetype', 'application/xhtml+xml' ); // Since sending a header won't work.
     751
    743752                $initial_ob_level = ob_get_level();
    744753                $this->assertTrue( wp_start_template_enhancement_output_buffer(), 'Expected wp_start_template_enhancement_output_buffer() to return true indicating the output buffer started.' );
     
    750759                        <html lang="en">
    751760                        <head>
     761                                <meta charset="utf-8">
    752762                                <title>Unprocessed</title>
    753763                        </head>
     
    756766                                <!-- ... -->
    757767                <?php ob_clean(); // Clean the buffer started by wp_start_template_enhancement_output_buffer(), allowing the following document to replace the above.. ?>
     768                <?php echo '<?xml version="1.0" encoding="UTF-8"?>'; ?>
    758769                <!DOCTYPE html>
    759                 <html lang="en">
     770                <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    760771                        <head>
     772                                <meta charset="utf-8" />
    761773                                <title>Template Replaced</title>
    762774                        </head>
     
    800812                $this->assertSame( $initial_ob_level + 1, ob_get_level(), 'Expected the output buffer level to have been incremented.' );
    801813
     814                $this->assertCount( 0, headers_list(), 'Expected no headers to have been sent during unit tests.' );
    802815                ini_set( 'default_mimetype', 'application/json' ); // Since sending a header won't work.
     816
    803817                $json = wp_json_encode(
    804818                        array(
Note: See TracChangeset for help on using the changeset viewer.