diff --git a/src/wp-includes/formatting.php b/src/wp-includes/formatting.php index 258a261bd4983..1c5535b735368 100644 --- a/src/wp-includes/formatting.php +++ b/src/wp-includes/formatting.php @@ -4674,12 +4674,14 @@ function esc_url( $url, $protocols = null, $_context = 'display' ) { /* * If the URL doesn't appear to contain a scheme, we presume * it needs http:// prepended (unless it's a relative link - * starting with /, # or ?, or a PHP file). + * starting with /, # or ?, or a PHP file). If the first item + * in $protocols is 'https', then https:// is prepended. */ if ( ! str_contains( $url, ':' ) && ! in_array( $url[0], array( '/', '#', '?' ), true ) && ! preg_match( '/^[a-z0-9-]+?\.php/i', $url ) ) { - $url = 'http://' . $url; + $scheme = ( is_array( $protocols ) && 'https' === reset( $protocols ) ) ? 'https://' : 'http://'; + $url = $scheme . $url; } // Replace ampersands and single quotes only when displaying. diff --git a/tests/phpunit/tests/formatting/escUrl.php b/tests/phpunit/tests/formatting/escUrl.php index 6fdd582617a19..e994ecdebd30b 100644 --- a/tests/phpunit/tests/formatting/escUrl.php +++ b/tests/phpunit/tests/formatting/escUrl.php @@ -90,16 +90,48 @@ public function test_encoding() { } /** + * @ticket 23605 + * @ticket 52886 + * * @covers ::wp_allowed_protocols */ public function test_protocol() { $this->assertSame( 'http://example.com', esc_url( 'http://example.com' ) ); $this->assertSame( '', esc_url( 'nasty://example.com/' ) ); $this->assertSame( - '', + 'https://example.com', + esc_url( + 'example.com', + array( + 'https', + ) + ) + ); + $this->assertSame( + 'http://example.com', esc_url( 'example.com', array( + 'http', + ) + ) + ); + $this->assertSame( + 'https://example.com', + esc_url( + 'example.com', + array( + 'https', + 'http', + ) + ) + ); + $this->assertSame( + 'http://example.com', + esc_url( + 'example.com', + array( + 'http', 'https', ) )