diff --git a/src/wp-includes/http.php b/src/wp-includes/http.php index fba9dd3bbaded..d607d3c354bae 100644 --- a/src/wp-includes/http.php +++ b/src/wp-includes/http.php @@ -666,32 +666,88 @@ function ms_allowed_http_request_hosts( $is_external, $host ) { * doesn't exist in the given URL; a string or - in the case of * PHP_URL_PORT - integer when it does. See parse_url()'s return values. */ -function wp_parse_url( $url, $component = -1 ) { - $to_unset = array(); - $url = (string) $url; +if ( class_exists( 'Uri\\WhatWg\\Url', false ) ) { - if ( '//' === substr( $url, 0, 2 ) ) { - $to_unset[] = 'scheme'; - $url = 'placeholder:' . $url; - } elseif ( '/' === substr( $url, 0, 1 ) ) { - $to_unset[] = 'scheme'; - $to_unset[] = 'host'; - $url = 'placeholder://placeholder' . $url; - } + // WHATWG implementation (PHP 8.5+). + function wp_parse_url( $url, $component = -1 ) { + + $to_unset = array(); + $url = (string) $url; + + if ( str_starts_with( $url, '//' ) ) { + $to_unset[] = 'scheme'; + $url = 'placeholder:' . $url; + } elseif ( str_starts_with( $url, '/' ) ) { + $to_unset[] = 'scheme'; + $to_unset[] = 'host'; + $url = 'placeholder://placeholder' . $url; + } - $parts = parse_url( $url ); + $parsed = \Uri\WhatWg\Url::parse( $url ); - if ( false === $parts ) { // Parsing failure. - return $parts; - } + if ( null === $parsed ) { + return false; + } + + $parts = array(); + + foreach ( + array( + 'scheme' => $parsed->getScheme(), + 'host' => $parsed->getAsciiHost(), + 'port' => $parsed->getPort(), + 'user' => $parsed->getUsername(), + 'pass' => $parsed->getPassword(), + 'path' => $parsed->getPath(), + 'query' => $parsed->getQuery(), + 'fragment' => $parsed->getFragment(), + ) + as $key => $value + ) { + if ( null !== $value && '' !== $value ) { + $parts[ $key ] = $value; + } + } + + // Remove the placeholder values. + foreach ( $to_unset as $key ) { + unset( $parts[ $key ] ); + } - // Remove the placeholder values. - foreach ( $to_unset as $key ) { - unset( $parts[ $key ] ); + return _get_component_from_parsed_url_array( $parts, $component ); } +} else { - return _get_component_from_parsed_url_array( $parts, $component ); + // Legacy parse_url implementation. + function wp_parse_url( $url, $component = -1 ) { + + $to_unset = array(); + $url = (string) $url; + + if ( str_starts_with( $url, '//' ) ) { + $to_unset[] = 'scheme'; + $url = 'placeholder:' . $url; + } elseif ( str_starts_with( $url, '/' ) ) { + $to_unset[] = 'scheme'; + $to_unset[] = 'host'; + $url = 'placeholder://placeholder' . $url; + } + + $parts = parse_url( $url ); + + if ( false === $parts ) { + // Parsing failure. + return $parts; + } + + // Remove the placeholder values. + foreach ( $to_unset as $key ) { + unset( $parts[ $key ] ); + } + + return _get_component_from_parsed_url_array( $parts, $component ); + } } /**