From 7d183c2bc8a2f364e93e7f9911ae28752212868d Mon Sep 17 00:00:00 2001 From: "Stephen A. Bernhardt" Date: Mon, 2 Feb 2026 10:49:47 -0600 Subject: [PATCH 1/2] Create unit tests --- tests/phpunit/tests/formatting/escUrl.php | 9 +++++++++ 1 file changed, 9 insertions(+) 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' ) ); + } } From 0810cb7f98931b5a2576bf775e273bc4225f0ea0 Mon Sep 17 00:00:00 2001 From: "Stephen A. Bernhardt" Date: Mon, 2 Feb 2026 11:24:33 -0600 Subject: [PATCH 2/2] Changes from 46791-2.diff --- src/wp-includes/formatting.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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://';