From 47cd92b2050f7dd6cfd68460ab3f2c5e95753195 Mon Sep 17 00:00:00 2001 From: webchick <drupal@webchick.net> Date: Fri, 13 Feb 2015 11:35:29 -0800 Subject: [PATCH] Issue #2423579 by mpdonadio, xjm, heilop, Wim Leers, webchick: Url::fromUrl('user-path:/') should throw an exception when a path component without a slash is given --- core/lib/Drupal/Core/Url.php | 6 ++ .../Plugin/Field/FieldWidget/LinkWidget.php | 1 + core/tests/Drupal/Tests/Core/UrlTest.php | 72 +++++++++++++++++++ 3 files changed, 79 insertions(+) diff --git a/core/lib/Drupal/Core/Url.php b/core/lib/Drupal/Core/Url.php index 6a8c17a46e79..8c59abe4d8b5 100644 --- a/core/lib/Drupal/Core/Url.php +++ b/core/lib/Drupal/Core/Url.php @@ -353,6 +353,9 @@ protected static function fromEntityUri(array $uri_parts, array $options, $uri) * * @return \Drupal\Core\Url * A new Url object for a 'user-path:' URI. + * + * @throws \InvalidArgumentException + * Thrown when the URI's path component doesn't have a leading slash. */ protected static function fromUserPathUri(array $uri_parts, array $options) { // Both PathValidator::getUrlIfValidWithoutAccessCheck() and 'base:' URIs @@ -366,6 +369,9 @@ protected static function fromUserPathUri(array $uri_parts, array $options) { $uri_parts['path'] = '<front>'; } else { + if ($uri_parts['path'][0] !== '/') { + throw new \InvalidArgumentException(String::format('The user-path path component "@path" is invalid. Its path component must have a leading slash, e.g. user-path:/foo.', ['@path' => $uri_parts['path']])); + } // Remove the leading slash. $uri_parts['path'] = substr($uri_parts['path'], 1); } diff --git a/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php index 3203423b5edf..e90d41686cdd 100644 --- a/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php +++ b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php @@ -154,6 +154,7 @@ public static function validateUriElement($element, FormStateInterface $form_sta // https://www.drupal.org/node/2421941 if (parse_url($uri, PHP_URL_SCHEME) === 'user-path' && !in_array($element['#value'][0], ['/', '?', '#'], TRUE) && substr($element['#value'], 0, 7) !== '<front>') { $form_state->setError($element, t('Manually entered paths should start with /, ? or #.')); + return; } // If the URI is empty or not well-formed, the link field type's validation diff --git a/core/tests/Drupal/Tests/Core/UrlTest.php b/core/tests/Drupal/Tests/Core/UrlTest.php index 4096e3d2658a..d57ae8b33655 100644 --- a/core/tests/Drupal/Tests/Core/UrlTest.php +++ b/core/tests/Drupal/Tests/Core/UrlTest.php @@ -636,6 +636,78 @@ public function providerTestToUriStringForUserPath() { ]; } + /** + * Tests the fromUri() method with a valid user-path: URI. + * + * @covers ::fromUri + * @dataProvider providerFromValidUserPathUri + */ + public function testFromValidUserPathUri($path) { + $url = Url::fromUri('user-path:' . $path); + $this->assertInstanceOf('Drupal\Core\Url', $url); + } + + /** + * Data provider for testFromValidUserPathUri(). + */ + public function providerFromValidUserPathUri() { + return [ + // Normal paths with a leading slash. + ['/kittens'], + ['/kittens/bengal'], + // Fragments with and without leading slashes. + ['/#about-our-kittens'], + ['/kittens#feeding'], + ['#feeding'], + // Query strings with and without leading slashes. + ['/kittens?page=1000'], + ['/?page=1000'], + ['?page=1000'], + // Paths with various token formats but no leading slash. + ['/[duckies]'], + ['/%bunnies'], + ['/{{ puppies }}'], + // Disallowed characters in the authority (host name) that are valid + // elsewhere in the path. + ['/(:;2&+h^'], + ['/AKI@&hO@'], + ]; + } + + /** + * Tests the fromUri() method with an invalid user-path: URI. + * + * @covers ::fromUri + * @expectedException \InvalidArgumentException + * @dataProvider providerFromInvalidUserPathUri + */ + public function testFromInvalidUserPathUri($path) { + Url::fromUri('user-path:' . $path); + } + + /** + * Data provider for testFromInvalidUserPathUri(). + */ + public function providerFromInvalidUserPathUri() { + return [ + // Normal paths without a leading slash. + ['kittens'], + ['kittens/bengal'], + // Path without a leading slash containing a fragment. + ['kittens#feeding'], + // Path without a leading slash containing a query string. + ['kittens?page=1000'], + // Paths with various token formats but no leading slash. + ['[duckies]'], + ['%bunnies'], + ['{{ puppies }}'], + // Disallowed characters in the authority (host name) that are valid + // elsewhere in the path. + ['(:;2&+h^'], + ['AKI@&hO@'], + ]; + } + /** * Tests the toUriString() method with route: URIs. * -- GitLab