diff --git a/src/wp-includes/formatting.php b/src/wp-includes/formatting.php index f59f877775b77..09252115d6f37 100644 --- a/src/wp-includes/formatting.php +++ b/src/wp-includes/formatting.php @@ -4509,10 +4509,10 @@ 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). If the first item - * in $protocols is 'https', then https:// is prepended. + * 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 ) && + if ( ! str_contains( $url, ':' ) && ! in_array( $url[0], array( '.', '/', '#', '?' ), true ) && ! preg_match( '/^[a-z0-9-]+?\.php/i', $url ) ) { $scheme = ( is_array( $protocols ) && 'https' === array_first( $protocols ) ) ? 'https://' : 'http://'; diff --git a/tests/phpunit/tests/formatting/escUrl.php b/tests/phpunit/tests/formatting/escUrl.php index e994ecdebd30b..da4a4aaa33328 100644 --- a/tests/phpunit/tests/formatting/escUrl.php +++ b/tests/phpunit/tests/formatting/escUrl.php @@ -311,4 +311,13 @@ public function test_ipv6_hosts() { $this->assertSame( '//[::FFFF::127.0.0.1]/?foo%5Bbar%5D=baz', esc_url( '//[::FFFF::127.0.0.1]/?foo[bar]=baz' ) ); $this->assertSame( 'http://[::FFFF::127.0.0.1]/?foo%5Bbar%5D=baz', esc_url( 'http://[::FFFF::127.0.0.1]/?foo[bar]=baz' ) ); } + + /** + * @ticket 46791 + */ + public function test_directory_relative_references() { + $this->assertSame( './current-directory', esc_url( './current-directory' ) ); + $this->assertSame( '../parent-directory', esc_url( '../parent-directory' ) ); + $this->assertSame( '../../../../up-four-directories', esc_url( '../../../../up-four-directories' ) ); + } }