SafeMarkupKernelTest.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. <?php
  2. namespace Drupal\KernelTests\Component\Utility;
  3. use Drupal\Component\Render\FormattableMarkup;
  4. use Drupal\Core\Url;
  5. use Drupal\KernelTests\KernelTestBase;
  6. /**
  7. * Provides a test covering integration of SafeMarkup with other systems.
  8. *
  9. * @group Utility
  10. */
  11. class SafeMarkupKernelTest extends KernelTestBase {
  12. /**
  13. * {@inheritdoc}
  14. */
  15. public static $modules = ['system'];
  16. /**
  17. * {@inheritdoc}
  18. */
  19. protected function setUp() {
  20. parent::setUp();
  21. $this->container->get('router.builder')->rebuild();
  22. }
  23. /**
  24. * Gets arguments for FormattableMarkup based on Url::fromUri() parameters.
  25. *
  26. * @param string $uri
  27. * The URI of the resource.
  28. * @param array $options
  29. * The options to pass to Url::fromUri().
  30. *
  31. * @return array
  32. * Array containing:
  33. * - ':url': A URL string.
  34. *
  35. * @see \Drupal\Component\Render\FormattableMarkup
  36. */
  37. protected static function getSafeMarkupUriArgs($uri, $options = []) {
  38. $args[':url'] = Url::fromUri($uri, $options)->toString();
  39. return $args;
  40. }
  41. /**
  42. * Tests URL ":placeholders" in \Drupal\Component\Render\FormattableMarkup.
  43. *
  44. * @dataProvider providerTestSafeMarkupUri
  45. */
  46. public function testSafeMarkupUri($string, $uri, $options, $expected) {
  47. $args = self::getSafeMarkupUriArgs($uri, $options);
  48. $this->assertEquals($expected, new FormattableMarkup($string, $args));
  49. }
  50. /**
  51. * @return array
  52. */
  53. public function providerTestSafeMarkupUri() {
  54. $data = [];
  55. $data['routed-url'] = [
  56. 'Hey giraffe <a href=":url">MUUUH</a>',
  57. 'route:system.admin',
  58. [],
  59. 'Hey giraffe <a href="/admin">MUUUH</a>',
  60. ];
  61. $data['routed-with-query'] = [
  62. 'Hey giraffe <a href=":url">MUUUH</a>',
  63. 'route:system.admin',
  64. ['query' => ['bar' => 'baz#']],
  65. 'Hey giraffe <a href="/admin?bar=baz%23">MUUUH</a>',
  66. ];
  67. $data['routed-with-fragment'] = [
  68. 'Hey giraffe <a href=":url">MUUUH</a>',
  69. 'route:system.admin',
  70. ['fragment' => 'bar&lt;'],
  71. 'Hey giraffe <a href="/admin#bar&amp;lt;">MUUUH</a>',
  72. ];
  73. $data['unrouted-url'] = [
  74. 'Hey giraffe <a href=":url">MUUUH</a>',
  75. 'base://foo',
  76. [],
  77. 'Hey giraffe <a href="/foo">MUUUH</a>',
  78. ];
  79. $data['unrouted-with-query'] = [
  80. 'Hey giraffe <a href=":url">MUUUH</a>',
  81. 'base://foo',
  82. ['query' => ['bar' => 'baz#']],
  83. 'Hey giraffe <a href="/foo?bar=baz%23">MUUUH</a>',
  84. ];
  85. $data['unrouted-with-fragment'] = [
  86. 'Hey giraffe <a href=":url">MUUUH</a>',
  87. 'base://foo',
  88. ['fragment' => 'bar&lt;'],
  89. 'Hey giraffe <a href="/foo#bar&amp;lt;">MUUUH</a>',
  90. ];
  91. $data['mailto-protocol'] = [
  92. 'Hey giraffe <a href=":url">MUUUH</a>',
  93. 'mailto:test@example.com',
  94. [],
  95. 'Hey giraffe <a href="mailto:test@example.com">MUUUH</a>',
  96. ];
  97. return $data;
  98. }
  99. /**
  100. * @dataProvider providerTestSafeMarkupUriWithException
  101. */
  102. public function testSafeMarkupUriWithExceptionUri($string, $uri) {
  103. // Should throw an \InvalidArgumentException, due to Uri::toString().
  104. $this->setExpectedException(\InvalidArgumentException::class);
  105. $args = self::getSafeMarkupUriArgs($uri);
  106. new FormattableMarkup($string, $args);
  107. }
  108. /**
  109. * @return array
  110. */
  111. public function providerTestSafeMarkupUriWithException() {
  112. $data = [];
  113. $data['js-protocol'] = [
  114. 'Hey giraffe <a href=":url">MUUUH</a>',
  115. "javascript:alert('xss')",
  116. ];
  117. $data['js-with-fromCharCode'] = [
  118. 'Hey giraffe <a href=":url">MUUUH</a>',
  119. "javascript:alert(String.fromCharCode(88,83,83))",
  120. ];
  121. $data['non-url-with-colon'] = [
  122. 'Hey giraffe <a href=":url">MUUUH</a>',
  123. "llamas: they are not URLs",
  124. ];
  125. $data['non-url-with-html'] = [
  126. 'Hey giraffe <a href=":url">MUUUH</a>',
  127. '<span>not a url</span>',
  128. ];
  129. return $data;
  130. }
  131. }