Security update for Core, with self-updated composer
[yaffs-website] / web / core / modules / system / src / Tests / Form / TriggeringElementTest.php
1 <?php
2
3 namespace Drupal\system\Tests\Form;
4
5 use Drupal\simpletest\WebTestBase;
6
7 /**
8  * Tests that FAPI correctly determines the triggering element.
9  *
10  * @group Form
11  */
12 class TriggeringElementTest extends WebTestBase {
13
14   /**
15    * Modules to enable.
16    *
17    * @var array
18    */
19   public static $modules = ['form_test'];
20
21   /**
22    * Test the determination of the triggering element when no button
23    * information is included in the POST data, as is sometimes the case when
24    * the ENTER key is pressed in a textfield in Internet Explorer.
25    */
26   public function testNoButtonInfoInPost() {
27     $path = 'form-test/clicked-button';
28     $edit = [];
29     $form_html_id = 'form-test-clicked-button';
30
31     // Ensure submitting a form with no buttons results in no triggering element
32     // and the form submit handler not running.
33     $this->drupalPostForm($path, $edit, NULL, [], [], $form_html_id);
34     $this->assertText('There is no clicked button.', '$form_state->getTriggeringElement() set to NULL.');
35     $this->assertNoText('Submit handler for form_test_clicked_button executed.', 'Form submit handler did not execute.');
36
37     // Ensure submitting a form with one or more submit buttons results in the
38     // triggering element being set to the first one the user has access to. An
39     // argument with 'r' in it indicates a restricted (#access=FALSE) button.
40     $this->drupalPostForm($path . '/s', $edit, NULL, [], [], $form_html_id);
41     $this->assertText('The clicked button is button1.', '$form_state->getTriggeringElement() set to only button.');
42     $this->assertText('Submit handler for form_test_clicked_button executed.', 'Form submit handler executed.');
43
44     $this->drupalPostForm($path . '/s/s', $edit, NULL, [], [], $form_html_id);
45     $this->assertText('The clicked button is button1.', '$form_state->getTriggeringElement() set to first button.');
46     $this->assertText('Submit handler for form_test_clicked_button executed.', 'Form submit handler executed.');
47
48     $this->drupalPostForm($path . '/rs/s', $edit, NULL, [], [], $form_html_id);
49     $this->assertText('The clicked button is button2.', '$form_state->getTriggeringElement() set to first available button.');
50     $this->assertText('Submit handler for form_test_clicked_button executed.', 'Form submit handler executed.');
51
52     // Ensure submitting a form with buttons of different types results in the
53     // triggering element being set to the first button, regardless of type. For
54     // the FAPI 'button' type, this should result in the submit handler not
55     // executing. The types are 's'(ubmit), 'b'(utton), and 'i'(mage_button).
56     $this->drupalPostForm($path . '/s/b/i', $edit, NULL, [], [], $form_html_id);
57     $this->assertText('The clicked button is button1.', '$form_state->getTriggeringElement() set to first button.');
58     $this->assertText('Submit handler for form_test_clicked_button executed.', 'Form submit handler executed.');
59
60     $this->drupalPostForm($path . '/b/s/i', $edit, NULL, [], [], $form_html_id);
61     $this->assertText('The clicked button is button1.', '$form_state->getTriggeringElement() set to first button.');
62     $this->assertNoText('Submit handler for form_test_clicked_button executed.', 'Form submit handler did not execute.');
63
64     $this->drupalPostForm($path . '/i/s/b', $edit, NULL, [], [], $form_html_id);
65     $this->assertText('The clicked button is button1.', '$form_state->getTriggeringElement() set to first button.');
66     $this->assertText('Submit handler for form_test_clicked_button executed.', 'Form submit handler executed.');
67   }
68
69   /**
70    * Test that the triggering element does not get set to a button with
71    * #access=FALSE.
72    */
73   public function testAttemptAccessControlBypass() {
74     $path = 'form-test/clicked-button';
75     $form_html_id = 'form-test-clicked-button';
76
77     // Retrieve a form where 'button1' has #access=FALSE and 'button2' doesn't.
78     $this->drupalGet($path . '/rs/s');
79
80     // Submit the form with 'button1=button1' in the POST data, which someone
81     // trying to get around security safeguards could easily do. We have to do
82     // a little trickery here, to work around the safeguards in drupalPostForm(): by
83     // renaming the text field that is in the form to 'button1', we can get the
84     // data we want into \Drupal::request()->request.
85     $elements = $this->xpath('//form[@id="' . $form_html_id . '"]//input[@name="text"]');
86     $elements[0]['name'] = 'button1';
87     $this->drupalPostForm(NULL, ['button1' => 'button1'], NULL, [], [], $form_html_id);
88
89     // Ensure that the triggering element was not set to the restricted button.
90     // Do this with both a negative and positive assertion, because negative
91     // assertions alone can be brittle. See testNoButtonInfoInPost() for why the
92     // triggering element gets set to 'button2'.
93     $this->assertNoText('The clicked button is button1.', '$form_state->getTriggeringElement() not set to a restricted button.');
94     $this->assertText('The clicked button is button2.', '$form_state->getTriggeringElement() not set to a restricted button.');
95   }
96
97 }