Make WordPress Core


Ignore:
Timestamp:
12/16/2020 02:24:07 PM (4 years ago)
Author:
iandunn
Message:

Feed: Merge multiple header values to avoid fatal error.

When SimplePie parses HTTP headers, it combines multiple values for the same header into a comma-separated string. WP_SimplePie_File overrides the parsing, but was leaving them as an array instead.

That lead to a fatal error in PHP 8, because other parts of the codebase ended up passing an array to a function that expected a string.

Props david.binda, litemotiv, inc2734, NicolasKulka, hellofromTonya, mbabker, skithund, SergeyBiryukov, desrosj, timothyblynjacobs.
Reviewed by SergeyBiryukov, iandunn.
Merges [49803] and [49805] to the 5.6 branch.
Fixes #51056. See #51956.

Location:
branches/5.6
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/5.6

  • branches/5.6/src/wp-includes/class-wp-simplepie-file.php

    r49120 r49806  
    1111 * Core class for fetching remote files and reading local files with SimplePie.
    1212 *
     13 * This uses Core's HTTP API to make requests, which gives plugins the ability
     14 * to hook into the process.
     15 *
    1316 * @since 2.8.0
    1417 *
     
    2225     * @since 2.8.0
    2326     * @since 3.2.0 Updated to use a PHP5 constructor.
     27     * @since 5.6.1 Multiple headers are concatenated into a comma-separated string, rather than remaining
     28     *              an array.
    2429     *
    2530     * @param string       $url             Remote file URL.
     
    6166                $this->error   = 'WP HTTP Error: ' . $res->get_error_message();
    6267                $this->success = false;
     68
    6369            } else {
    64                 $this->headers     = wp_remote_retrieve_headers( $res );
     70                $this->headers = wp_remote_retrieve_headers( $res );
     71
     72                /*
     73                 * SimplePie expects multiple headers to be stored as a comma-separated string, but
     74                 * `wp_remote_retrieve_headers()` returns them as an array, so they need to be
     75                 * converted.
     76                 *
     77                 * The only exception to that is the `content-type` header, which should ignore any
     78                 * previous values and only use the last one.
     79                 *
     80                 * @see SimplePie_HTTP_Parser::new_line().
     81                 */
     82                foreach ( $this->headers as $name => $value ) {
     83                    if ( ! is_array( $value ) ) {
     84                        continue;
     85                    }
     86
     87                    if ( 'content-type' === $name ) {
     88                        $this->headers[ $name ] = array_pop( $value );
     89                    } else {
     90                        $this->headers[ $name ] = implode( ', ', $value );
     91                    }
     92                }
     93
    6594                $this->body        = wp_remote_retrieve_body( $res );
    6695                $this->status_code = wp_remote_retrieve_response_code( $res );
Note: See TracChangeset for help on using the changeset viewer.