summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorxjm2015-06-13 22:32:53 -0500
committerxjm2015-06-13 22:34:41 -0500
commitc6cc4fa122dc4d9e8c0ff0143c179ff6af7a9c83 (patch)
tree4e73cead3603baec54c9824edb222c2ae0b4c90c
parent287d1e197ee82abf3fe428dc6af2d1b23e7e831a (diff)
Issue #2501705 by tetranz, pwolanin, Cottser, joelpittet, akalata: Remove SafeMarkup::set() in LinkGenerator and document SafeMarkup::set() in LinkGeneratorTest
-rw-r--r--core/lib/Drupal/Core/Utility/LinkGenerator.php18
-rw-r--r--core/tests/Drupal/Tests/Core/Utility/LinkGeneratorTest.php37
-rw-r--r--core/tests/Drupal/Tests/Core/Utility/UnroutedUrlAssemblerTest.php2
3 files changed, 47 insertions, 10 deletions
diff --git a/core/lib/Drupal/Core/Utility/LinkGenerator.php b/core/lib/Drupal/Core/Utility/LinkGenerator.php
index ab2d232..128dafd 100644
--- a/core/lib/Drupal/Core/Utility/LinkGenerator.php
+++ b/core/lib/Drupal/Core/Utility/LinkGenerator.php
@@ -125,26 +125,26 @@ class LinkGenerator implements LinkGeneratorInterface {
// Allow other modules to modify the structure of the link.
$this->moduleHandler->alter('link', $variables);
- // Move attributes out of options. generateFromRoute(() doesn't need them.
- $attributes = new Attribute($variables['options']['attributes']);
+ // Move attributes out of options since generateFromRoute() doesn't need
+ // them. Include a placeholder for the href.
+ $attributes = array('href' => '') + $variables['options']['attributes'];
unset($variables['options']['attributes']);
$url->setOptions($variables['options']);
- // The result of the url generator is a plain-text URL. Because we are using
- // it here in an HTML argument context, we need to encode it properly.
if (!$collect_cacheability_metadata) {
- $url = SafeMarkup::checkPlain($url->toString($collect_cacheability_metadata));
+ $url_string = $url->toString($collect_cacheability_metadata);
}
else {
$generated_url = $url->toString($collect_cacheability_metadata);
- $url = SafeMarkup::checkPlain($generated_url->getGeneratedUrl());
+ $url_string = $generated_url->getGeneratedUrl();
$generated_link = GeneratedLink::createFromObject($generated_url);
}
+ // The result of the URL generator is a plain-text URL to use as the href
+ // attribute, and it is escaped by \Drupal\Core\Template\Attribute.
+ $attributes['href'] = $url_string;
- // Make sure the link text is sanitized.
- $safe_text = SafeMarkup::escape($variables['text']);
+ $result = SafeMarkup::format('<a@attributes>@text</a>', array('@attributes' => new Attribute($attributes), '@text' => $variables['text']));
- $result = SafeMarkup::set('<a href="' . $url . '"' . $attributes . '>' . $safe_text . '</a>');
return $collect_cacheability_metadata ? $generated_link->setGeneratedLink($result) : $result;
}
diff --git a/core/tests/Drupal/Tests/Core/Utility/LinkGeneratorTest.php b/core/tests/Drupal/Tests/Core/Utility/LinkGeneratorTest.php
index 5bf2b94..fde662c 100644
--- a/core/tests/Drupal/Tests/Core/Utility/LinkGeneratorTest.php
+++ b/core/tests/Drupal/Tests/Core/Utility/LinkGeneratorTest.php
@@ -14,6 +14,7 @@ use Drupal\Core\Link;
use Drupal\Core\Url;
use Drupal\Core\Utility\LinkGenerator;
use Drupal\Tests\UnitTestCase;
+use Drupal\Core\DependencyInjection\ContainerBuilder;
/**
* @coversDefaultClass \Drupal\Core\Utility\LinkGenerator
@@ -181,6 +182,37 @@ class LinkGeneratorTest extends UnitTestCase {
}
/**
+ * Tests the generate() method with a url containing double quotes.
+ *
+ * @covers ::generate
+ */
+ public function testGenerateUrlWithQuotes() {
+ $this->urlAssembler->expects($this->once())
+ ->method('assemble')
+ ->with('base:example', array('query' => array('foo' => '"bar"', 'zoo' => 'baz')) + $this->defaultOptions)
+ ->will($this->returnValue('/example?foo=%22bar%22&zoo=baz'));
+
+ $path_validator = $this->getMock('Drupal\Core\Path\PathValidatorInterface');
+ $container_builder = new ContainerBuilder();
+ $container_builder->set('path.validator', $path_validator);
+ \Drupal::setContainer($container_builder);
+
+ $path = '/example?foo="bar"&zoo=baz';
+ $url = Url::fromUserInput($path);
+ $url->setUrlGenerator($this->urlGenerator);
+ $url->setUnroutedUrlAssembler($this->urlAssembler);
+
+ $result = $this->linkGenerator->generate('Drupal', $url);
+
+ $this->assertLink(array(
+ 'attributes' => array(
+ 'href' => '/example?foo=%22bar%22&zoo=baz',
+ ),
+ 'content' => 'Drupal',
+ ), $result, 1);
+ }
+
+ /**
* Tests the link method with additional attributes.
*
* @see \Drupal\Core\Utility\LinkGenerator::generate()
@@ -332,7 +364,9 @@ class LinkGeneratorTest extends UnitTestCase {
),
), $result);
- // Test that safe HTML is output inside the anchor tag unescaped.
+ // Test that safe HTML is output inside the anchor tag unescaped. The
+ // SafeMarkup::set() call is an intentional unit test for the interaction
+ // between SafeMarkup and the LinkGenerator.
$url = new Url('test_route_5', array());
$url->setUrlGenerator($this->urlGenerator);
$result = $this->linkGenerator->generate(SafeMarkup::set('<em>HTML output</em>'), $url);
@@ -342,6 +376,7 @@ class LinkGeneratorTest extends UnitTestCase {
'tag' => 'em',
),
), $result);
+ $this->assertTrue(strpos($result, '<em>HTML output</em>') !== FALSE);
}
/**
diff --git a/core/tests/Drupal/Tests/Core/Utility/UnroutedUrlAssemblerTest.php b/core/tests/Drupal/Tests/Core/Utility/UnroutedUrlAssemblerTest.php
index 0433561..98fab07 100644
--- a/core/tests/Drupal/Tests/Core/Utility/UnroutedUrlAssemblerTest.php
+++ b/core/tests/Drupal/Tests/Core/Utility/UnroutedUrlAssemblerTest.php
@@ -125,6 +125,8 @@ class UnroutedUrlAssemblerTest extends UnitTestCase {
return [
['base:example', [], FALSE, '/example'],
['base:example', ['query' => ['foo' => 'bar']], FALSE, '/example?foo=bar'],
+ ['base:example', ['query' => ['foo' => '"bar"']], FALSE, '/example?foo=%22bar%22'],
+ ['base:example', ['query' => ['foo' => '"bar"', 'zoo' => 'baz']], FALSE, '/example?foo=%22bar%22&zoo=baz'],
['base:example', ['fragment' => 'example', ], FALSE, '/example#example'],
['base:example', [], TRUE, '/subdir/example'],
['base:example', ['query' => ['foo' => 'bar']], TRUE, '/subdir/example?foo=bar'],