Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 namespace Drupal\Tests\locale\Kernel;
|
Chris@0
|
4
|
Chris@0
|
5 use Drupal\KernelTests\KernelTestBase;
|
Chris@0
|
6
|
Chris@0
|
7 /**
|
Chris@0
|
8 * Tests locale translation safe string handling.
|
Chris@0
|
9 *
|
Chris@0
|
10 * @group locale
|
Chris@0
|
11 */
|
Chris@0
|
12 class LocaleStringIsSafeTest extends KernelTestBase {
|
Chris@0
|
13
|
Chris@0
|
14 /**
|
Chris@0
|
15 * Modules to enable.
|
Chris@0
|
16 *
|
Chris@0
|
17 * @var array
|
Chris@0
|
18 */
|
Chris@0
|
19 public static $modules = ['locale', 'locale_test'];
|
Chris@0
|
20
|
Chris@0
|
21 /**
|
Chris@0
|
22 * Tests for locale_string_is_safe().
|
Chris@0
|
23 */
|
Chris@0
|
24 public function testLocaleStringIsSafe() {
|
Chris@0
|
25 // Check a translatable string without HTML.
|
Chris@0
|
26 $string = 'Hello world!';
|
Chris@0
|
27 $result = locale_string_is_safe($string);
|
Chris@0
|
28 $this->assertTrue($result);
|
Chris@0
|
29
|
Chris@0
|
30 // Check a translatable string which includes trustable HTML.
|
Chris@0
|
31 $string = 'Hello <strong>world</strong>!';
|
Chris@0
|
32 $result = locale_string_is_safe($string);
|
Chris@0
|
33 $this->assertTrue($result);
|
Chris@0
|
34
|
Chris@0
|
35 // Check an untranslatable string which includes untrustable HTML (according
|
Chris@0
|
36 // to the locale_string_is_safe() function definition).
|
Chris@0
|
37 $string = 'Hello <img src="world.png" alt="world" />!';
|
Chris@0
|
38 $result = locale_string_is_safe($string);
|
Chris@0
|
39 $this->assertFalse($result);
|
Chris@0
|
40
|
Chris@0
|
41 // Check a translatable string which includes a token in an href attribute.
|
Chris@0
|
42 $string = 'Hi <a href="[current-user:url]">user</a>';
|
Chris@0
|
43 $result = locale_string_is_safe($string);
|
Chris@0
|
44 $this->assertTrue($result);
|
Chris@0
|
45 }
|
Chris@0
|
46
|
Chris@0
|
47 /**
|
Chris@0
|
48 * Tests if a translated and tokenized string is properly escaped by Twig.
|
Chris@0
|
49 *
|
Chris@0
|
50 * In each assert* call we add a new line at the expected result to match the
|
Chris@0
|
51 * newline at the end of the template file.
|
Chris@0
|
52 */
|
Chris@0
|
53 public function testLocalizedTokenizedString() {
|
Chris@0
|
54 $tests_to_do = [
|
Chris@0
|
55 1 => [
|
Chris@0
|
56 'original' => 'Go to the <a href="[locale_test:security_test1]">frontpage</a>',
|
Chris@0
|
57 'replaced' => 'Go to the <a href="javascript:alert(&#039;Mooooh!&#039;);">frontpage</a>',
|
Chris@0
|
58 ],
|
Chris@0
|
59 2 => [
|
Chris@0
|
60 'original' => 'Hello <strong>[locale_test:security_test2]</strong>!',
|
Chris@0
|
61 'replaced' => 'Hello <strong>&lt;script&gt;alert(&#039;Mooooh!&#039;);&lt;/script&gt;</strong>!',
|
Chris@0
|
62 ],
|
Chris@0
|
63 ];
|
Chris@0
|
64
|
Chris@0
|
65 foreach ($tests_to_do as $i => $test) {
|
Chris@0
|
66 $original_string = $test['original'];
|
Chris@0
|
67 $rendered_original_string = \Drupal::theme()->render('locale_test_tokenized', ['content' => $original_string]);
|
Chris@0
|
68 // Twig assumes that strings are unsafe so it escapes them, and so the
|
Chris@0
|
69 // original and the rendered version should be different.
|
Chris@0
|
70 $this->assertNotEqual(
|
Chris@0
|
71 $rendered_original_string,
|
Chris@0
|
72 $original_string . "\n",
|
Chris@0
|
73 'Security test ' . $i . ' before translation'
|
Chris@0
|
74 );
|
Chris@0
|
75
|
Chris@0
|
76 // Pass the original string to the t() function to get it marked as safe.
|
Chris@0
|
77 $safe_string = t($original_string);
|
Chris@0
|
78 $rendered_safe_string = \Drupal::theme()->render('locale_test_tokenized', ['content' => $safe_string]);
|
Chris@0
|
79 // t() function always marks the string as safe so it won't be escaped,
|
Chris@0
|
80 // and should be the same as the original.
|
Chris@0
|
81 $this->assertEqual(
|
Chris@0
|
82 $rendered_safe_string,
|
Chris@0
|
83 $original_string . "\n",
|
Chris@0
|
84 'Security test ' . $i . ' after translation before token replacement'
|
Chris@0
|
85 );
|
Chris@0
|
86
|
Chris@0
|
87 // Replace tokens in the safe string to inject it with dangerous content.
|
Chris@0
|
88 // @see locale_test_tokens().
|
Chris@0
|
89 $unsafe_string = \Drupal::token()->replace($safe_string);
|
Chris@0
|
90 $rendered_unsafe_string = \Drupal::theme()->render('locale_test_tokenized', ['content' => $unsafe_string]);
|
Chris@0
|
91 // Token replacement changes the string so it is not marked as safe
|
Chris@0
|
92 // anymore. Check it is escaped the way we expect.
|
Chris@0
|
93 $this->assertEqual(
|
Chris@0
|
94 $rendered_unsafe_string,
|
Chris@0
|
95 $test['replaced'] . "\n",
|
Chris@0
|
96 'Security test ' . $i . ' after translation after token replacement'
|
Chris@0
|
97 );
|
Chris@0
|
98 }
|
Chris@0
|
99 }
|
Chris@0
|
100
|
Chris@0
|
101 }
|