diff --git a/core/lib/Drupal/Core/Form/FormBuilder.php b/core/lib/Drupal/Core/Form/FormBuilder.php index 8773d4f..c594d8a 100644 --- a/core/lib/Drupal/Core/Form/FormBuilder.php +++ b/core/lib/Drupal/Core/Form/FormBuilder.php @@ -21,6 +21,7 @@ use Drupal\Core\Render\ElementInfoManagerInterface; use Drupal\Core\Theme\ThemeManagerInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\HttpFoundation\FileBag; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Response; @@ -122,6 +123,7 @@ class FormBuilder implements FormBuilderInterface, FormValidatorInterface, FormS 'Drupal\Core\Render\Element\Checkbox::valueCallback', 'Drupal\Core\Render\Element\Checkboxes::valueCallback', 'Drupal\Core\Render\Element\PasswordConfirm::valueCallback', + 'Drupal\Core\Render\Element\Radio::valueCallback', 'Drupal\Core\Render\Element\Radios::valueCallback', 'Drupal\Core\Render\Element\Range::valueCallback', 'Drupal\Core\Render\Element\Select::valueCallback', @@ -856,6 +858,7 @@ public function doBuildForm($form_id, &$element, FormStateInterface &$form_state // Make sure file uploads do not get processed. $_FILES = array(); + $this->requestStack->getCurrentRequest()->files = new FileBag(); } } } diff --git a/core/modules/system/src/Tests/Form/FormTest.php b/core/modules/system/src/Tests/Form/FormTest.php index 10de804..535358e 100644 --- a/core/modules/system/src/Tests/Form/FormTest.php +++ b/core/modules/system/src/Tests/Form/FormTest.php @@ -237,7 +237,7 @@ function testRequiredCheckboxesRadio() { * * Submits a test form containing several types of form elements. */ - function testInputWithInvalidToken() { + public function testInputWithInvalidToken() { // We need to be logged in to have CSRF tokens. $account = $this->createUser(); $this->drupalLogin($account); @@ -258,7 +258,7 @@ function testInputWithInvalidToken() { $this->assertNoFieldChecked('edit-checkboxes-foo'); $this->assertFieldChecked('edit-checkboxes-bar'); $this->assertOptionSelected('edit-select', 'bar'); - // @todo - radios are not retaining the value. + $this->assertFieldChecked('edit-radios-foo'); } /** diff --git a/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php index 9c6d727..efcdedc 100644 --- a/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php +++ b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php @@ -17,6 +17,7 @@ use Drupal\Core\Form\FormInterface; use Drupal\Core\Form\FormState; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Session\AccountInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; @@ -723,6 +724,53 @@ function () {}, return $data; } + /** + * @covers ::doBuildForm + * + * @dataProvider providerTestInvalidToken + */ + public function testInvalidToken($expected, $valid_token, $user_is_authenticated) { + $form_token = 'the_form_token'; + $form_id = 'test_form_id'; + + if (is_bool($valid_token)) { + $this->csrfToken->expects($this->any()) + ->method('get') + ->willReturnArgument(0); + $this->csrfToken->expects($this->atLeastOnce()) + ->method('validate') + ->will($this->returnValueMap([ + [$form_token, $form_id, $valid_token], + [$form_id, $form_id, $valid_token], + ])); + } + + $current_user = $this->prophesize(AccountInterface::class); + $current_user->isAuthenticated()->willReturn($user_is_authenticated); + $property = new \ReflectionProperty(FormBuilder::class, 'currentUser'); + $property->setAccessible(TRUE); + $property->setValue($this->formBuilder, $current_user->reveal()); + + $expected_form = $form_id(); + $form_arg = $this->getMockForm($form_id, $expected_form); + + $form_state = new FormState(); + $input['form_id'] = $form_id; + $input['form_token'] = $form_token; + $form_state->setUserInput($input); + $this->simulateFormSubmission($form_id, $form_arg, $form_state, FALSE); + $this->assertSame($expected, $form_state->hasInvalidToken()); + } + + public function providerTestInvalidToken() { + $data = []; + $data[] = [TRUE, FALSE, TRUE]; + $data[] = [FALSE, TRUE, TRUE]; + $data[] = [FALSE, NULL, FALSE]; + $data[] = [FALSE, NULL, FALSE]; + return $data; + } + } class TestForm implements FormInterface {