diff --git a/composer.lock b/composer.lock index 6c58cb455f6..23057050a12 100644 --- a/composer.lock +++ b/composer.lock @@ -652,7 +652,7 @@ "dist": { "type": "path", "url": "core", - "reference": "00a84fa61ee921f106f7912c3ca0393a2c328e68" + "reference": "38c1ef280518a68c80c796780c4f94a259f50fc0" }, "require": { "asm89/stack-cors": "^1.1", @@ -875,10 +875,7 @@ "license": [ "GPL-2.0-or-later" ], - "description": "Drupal is an open source content management platform powering millions of websites and applications.", - "transport-options": { - "relative": true - } + "description": "Drupal is an open source content management platform powering millions of websites and applications." }, { "name": "drupal/core-project-message", @@ -886,7 +883,7 @@ "dist": { "type": "path", "url": "composer/Plugin/ProjectMessage", - "reference": "d55605e98b8eb1d14bf049124838fdf0c85a9524" + "reference": "ed6afc20bfed583e5325ca86f78d07a653d6045c" }, "require": { "composer-plugin-api": "^1.1 || ^2", @@ -908,10 +905,7 @@ "homepage": "https://www.drupal.org/project/drupal", "keywords": [ "drupal" - ], - "transport-options": { - "relative": true - } + ] }, { "name": "drupal/core-vendor-hardening", @@ -919,7 +913,7 @@ "dist": { "type": "path", "url": "composer/Plugin/VendorHardening", - "reference": "29f9f91029bb46c2c3d14f17f151b66ce3e66b5f" + "reference": "6773d713a655ec8a5ac8c29cd5df653cfec6d3cc" }, "require": { "composer-plugin-api": "^1.1 || ^2", @@ -941,10 +935,7 @@ "homepage": "https://www.drupal.org/project/drupal", "keywords": [ "drupal" - ], - "transport-options": { - "relative": true - } + ] }, { "name": "easyrdf/easyrdf", @@ -1546,12 +1537,6 @@ "laminas", "zf" ], - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], "time": "2020-05-20T16:45:56+00:00" }, { @@ -2224,20 +2209,6 @@ ], "description": "Symfony ClassLoader Component", "homepage": "https://symfony.com", - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], "time": "2020-03-15T09:38:08+00:00" }, { @@ -2310,20 +2281,6 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], "time": "2020-05-30T18:58:05+00:00" }, { @@ -2380,20 +2337,6 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], "time": "2020-05-22T18:25:20+00:00" }, { @@ -2465,20 +2408,6 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], "time": "2020-05-30T21:06:01+00:00" }, { @@ -2542,20 +2471,6 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], "time": "2020-05-05T15:06:23+00:00" }, { @@ -2610,20 +2525,6 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], "time": "2020-05-16T13:15:54+00:00" }, { @@ -2714,20 +2615,6 @@ ], "description": "Symfony HttpKernel Component", "homepage": "https://symfony.com", - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], "time": "2020-05-31T05:14:17+00:00" }, { @@ -2786,20 +2673,6 @@ "polyfill", "portable" ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], "time": "2020-05-12T16:14:59+00:00" }, { @@ -2859,20 +2732,6 @@ "portable", "shim" ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], "time": "2020-05-12T16:47:27+00:00" }, { @@ -2935,20 +2794,6 @@ "portable", "shim" ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], "time": "2020-05-12T16:47:27+00:00" }, { @@ -3008,20 +2853,6 @@ "portable", "shim" ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], "time": "2020-05-12T16:47:27+00:00" }, { @@ -3078,20 +2909,6 @@ "portable", "shim" ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], "time": "2020-05-12T16:47:27+00:00" }, { @@ -3151,20 +2968,6 @@ "portable", "shim" ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], "time": "2020-05-12T16:47:27+00:00" }, { @@ -3220,20 +3023,6 @@ "portable", "shim" ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], "time": "2020-05-12T16:47:27+00:00" }, { @@ -3286,20 +3075,6 @@ "polyfill", "shim" ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], "time": "2020-05-12T16:14:59+00:00" }, { @@ -3349,20 +3124,6 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], "time": "2020-05-23T17:05:51+00:00" }, { @@ -3502,20 +3263,6 @@ "uri", "url" ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], "time": "2020-05-30T19:50:06+00:00" }, { @@ -3595,20 +3342,6 @@ ], "description": "Symfony Serializer Component", "homepage": "https://symfony.com", - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], "time": "2020-05-30T18:58:05+00:00" }, { @@ -3679,20 +3412,6 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com", - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], "time": "2020-05-30T18:58:05+00:00" }, { @@ -3779,20 +3498,6 @@ ], "description": "Symfony Validator Component", "homepage": "https://symfony.com", - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], "time": "2020-05-30T18:43:38+00:00" }, { @@ -3852,20 +3557,6 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], "time": "2020-05-11T07:51:54+00:00" }, { @@ -4272,16 +3963,6 @@ "ssl", "tls" ], - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], "time": "2020-04-08T08:27:21+00:00" }, { @@ -4326,9 +4007,6 @@ "ext-zip": "Enabling the zip extension allows you to unzip archives", "ext-zlib": "Allow gzip compression of HTTP requests" }, - "bin": [ - "bin/composer" - ], "type": "library", "extra": { "branch-alias": { @@ -4363,16 +4041,6 @@ "dependency", "package" ], - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], "time": "2020-05-06T08:28:10+00:00" }, { @@ -4477,12 +4145,6 @@ "Xdebug", "performance" ], - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - } - ], "time": "2020-03-01T12:26:26+00:00" }, { @@ -6278,16 +5940,6 @@ "parser", "validator" ], - "funding": [ - { - "url": "https://github.com/Seldaek", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/seld/jsonlint", - "type": "tidelift" - } - ], "time": "2020-04-30T19:05:18+00:00" }, { @@ -6440,20 +6092,6 @@ ], "description": "Symfony BrowserKit Component", "homepage": "https://symfony.com", - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], "time": "2020-04-27T06:55:12+00:00" }, { @@ -6507,20 +6145,6 @@ ], "description": "Symfony CssSelector Component", "homepage": "https://symfony.com", - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], "time": "2020-03-16T08:31:04+00:00" }, { @@ -6578,20 +6202,6 @@ ], "description": "Symfony DomCrawler Component", "homepage": "https://symfony.com", - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], "time": "2020-05-22T19:35:43+00:00" }, { @@ -6642,20 +6252,6 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], "time": "2020-05-30T17:48:24+00:00" }, { @@ -6767,20 +6363,6 @@ "redlock", "semaphore" ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], "time": "2020-05-08T10:38:31+00:00" }, { @@ -6846,20 +6428,6 @@ ], "description": "Symfony PHPUnit Bridge", "homepage": "https://symfony.com", - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], "time": "2020-05-21T18:33:26+00:00" }, { @@ -6961,6 +6529,5 @@ "prefer-stable": true, "prefer-lowest": false, "platform": [], - "platform-dev": [], - "plugin-api-version": "1.1.0" + "platform-dev": [] } diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index d2a0313a499..0f8e7f10879 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -681,11 +681,17 @@ function drupal_valid_test_ua($new_prefix = NULL) { // Ensure that no information leaks on production sites. $test_db = new TestDatabase($prefix); $key_file = DRUPAL_ROOT . '/' . $test_db->getTestSitePath() . '/.htkey'; - if (!is_readable($key_file)) { + if (!is_readable($key_file) || is_dir($key_file)) { header($_SERVER['SERVER_PROTOCOL'] . ' 403 Forbidden'); exit; } $private_key = file_get_contents($key_file); + // The string from drupal_generate_test_ua() is 74 bytes long. If we don't + // have it, tests cannot be allowed. + if (empty($private_key) || strlen($private_key) < 74) { + header($_SERVER['SERVER_PROTOCOL'] . ' 403 Forbidden'); + exit; + } // The file properties add more entropy not easily accessible to others. $key = $private_key . filectime(__FILE__) . fileinode(__FILE__); $time_diff = REQUEST_TIME - $time; diff --git a/core/lib/Drupal/Core/Form/FormBuilder.php b/core/lib/Drupal/Core/Form/FormBuilder.php index ae2851ed221..5e8e22a6042 100644 --- a/core/lib/Drupal/Core/Form/FormBuilder.php +++ b/core/lib/Drupal/Core/Form/FormBuilder.php @@ -19,6 +19,7 @@ use Drupal\Core\Security\TrustedCallbackInterface; use Drupal\Core\Theme\ThemeManagerInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpFoundation\FileBag; +use Symfony\Component\HttpFoundation\ParameterBag; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Response; @@ -957,8 +958,16 @@ class FormBuilder implements FormBuilderInterface, FormValidatorInterface, FormS // This value is checked in self::handleInputElement(). $form_state->setInvalidToken(TRUE); + // Ignore all submitted values. + $form_state->setUserInput([]); + + $request = $this->requestStack->getCurrentRequest(); + // Do not trust any POST data. + $request->request = new ParameterBag(); // Make sure file uploads do not get processed. - $this->requestStack->getCurrentRequest()->files = new FileBag(); + $request->files = new FileBag(); + // Ensure PHP globals reflect these changes. + $request->overrideGlobals(); } } } diff --git a/core/lib/Drupal/Core/Form/FormValidator.php b/core/lib/Drupal/Core/Form/FormValidator.php index 57d24cc21e7..2afcb52ba9d 100644 --- a/core/lib/Drupal/Core/Form/FormValidator.php +++ b/core/lib/Drupal/Core/Form/FormValidator.php @@ -124,10 +124,8 @@ class FormValidator implements FormValidatorInterface { * {@inheritdoc} */ public function setInvalidTokenError(FormStateInterface $form_state) { - $url = $this->requestStack->getCurrentRequest()->getRequestUri(); - // Setting this error will cause the form to fail validation. - $form_state->setErrorByName('form_token', $this->t('The form has become outdated. Copy any unsaved work in the form below and then reload this page.', [':link' => $url])); + $form_state->setErrorByName('form_token', $this->t('The form has become outdated. Press the back button, copy any unsaved work in the form, and then reload the page.')); } /** diff --git a/core/modules/file/tests/src/Functional/FileManagedFileElementTest.php b/core/modules/file/tests/src/Functional/FileManagedFileElementTest.php index 348cee7d3a9..3f67a7948a8 100644 --- a/core/modules/file/tests/src/Functional/FileManagedFileElementTest.php +++ b/core/modules/file/tests/src/Functional/FileManagedFileElementTest.php @@ -50,7 +50,7 @@ class FileManagedFileElementTest extends FileFieldTestBase { $file_field_name => \Drupal::service('file_system')->realpath($test_file->getFileUri()), ]; $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertText('The form has become outdated. Copy any unsaved work in the form below'); + $this->assertText('The form has become outdated.'); $last_fid = $this->getLastFileId(); $this->assertEqual($last_fid_prior, $last_fid, 'File was not saved when uploaded with an invalid form token.'); diff --git a/core/modules/jsonapi/src/Controller/EntityResource.php b/core/modules/jsonapi/src/Controller/EntityResource.php index 7f6b5fc9b7b..4bd865bc0a2 100644 --- a/core/modules/jsonapi/src/Controller/EntityResource.php +++ b/core/modules/jsonapi/src/Controller/EntityResource.php @@ -322,7 +322,7 @@ class EntityResource { )); } $data += ['attributes' => [], 'relationships' => []]; - $field_names = array_merge(array_keys($data['attributes']), array_keys($data['relationships'])); + $field_names = array_map([$resource_type, 'getInternalName'], array_merge(array_keys($data['attributes']), array_keys($data['relationships']))); // User resource objects contain a read-only attribute that is not a real // field on the user entity type. diff --git a/core/modules/jsonapi/src/Controller/FileUpload.php b/core/modules/jsonapi/src/Controller/FileUpload.php index eb9fd6cd449..b4a5800ca26 100644 --- a/core/modules/jsonapi/src/Controller/FileUpload.php +++ b/core/modules/jsonapi/src/Controller/FileUpload.php @@ -112,6 +112,7 @@ class FileUpload { * created file entity. */ public function handleFileUploadForExistingResource(Request $request, ResourceType $resource_type, $file_field_name, FieldableEntityInterface $entity) { + $file_field_name = $resource_type->getInternalName($file_field_name); $field_definition = $this->validateAndLoadFieldDefinition($resource_type->getEntityTypeId(), $resource_type->getBundle(), $file_field_name); static::ensureFileUploadAccess($this->currentUser, $field_definition, $entity); @@ -138,7 +139,7 @@ class FileUpload { $entity->save(); $route_parameters = ['entity' => $entity->uuid()]; - $route_name = sprintf('jsonapi.%s.%s.related', $resource_type->getTypeName(), $file_field_name); + $route_name = sprintf('jsonapi.%s.%s.related', $resource_type->getTypeName(), $resource_type->getPublicName($file_field_name)); $related_url = Url::fromRoute($route_name, $route_parameters)->toString(TRUE); $request = Request::create($related_url->getGeneratedUrl(), 'GET', [], $request->cookies->all(), [], $request->server->all()); return $this->httpKernel->handle($request, HttpKernelInterface::SUB_REQUEST); @@ -161,6 +162,7 @@ class FileUpload { * Thrown when there are validation errors. */ public function handleFileUploadForNewResource(Request $request, ResourceType $resource_type, $file_field_name) { + $file_field_name = $resource_type->getInternalName($file_field_name); $field_definition = $this->validateAndLoadFieldDefinition($resource_type->getEntityTypeId(), $resource_type->getBundle(), $file_field_name); static::ensureFileUploadAccess($this->currentUser, $field_definition); @@ -182,7 +184,7 @@ class FileUpload { /* $self_link = new Link(new CacheableMetadata(), $this->entity->toUrl('jsonapi'), ['self']); */ $links = new LinkCollection(['self' => $self_link]); - $relatable_resource_types = $resource_type->getRelatableResourceTypesByField($file_field_name); + $relatable_resource_types = $resource_type->getRelatableResourceTypesByField($resource_type->getPublicName($file_field_name)); $file_resource_type = reset($relatable_resource_types); $resource_object = ResourceObject::createFromEntity($file_resource_type, $file); return new ResourceResponse(new JsonApiDocumentTopLevel(new ResourceObjectData([$resource_object], 1), new NullIncludedData(), $links), 201, []); diff --git a/core/modules/system/tests/src/Functional/Form/FormTest.php b/core/modules/system/tests/src/Functional/Form/FormTest.php index 08d556dc127..31b16d0dc45 100644 --- a/core/modules/system/tests/src/Functional/Form/FormTest.php +++ b/core/modules/system/tests/src/Functional/Form/FormTest.php @@ -251,21 +251,27 @@ class FormTest extends BrowserTestBase { $this->assertSession() ->elementExists('css', 'input[name="form_token"]') ->setValue('invalid token'); + $random_string = $this->randomString(); $edit = [ - 'textfield' => $this->randomString(), + 'textfield' => $random_string, 'checkboxes[bar]' => TRUE, 'select' => 'bar', 'radios' => 'foo', ]; $this->drupalPostForm(NULL, $edit, 'Submit'); $this->assertFieldByXpath('//div[contains(@class, "error")]', NULL, 'Error message is displayed with invalid token even when required fields are filled.'); - $this->assertText('The form has become outdated. Copy any unsaved work in the form below'); - // Verify that input elements retained the posted values. - $this->assertFieldByName('textfield', $edit['textfield']); + + $assert = $this->assertSession(); + $element = $assert->fieldExists('textfield'); + $this->assertEmpty($element->getValue()); + $assert->responseNotContains($random_string); + $this->assertText('The form has become outdated.'); + // Ensure that we don't use the posted values. + $this->assertFieldByName('textfield', ''); $this->assertNoFieldChecked('edit-checkboxes-foo'); - $this->assertFieldChecked('edit-checkboxes-bar'); - $this->assertOptionSelected('edit-select', 'bar'); - $this->assertFieldChecked('edit-radios-foo'); + $this->assertNoFieldChecked('edit-checkboxes-bar'); + $this->assertOptionSelected('edit-select', ''); + $this->assertNoFieldChecked('edit-radios-foo'); // Check another form that has a textarea input. $this->drupalGet(Url::fromRoute('form_test.required')); @@ -278,9 +284,9 @@ class FormTest extends BrowserTestBase { ]; $this->drupalPostForm(NULL, $edit, 'Submit'); $this->assertFieldByXpath('//div[contains(@class, "error")]', NULL, 'Error message is displayed with invalid token even when required fields are filled.'); - $this->assertText('The form has become outdated. Copy any unsaved work in the form below'); - $this->assertFieldByName('textfield', $edit['textfield']); - $this->assertFieldByName('textarea', $edit['textarea']); + $this->assertText('The form has become outdated.'); + $this->assertFieldByName('textfield', ''); + $this->assertFieldByName('textarea', ''); // Check another form that has a number input. $this->drupalGet(Url::fromRoute('form_test.number')); @@ -288,12 +294,14 @@ class FormTest extends BrowserTestBase { ->elementExists('css', 'input[name="form_token"]') ->setValue('invalid token'); $edit = [ - 'integer_step' => mt_rand(1, 100), + // We choose a random value which is higher than the default value, + // so we don't accidentally generate the default value. + 'integer_step' => mt_rand(6, 100), ]; $this->drupalPostForm(NULL, $edit, 'Submit'); $this->assertFieldByXpath('//div[contains(@class, "error")]', NULL, 'Error message is displayed with invalid token even when required fields are filled.'); - $this->assertText('The form has become outdated. Copy any unsaved work in the form below'); - $this->assertFieldByName('integer_step', $edit['integer_step']); + $this->assertText('The form has become outdated.'); + $this->assertFieldByName('integer_step', 5); // Check a form with a Url field $this->drupalGet(Url::fromRoute('form_test.url')); @@ -305,8 +313,8 @@ class FormTest extends BrowserTestBase { ]; $this->drupalPostForm(NULL, $edit, 'Submit'); $this->assertFieldByXpath('//div[contains(@class, "error")]', NULL, 'Error message is displayed with invalid token even when required fields are filled.'); - $this->assertText('The form has become outdated. Copy any unsaved work in the form below'); - $this->assertFieldByName('url', $edit['url']); + $this->assertText('The form has become outdated.'); + $this->assertFieldByName('url', ''); } /** diff --git a/core/modules/system/tests/src/Functional/Form/ValidationTest.php b/core/modules/system/tests/src/Functional/Form/ValidationTest.php index cadf427581e..4633aabba69 100644 --- a/core/modules/system/tests/src/Functional/Form/ValidationTest.php +++ b/core/modules/system/tests/src/Functional/Form/ValidationTest.php @@ -74,7 +74,7 @@ class ValidationTest extends BrowserTestBase { $this->drupalPostForm(NULL, ['name' => 'validate'], 'Save'); $this->assertNoFieldByName('name', '#value changed by #validate', 'Form element #value was not altered.'); $this->assertNoText('Name value: value changed by setValueForElement() in #validate', 'Form element value in $form_state was not altered.'); - $this->assertText('The form has become outdated. Copy any unsaved work in the form below'); + $this->assertText('The form has become outdated.'); } /** diff --git a/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php index f9bc6aee60d..d2b49036726 100644 --- a/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php +++ b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php @@ -832,12 +832,30 @@ class FormBuilderTest extends FormTestBase { $expected_form = $form_id(); $form_arg = $this->getMockForm($form_id, $expected_form); + // Set up some request data so we can be sure it is removed when a token is + // invalid. + $this->request->request->set('foo', 'bar'); + $_POST['foo'] = 'bar'; + $form_state = new FormState(); $input['form_id'] = $form_id; $input['form_token'] = $form_token; + $input['test'] = 'example-value'; $form_state->setUserInput($input); - $this->simulateFormSubmission($form_id, $form_arg, $form_state, FALSE); + $form = $this->simulateFormSubmission($form_id, $form_arg, $form_state, FALSE); $this->assertSame($expected, $form_state->hasInvalidToken()); + if ($expected) { + $this->assertEmpty($form['test']['#value']); + $this->assertEmpty($form_state->getValue('test')); + $this->assertEmpty($_POST); + $this->assertEmpty(iterator_to_array($this->request->request->getIterator())); + } + else { + $this->assertEquals('example-value', $form['test']['#value']); + $this->assertEquals('example-value', $form_state->getValue('test')); + $this->assertEquals('bar', $_POST['foo']); + $this->assertEquals('bar', $this->request->request->get('foo')); + } } public function providerTestInvalidToken() { diff --git a/core/tests/Drupal/Tests/Core/Form/FormTestBase.php b/core/tests/Drupal/Tests/Core/Form/FormTestBase.php index f0cb2f22d6a..b01f1542c60 100644 --- a/core/tests/Drupal/Tests/Core/Form/FormTestBase.php +++ b/core/tests/Drupal/Tests/Core/Form/FormTestBase.php @@ -173,7 +173,7 @@ abstract class FormTestBase extends UnitTestCase { ->getMock(); $this->account = $this->createMock('Drupal\Core\Session\AccountInterface'); $this->themeManager = $this->createMock('Drupal\Core\Theme\ThemeManagerInterface'); - $this->request = new Request(); + $this->request = Request::createFromGlobals(); $this->eventDispatcher = $this->createMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); $this->requestStack = new RequestStack(); $this->requestStack->push($this->request); diff --git a/core/tests/Drupal/Tests/Core/Form/FormValidatorTest.php b/core/tests/Drupal/Tests/Core/Form/FormValidatorTest.php index bf31b475e00..02d98113bb3 100644 --- a/core/tests/Drupal/Tests/Core/Form/FormValidatorTest.php +++ b/core/tests/Drupal/Tests/Core/Form/FormValidatorTest.php @@ -131,7 +131,7 @@ class FormValidatorTest extends UnitTestCase { ->getMock(); $form_state->expects($this->once()) ->method('setErrorByName') - ->with('form_token', 'The form has become outdated. Copy any unsaved work in the form below and then reload this page.'); + ->with('form_token', 'The form has become outdated. Press the back button, copy any unsaved work in the form, and then reload the page.'); $form_state->setValue('form_token', 'some_random_token'); $form_validator->validateForm('test_form_id', $form, $form_state); $this->assertTrue($form_state->isValidationComplete());