From 546841949f99a9c748bbf25de0a0c70a431bc148 Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Tue, 26 Mar 2019 23:11:52 +0000 Subject: [PATCH] Bootstrap/Load: Add support for XML requests to `wp_die()`. In addition to AJAX, XML-RPC, JSON, and JSONP requests, `wp_die()` now handles XML requests correctly, returning information in the expected content type. Props spacedmonkey, birgire. Fixes #46026. See #44458. Built from https://develop.svn.wordpress.org/trunk@45016 git-svn-id: http://core.svn.wordpress.org/trunk@44825 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/functions.php | 102 +++++++++++++++++++++++++++++--------- wp-includes/load.php | 33 ++++++++++++ wp-includes/version.php | 2 +- 3 files changed, 113 insertions(+), 24 deletions(-) diff --git a/wp-includes/functions.php b/wp-includes/functions.php index 0bb42018f9..10a60896ec 100644 --- a/wp-includes/functions.php +++ b/wp-includes/functions.php @@ -3007,9 +3007,21 @@ function wp_die( $message = '', $title = '', $args = array() ) { * @param callable $function Callback function name. */ $function = apply_filters( 'wp_die_xmlrpc_handler', '_xmlrpc_wp_die_handler' ); + } elseif ( wp_is_xml_request() + || function_exists( 'is_feed' ) && is_feed() + || function_exists( 'is_comment_feed' ) && is_comment_feed() + || function_exists( 'is_trackback' ) && is_trackback() ) { + /** + * Filters the callback for killing WordPress execution for XML requests. + * + * @since 5.2.0 + * + * @param callable $function Callback function name. + */ + $function = apply_filters( 'wp_die_xml_handler', '_xml_wp_die_handler' ); } else { /** - * Filters the callback for killing WordPress execution for all non-Ajax, non-XML-RPC requests. + * Filters the callback for killing WordPress execution for all non-Ajax, non-JSON, non-XML requests. * * @since 3.0.0 * @@ -3218,6 +3230,48 @@ function _default_wp_die_handler( $message, $title = '', $args = array() ) { } } +/** + * Kills WordPress execution and displays Ajax response with an error message. + * + * This is the handler for wp_die() when processing Ajax requests. + * + * @since 3.4.0 + * @access private + * + * @param string $message Error message. + * @param string $title Optional. Error title (unused). Default empty. + * @param string|array $args Optional. Arguments to control behavior. Default empty array. + */ +function _ajax_wp_die_handler( $message, $title = '', $args = array() ) { + // Set default 'response' to 200 for AJAX requests. + $args = wp_parse_args( + $args, + array( 'response' => 200 ) + ); + + list( $message, $title, $r ) = _wp_die_process_input( $message, $title, $args ); + + if ( ! headers_sent() ) { + // This is intentional. For backward-compatibility, support passing null here. + if ( null !== $args['response'] ) { + status_header( $r['response'] ); + } + nocache_headers(); + } + + if ( is_scalar( $message ) ) { + $message = (string) $message; + } else { + $message = '0'; + } + + if ( $r['exit'] ) { + die( $message ); + } + + echo $message; +} + /** * Kills WordPress execution and displays JSON response with an error message. * @@ -3331,45 +3385,47 @@ function _xmlrpc_wp_die_handler( $message, $title = '', $args = array() ) { } /** - * Kills WordPress execution and displays Ajax response with an error message. + * Kill WordPress execution and display XML message with error message. * - * This is the handler for wp_die() when processing Ajax requests. + * This is the handler for wp_die when processing XML requests. * - * @since 3.4.0 + * @since 5.2.0 * @access private * * @param string $message Error message. - * @param string $title Optional. Error title (unused). Default empty. + * @param string $title Optional. Error title. Default empty. * @param string|array $args Optional. Arguments to control behavior. Default empty array. */ -function _ajax_wp_die_handler( $message, $title = '', $args = array() ) { - // Set default 'response' to 200 for AJAX requests. - $args = wp_parse_args( - $args, - array( 'response' => 200 ) - ); - +function _xml_wp_die_handler( $message, $title = '', $args = array() ) { list( $message, $title, $r ) = _wp_die_process_input( $message, $title, $args ); + $message = htmlspecialchars( $message ); + $title = htmlspecialchars( $title ); + + $xml = << + {$r['code']} + <![CDATA[{$title}]]> + + + {$r['response']} + + + +EOD; + if ( ! headers_sent() ) { - // This is intentional. For backward-compatibility, support passing null here. - if ( null !== $args['response'] ) { + header( 'Content-Type: text/xml; charset=utf-8' ); + if ( null !== $r['response'] ) { status_header( $r['response'] ); } nocache_headers(); } - if ( is_scalar( $message ) ) { - $message = (string) $message; - } else { - $message = '0'; - } - + echo $xml; if ( $r['exit'] ) { - die( $message ); + die(); } - - echo $message; } /** diff --git a/wp-includes/load.php b/wp-includes/load.php index eba596ed1b..566bbeedbf 100644 --- a/wp-includes/load.php +++ b/wp-includes/load.php @@ -1529,3 +1529,36 @@ function wp_is_jsonp_request() { return $jsonp_enabled; } + +/** + * + * Checks whether current request is a XML request, or is expecting a XML response. + * + * @since 5.2.0 + * + * @return bool True if Accepts or Content-Type headers contain xml, false otherwise. + */ +function wp_is_xml_request() { + $accepted = array( + 'text/xml', + 'application/rss+xml', + 'application/atom+xml', + 'application/rdf+xml', + 'text/xml+oembed', + 'application/xml+oembed', + ); + + if ( isset( $_SERVER['HTTP_ACCEPT'] ) ) { + foreach ( $accepted as $type ) { + if ( false !== strpos( $_SERVER['HTTP_ACCEPT'], $type ) ) { + return true; + } + } + } + + if ( isset( $_SERVER['CONTENT_TYPE'] ) && in_array( $_SERVER['CONTENT_TYPE'], $accepted, true ) ) { + return true; + } + + return false; +} diff --git a/wp-includes/version.php b/wp-includes/version.php index af80917cb9..f24465f2e2 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -13,7 +13,7 @@ * * @global string $wp_version */ -$wp_version = '5.2-alpha-45015'; +$wp_version = '5.2-alpha-45016'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.