Make WordPress Core

Changeset 60973


Ignore:
Timestamp:
10/19/2025 12:19:27 AM (12 hours 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.