From 820aeb12461e53604823030183f9eaeb77ce0a15 Mon Sep 17 00:00:00 2001
From: bcweaver <brianweaver@gmail.com>
Date: Wed, 16 Sep 2020 16:27:39 -0400
Subject: [PATCH] SECURITY update: drupal core 8.9.6

---
 composer.json                                 |   4 +-
 composer.lock                                 |  36 +--
 vendor/composer/installed.json                |  40 +--
 .../Controller/ControllerResolver.php         |   2 +-
 .../ArgumentMetadataFactory.php               |   2 +-
 .../DataCollector/ConfigDataCollector.php     |   2 +-
 .../AddAnnotatedClassesToCachePass.php        |   4 +-
 .../symfony/http-kernel/HttpCache/Store.php   |  41 ++-
 vendor/symfony/http-kernel/Kernel.php         |   6 +-
 .../ContainerControllerResolverTest.php       |  27 +-
 .../DataCollector/ConfigDataCollectorTest.php |   6 +-
 .../RequestDataCollectorTest.php              |   2 +-
 .../FilterControllerArgumentsEventTest.php    |   2 +-
 .../EventListener/TranslatorListenerTest.php  |  28 +-
 .../Tests/HttpCache/HttpCacheTest.php         |  20 +-
 .../Tests/HttpCache/HttpCacheTestCase.php     |   4 +-
 .../http-kernel/Tests/HttpCache/StoreTest.php |  33 +++
 .../http-kernel/Tests/HttpKernelTest.php      |   4 +-
 .../symfony/http-kernel/Tests/KernelTest.php  |  14 +-
 .../Profiler/FileProfilerStorageTest.php      |  10 +-
 web/core/lib/Drupal.php                       |   2 +-
 .../lib/Drupal/Component/Utility/Image.php    |   2 -
 .../Core/Asset/LibraryDiscoveryParser.php     |   2 +-
 .../DeprecatedServicePropertyTrait.php        |   2 +-
 .../ExceptionLoggingSubscriber.php            |   1 +
 web/core/lib/Drupal/Core/Form/FormBuilder.php |   3 +-
 .../lib/Drupal/Core/Logger/RfcLogLevel.php    |   4 +-
 .../lib/Drupal/Core/Render/Element/Email.php  |   8 +-
 web/core/misc/ajax.es6.js                     |   1 +
 web/core/misc/ajax.js                         |   1 +
 web/core/misc/autocomplete.es6.js             |   1 +
 web/core/misc/autocomplete.js                 |   3 +-
 .../src/Functional/IpAddressBlockingTest.php  |   4 +-
 .../tests/src/Functional/BigPipeTest.php      |  11 +-
 .../plugins/drupalimagecaption/plugin.es6.js  |   3 +
 .../js/plugins/drupalimagecaption/plugin.js   |   3 +
 .../views/filter/ModerationStateFilter.php    |  13 +-
 ...tate_filter_base_table_filter_group_or.yml | 268 ++++++++++++++++++
 .../Kernel/ViewsModerationStateFilterTest.php |  32 ++-
 .../src/Functional/DbLogResourceTest.php      |   7 +-
 .../dblog/tests/src/Functional/DbLogTest.php  |  47 ++-
 .../src/Kernel/ConnectionFailureTest.php      |   5 +-
 .../dblog/tests/src/Kernel/DbLogTest.php      |  10 +-
 .../field/tests/src/Kernel/BulkDeleteTest.php |  15 +-
 .../modules/file/src/Element/ManagedFile.php  |   4 +
 .../tests/src/Functional/FilePrivateTest.php  |  16 +-
 .../modules/filter/src/Element/TextFormat.php |   4 +-
 .../filter/src/Entity/FilterFormat.php        |  24 +-
 .../filter/src/FilterFormatInterface.php      |   8 +-
 .../src/Plugin/Filter/FilterCaption.php       |  63 +++-
 .../filter/src/Plugin/Filter/FilterHtml.php   |  22 +-
 .../tests/src/Kernel/FilterKernelTest.php     |  10 +-
 web/core/modules/jsonapi/jsonapi.api.php      |   4 +-
 .../src/Access/EntityAccessChecker.php        |   6 +-
 .../src/Access/RelationshipFieldAccess.php    |   2 +-
 .../src/Access/TemporaryQueryGuard.php        |   2 +-
 .../jsonapi/src/Context/FieldResolver.php     |  18 +-
 .../jsonapi/src/Controller/EntityResource.php |   6 +-
 .../jsonapi/src/Controller/EntryPoint.php     |   2 +-
 .../jsonapi/src/Controller/FileUpload.php     |   4 +-
 ...gisterSerializationClassesCompilerPass.php |   2 +-
 .../jsonapi/src/Encoder/JsonEncoder.php       |   2 +-
 .../src/Entity/EntityValidationTrait.php      |   2 +-
 .../DefaultExceptionSubscriber.php            |   2 +-
 .../JsonApiRequestValidator.php               |   2 +-
 .../ResourceResponseSubscriber.php            |   2 +-
 .../ResourceResponseValidator.php             |   2 +-
 .../EntityAccessDeniedHttpException.php       |   4 +-
 .../UnprocessableHttpEntityException.php      |   2 +-
 .../modules/jsonapi/src/IncludeResolver.php   |   2 +-
 .../jsonapi/src/JsonApiResource/Data.php      |   2 +-
 .../src/JsonApiResource/ErrorCollection.php   |   2 +-
 .../src/JsonApiResource/IncludedData.php      |   2 +-
 .../JsonApiDocumentTopLevel.php               |   2 +-
 .../LabelOnlyResourceObject.php               |   2 +-
 .../jsonapi/src/JsonApiResource/Link.php      |   2 +-
 .../src/JsonApiResource/LinkCollection.php    |   2 +-
 .../src/JsonApiResource/NullIncludedData.php  |   2 +-
 .../src/JsonApiResource/OmittedData.php       |   2 +-
 .../src/JsonApiResource/Relationship.php      |   2 +-
 .../src/JsonApiResource/RelationshipData.php  |   2 +-
 .../JsonApiResource/ResourceIdentifier.php    |   4 +-
 .../ResourceIdentifierInterface.php           |   2 +-
 .../ResourceIdentifierTrait.php               |   2 +-
 .../src/JsonApiResource/ResourceObject.php    |   2 +-
 .../JsonApiResource/ResourceObjectData.php    |   2 +-
 .../JsonApiResource/TopLevelDataInterface.php |   2 +-
 web/core/modules/jsonapi/src/JsonApiSpec.php  |   2 +-
 .../jsonapi/src/JsonapiServiceProvider.php    |   2 +-
 .../Normalizer/ConfigEntityDenormalizer.php   |   2 +-
 .../Normalizer/ContentEntityDenormalizer.php  |   2 +-
 ...ityAccessDeniedHttpExceptionNormalizer.php |   2 +-
 .../src/Normalizer/EntityDenormalizerBase.php |   2 +-
 .../EntityReferenceFieldNormalizer.php        |   2 +-
 .../src/Normalizer/FieldItemNormalizer.php    |   2 +-
 .../src/Normalizer/FieldNormalizer.php        |   2 +-
 .../Normalizer/HttpExceptionNormalizer.php    |   4 +-
 .../JsonApiDocumentTopLevelNormalizer.php     |   6 +-
 .../Normalizer/LinkCollectionNormalizer.php   |   2 +-
 .../jsonapi/src/Normalizer/NormalizerBase.php |   2 +-
 .../ResourceIdentifierNormalizer.php          |   2 +-
 .../Normalizer/ResourceObjectNormalizer.php   |   2 +-
 ...ocessableHttpEntityExceptionNormalizer.php |   2 +-
 .../Value/CacheableNormalization.php          |   2 +-
 .../Normalizer/Value/CacheableOmission.php    |   2 +-
 .../Value/HttpExceptionNormalizerValue.php    |   2 +-
 .../ParamConverter/EntityUuidConverter.php    |   2 +-
 .../ParamConverter/ResourceTypeConverter.php  |   2 +-
 .../jsonapi/src/Query/EntityCondition.php     |   2 +-
 .../src/Query/EntityConditionGroup.php        |   2 +-
 web/core/modules/jsonapi/src/Query/Filter.php |   5 +-
 .../modules/jsonapi/src/Query/OffsetPage.php  |   2 +-
 web/core/modules/jsonapi/src/Query/Sort.php   |   2 +-
 .../modules/jsonapi/src/ResourceResponse.php  |   2 +-
 .../jsonapi/src/ResourceType/ResourceType.php |   2 +-
 .../ResourceType/ResourceTypeAttribute.php    |   2 +-
 .../src/ResourceType/ResourceTypeField.php    |   2 +-
 .../ResourceType/ResourceTypeRelationship.php |   2 +-
 .../ResourceType/ResourceTypeRepository.php   |   2 +-
 .../ResourceTypeRepositoryInterface.php       |   2 +-
 .../InvalidVersionIdentifierException.php     |   2 +-
 .../jsonapi/src/Revisions/NegotiatorBase.php  |   2 +-
 .../ResourceVersionRouteEnhancer.php          |   4 +-
 .../jsonapi/src/Revisions/VersionById.php     |   2 +-
 .../jsonapi/src/Revisions/VersionByRel.php    |   2 +-
 .../src/Revisions/VersionNegotiator.php       |   2 +-
 .../Revisions/VersionNegotiatorInterface.php  |   2 +-
 .../Revisions/VersionNotFoundException.php    |   2 +-
 .../jsonapi/src/Routing/RouteEnhancer.php     |   2 +-
 .../modules/jsonapi/src/Routing/Routes.php    |   2 +-
 .../jsonapi/src/Serializer/Serializer.php     |   4 +-
 .../tests/src/Functional/BlockContentTest.php |   2 +-
 .../tests/src/Functional/CommentTest.php      |   2 +-
 .../Functional/ConfigurableLanguageTest.php   |   4 +-
 .../Functional/ExternalNormalizersTest.php    |   2 +-
 .../src/Functional/JsonApiRegressionTest.php  |  92 ++++--
 .../tests/src/Functional/MediaTest.php        |   2 +-
 .../src/Functional/MenuLinkContentTest.php    |   2 +-
 .../jsonapi/tests/src/Functional/NodeTest.php |   8 +-
 .../tests/src/Functional/ResourceTestBase.php |  23 +-
 .../jsonapi/tests/src/Functional/TermTest.php |   6 +-
 .../Update/ReadOnlyModeUpdateTest.php         |   2 +-
 .../jsonapi/tests/src/Functional/UserTest.php |   6 +-
 .../JsonApiDocumentTopLevelNormalizerTest.php |   2 +-
 .../tests/src/Kernel/Query/FilterTest.php     |   2 +-
 .../Functional/LocaleImportFunctionalTest.php |   6 +-
 .../src/Functional/LocalePluralFormatTest.php |  21 +-
 .../tests/src/Functional/LocaleUpdateBase.php |   8 +-
 .../tests/src/Functional/LocaleUpdateTest.php |  12 +-
 .../migrate_drupal/tests/fixtures/drupal6.php | 191 ++++++++-----
 .../tests/src/Functional/NodeCreationTest.php |   4 +-
 .../src/Kernel/Migrate/d6/MigrateNodeTest.php |  18 +-
 .../src/Kernel/NodeAccessRecordsTest.php      |  30 +-
 web/core/modules/rdf/rdf.module               |  13 +-
 .../src/Functional/CommentAttributesTest.php  |  20 +-
 .../src/Functional/UserAttributesTest.php     |   9 +-
 .../src/Kernel/RdfCommentStorageLoadTest.php  |  46 +++
 .../SearchNodeUpdateAndDeletionTest.php       |  12 +-
 .../src/Controller/ErrorTestController.php    |   4 +-
 .../Database/SelectPagerDefaultTest.php       |   4 +-
 .../tests/src/Functional/Form/StorageTest.php |   7 +-
 .../src/Functional/Module/InstallTest.php     |   2 +-
 .../Functional/Session/SessionHttpsTest.php   |   5 +-
 .../src/Functional/Session/SessionTest.php    |  23 +-
 .../Functional/System/ErrorHandlerTest.php    |   6 +-
 .../Plugin/views/filter/TaxonomyIndexTid.php  |  26 +-
 .../tests/src/Functional/TermIndexTest.php    | 110 ++++---
 .../Views/TaxonomyIndexTidUiTest.php          |  37 +++
 web/core/modules/user/src/AccountForm.php     |   7 +-
 .../user/src/Plugin/Block/UserLoginBlock.php  |   3 +-
 .../tests/src/Functional/UserEditTest.php     |  49 ++++
 .../Kernel/Plugin/RelationshipJoinInTest.php  |  21 +-
 .../src/Kernel/Plugin/RelationshipTest.php    |  35 ++-
 .../src/Controller/ViewsUIController.php      |  17 +-
 .../views_ui/tests/src/Kernel/TagTest.php     |  39 ++-
 .../workspaces/src/WorkspaceManager.php       |   6 +-
 .../ActiveWorkspaceUpdateTest.php             |  10 +-
 .../Core/Asset/LibraryDiscoveryParserTest.php |  18 ++
 .../library_test_files/empty.libraries.yml    |   1 +
 web/core/themes/claro/css/components/form.css |  15 +-
 .../themes/claro/css/components/form.pcss.css |  15 +-
 web/sites/default/settings.pantheon.php       |   4 +-
 182 files changed, 1504 insertions(+), 594 deletions(-)
 create mode 100644 web/core/modules/content_moderation/tests/modules/content_moderation_test_views/config/install/views.view.test_content_moderation_state_filter_base_table_filter_group_or.yml
 create mode 100644 web/core/modules/rdf/tests/src/Kernel/RdfCommentStorageLoadTest.php
 create mode 100644 web/core/tests/Drupal/Tests/Core/Asset/library_test_files/empty.libraries.yml

diff --git a/composer.json b/composer.json
index 767e82ff78..da752f6466 100644
--- a/composer.json
+++ b/composer.json
@@ -105,7 +105,7 @@
         "drupal/config_update": "1.5",
         "drupal/console": "1.8",
         "drupal/content_access": "1.0-alpha1",
-        "drupal/core-recommended": "8.9.3",
+        "drupal/core-recommended": "8.9.6",
         "drupal/crop": "2.1",
         "drupal/ctools": "3.4",
         "drupal/devel": "2.0",
@@ -309,4 +309,4 @@
             "php": "7.3"
         }
     }
-}
+}
\ No newline at end of file
diff --git a/composer.lock b/composer.lock
index 96b3bdc45f..5da0ac4c85 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "e50c5b47d7ac57cabe5d1578e6c466b1",
+    "content-hash": "4b5b35efe0ddebe629171eb4c1046ab9",
     "packages": [
         {
             "name": "alchemy/zippy",
@@ -3375,16 +3375,16 @@
         },
         {
             "name": "drupal/core",
-            "version": "8.9.3",
+            "version": "8.9.6",
             "source": {
                 "type": "git",
                 "url": "https://github.com/drupal/core.git",
-                "reference": "ee02fd4cbe4ac148b4d7e297ec63b3459983862e"
+                "reference": "caf4e756d31dfb0c2e52cd0748e900efe4b57766"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/drupal/core/zipball/ee02fd4cbe4ac148b4d7e297ec63b3459983862e",
-                "reference": "ee02fd4cbe4ac148b4d7e297ec63b3459983862e",
+                "url": "https://api.github.com/repos/drupal/core/zipball/caf4e756d31dfb0c2e52cd0748e900efe4b57766",
+                "reference": "caf4e756d31dfb0c2e52cd0748e900efe4b57766",
                 "shasum": ""
             },
             "require": {
@@ -3607,20 +3607,20 @@
                 "GPL-2.0-or-later"
             ],
             "description": "Drupal is an open source content management platform powering millions of websites and applications.",
-            "time": "2020-08-05T21:49:40+00:00"
+            "time": "2020-09-16T11:22:21+00:00"
         },
         {
             "name": "drupal/core-recommended",
-            "version": "8.9.3",
+            "version": "8.9.6",
             "source": {
                 "type": "git",
                 "url": "https://github.com/drupal/core-recommended.git",
-                "reference": "db5c2fdd4bf3e72aee8c862eca72dd445e704d71"
+                "reference": "6c5c4739afc5549e6089ef34b59c712c8872f154"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/drupal/core-recommended/zipball/db5c2fdd4bf3e72aee8c862eca72dd445e704d71",
-                "reference": "db5c2fdd4bf3e72aee8c862eca72dd445e704d71",
+                "url": "https://api.github.com/repos/drupal/core-recommended/zipball/6c5c4739afc5549e6089ef34b59c712c8872f154",
+                "reference": "6c5c4739afc5549e6089ef34b59c712c8872f154",
                 "shasum": ""
             },
             "require": {
@@ -3632,7 +3632,7 @@
                 "doctrine/common": "v2.7.3",
                 "doctrine/inflector": "v1.2.0",
                 "doctrine/lexer": "1.0.2",
-                "drupal/core": "8.9.3",
+                "drupal/core": "8.9.6",
                 "easyrdf/easyrdf": "0.9.1",
                 "egulias/email-validator": "2.1.17",
                 "guzzlehttp/guzzle": "6.5.4",
@@ -3661,7 +3661,7 @@
                 "symfony/dependency-injection": "v3.4.41",
                 "symfony/event-dispatcher": "v3.4.41",
                 "symfony/http-foundation": "v3.4.41",
-                "symfony/http-kernel": "v3.4.41",
+                "symfony/http-kernel": "v3.4.44",
                 "symfony/polyfill-ctype": "v1.17.0",
                 "symfony/polyfill-iconv": "v1.17.0",
                 "symfony/polyfill-intl-idn": "v1.17.0",
@@ -3689,7 +3689,7 @@
                 "GPL-2.0-or-later"
             ],
             "description": "Locked core dependencies; require this project INSTEAD OF drupal/core.",
-            "time": "2020-08-05T21:49:40+00:00"
+            "time": "2020-09-16T11:22:21+00:00"
         },
         {
             "name": "drupal/crop",
@@ -11944,16 +11944,16 @@
         },
         {
             "name": "symfony/http-kernel",
-            "version": "v3.4.41",
+            "version": "v3.4.44",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/http-kernel.git",
-                "reference": "e4e4ed6c008c983645b4eee6b67d8f258cde54df"
+                "reference": "27dcaa8c6b18c75df9f37badeb4d3564ffaa1326"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/http-kernel/zipball/e4e4ed6c008c983645b4eee6b67d8f258cde54df",
-                "reference": "e4e4ed6c008c983645b4eee6b67d8f258cde54df",
+                "url": "https://api.github.com/repos/symfony/http-kernel/zipball/27dcaa8c6b18c75df9f37badeb4d3564ffaa1326",
+                "reference": "27dcaa8c6b18c75df9f37badeb4d3564ffaa1326",
                 "shasum": ""
             },
             "require": {
@@ -12030,7 +12030,7 @@
             ],
             "description": "Symfony HttpKernel Component",
             "homepage": "https://symfony.com",
-            "time": "2020-05-31T05:14:17+00:00"
+            "time": "2020-08-31T05:53:42+00:00"
         },
         {
             "name": "symfony/polyfill-ctype",
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
index e7e8a031b5..504d93180f 100644
--- a/vendor/composer/installed.json
+++ b/vendor/composer/installed.json
@@ -3484,17 +3484,17 @@
     },
     {
         "name": "drupal/core",
-        "version": "8.9.3",
-        "version_normalized": "8.9.3.0",
+        "version": "8.9.6",
+        "version_normalized": "8.9.6.0",
         "source": {
             "type": "git",
             "url": "https://github.com/drupal/core.git",
-            "reference": "ee02fd4cbe4ac148b4d7e297ec63b3459983862e"
+            "reference": "caf4e756d31dfb0c2e52cd0748e900efe4b57766"
         },
         "dist": {
             "type": "zip",
-            "url": "https://api.github.com/repos/drupal/core/zipball/ee02fd4cbe4ac148b4d7e297ec63b3459983862e",
-            "reference": "ee02fd4cbe4ac148b4d7e297ec63b3459983862e",
+            "url": "https://api.github.com/repos/drupal/core/zipball/caf4e756d31dfb0c2e52cd0748e900efe4b57766",
+            "reference": "caf4e756d31dfb0c2e52cd0748e900efe4b57766",
             "shasum": ""
         },
         "require": {
@@ -3661,7 +3661,7 @@
             "drupal/workflows": "self.version",
             "drupal/workspaces": "self.version"
         },
-        "time": "2020-08-05T21:49:40+00:00",
+        "time": "2020-09-16T11:22:21+00:00",
         "type": "drupal-core",
         "extra": {
             "drupal-scaffold": {
@@ -3722,17 +3722,17 @@
     },
     {
         "name": "drupal/core-recommended",
-        "version": "8.9.3",
-        "version_normalized": "8.9.3.0",
+        "version": "8.9.6",
+        "version_normalized": "8.9.6.0",
         "source": {
             "type": "git",
             "url": "https://github.com/drupal/core-recommended.git",
-            "reference": "db5c2fdd4bf3e72aee8c862eca72dd445e704d71"
+            "reference": "6c5c4739afc5549e6089ef34b59c712c8872f154"
         },
         "dist": {
             "type": "zip",
-            "url": "https://api.github.com/repos/drupal/core-recommended/zipball/db5c2fdd4bf3e72aee8c862eca72dd445e704d71",
-            "reference": "db5c2fdd4bf3e72aee8c862eca72dd445e704d71",
+            "url": "https://api.github.com/repos/drupal/core-recommended/zipball/6c5c4739afc5549e6089ef34b59c712c8872f154",
+            "reference": "6c5c4739afc5549e6089ef34b59c712c8872f154",
             "shasum": ""
         },
         "require": {
@@ -3744,7 +3744,7 @@
             "doctrine/common": "v2.7.3",
             "doctrine/inflector": "v1.2.0",
             "doctrine/lexer": "1.0.2",
-            "drupal/core": "8.9.3",
+            "drupal/core": "8.9.6",
             "easyrdf/easyrdf": "0.9.1",
             "egulias/email-validator": "2.1.17",
             "guzzlehttp/guzzle": "6.5.4",
@@ -3773,7 +3773,7 @@
             "symfony/dependency-injection": "v3.4.41",
             "symfony/event-dispatcher": "v3.4.41",
             "symfony/http-foundation": "v3.4.41",
-            "symfony/http-kernel": "v3.4.41",
+            "symfony/http-kernel": "v3.4.44",
             "symfony/polyfill-ctype": "v1.17.0",
             "symfony/polyfill-iconv": "v1.17.0",
             "symfony/polyfill-intl-idn": "v1.17.0",
@@ -3795,7 +3795,7 @@
         "conflict": {
             "webflo/drupal-core-strict": "*"
         },
-        "time": "2020-08-05T21:49:40+00:00",
+        "time": "2020-09-16T11:22:21+00:00",
         "type": "metapackage",
         "notification-url": "https://packagist.org/downloads/",
         "license": [
@@ -12335,17 +12335,17 @@
     },
     {
         "name": "symfony/http-kernel",
-        "version": "v3.4.41",
-        "version_normalized": "3.4.41.0",
+        "version": "v3.4.44",
+        "version_normalized": "3.4.44.0",
         "source": {
             "type": "git",
             "url": "https://github.com/symfony/http-kernel.git",
-            "reference": "e4e4ed6c008c983645b4eee6b67d8f258cde54df"
+            "reference": "27dcaa8c6b18c75df9f37badeb4d3564ffaa1326"
         },
         "dist": {
             "type": "zip",
-            "url": "https://api.github.com/repos/symfony/http-kernel/zipball/e4e4ed6c008c983645b4eee6b67d8f258cde54df",
-            "reference": "e4e4ed6c008c983645b4eee6b67d8f258cde54df",
+            "url": "https://api.github.com/repos/symfony/http-kernel/zipball/27dcaa8c6b18c75df9f37badeb4d3564ffaa1326",
+            "reference": "27dcaa8c6b18c75df9f37badeb4d3564ffaa1326",
             "shasum": ""
         },
         "require": {
@@ -12392,7 +12392,7 @@
             "symfony/finder": "",
             "symfony/var-dumper": ""
         },
-        "time": "2020-05-31T05:14:17+00:00",
+        "time": "2020-08-31T05:53:42+00:00",
         "type": "library",
         "extra": {
             "branch-alias": {
diff --git a/vendor/symfony/http-kernel/Controller/ControllerResolver.php b/vendor/symfony/http-kernel/Controller/ControllerResolver.php
index 015448b510..8ed79ff7b2 100644
--- a/vendor/symfony/http-kernel/Controller/ControllerResolver.php
+++ b/vendor/symfony/http-kernel/Controller/ControllerResolver.php
@@ -274,7 +274,7 @@ private function typeMatchesRequestClass(\ReflectionParameter $param, Request $r
             return false;
         }
 
-        $class = new \ReflectionClass(method_exists($type, 'getName') ? $type->getName() : (string) $type);
+        $class = new \ReflectionClass($type instanceof \ReflectionNamedType ? $type->getName() : (string) $type);
 
         return $class && $class->isInstance($request);
     }
diff --git a/vendor/symfony/http-kernel/ControllerMetadata/ArgumentMetadataFactory.php b/vendor/symfony/http-kernel/ControllerMetadata/ArgumentMetadataFactory.php
index 2548a2a083..14e7ca3d11 100644
--- a/vendor/symfony/http-kernel/ControllerMetadata/ArgumentMetadataFactory.php
+++ b/vendor/symfony/http-kernel/ControllerMetadata/ArgumentMetadataFactory.php
@@ -105,7 +105,7 @@ private function getType(\ReflectionParameter $parameter, \ReflectionFunctionAbs
             if (!$type = $parameter->getType()) {
                 return null;
             }
-            $name = $type instanceof \ReflectionNamedType ? $type->getName() : $type->__toString();
+            $name = $type instanceof \ReflectionNamedType ? $type->getName() : (string) $type;
             if ('array' === $name && !$type->isBuiltin()) {
                 // Special case for HHVM with variadics
                 return null;
diff --git a/vendor/symfony/http-kernel/DataCollector/ConfigDataCollector.php b/vendor/symfony/http-kernel/DataCollector/ConfigDataCollector.php
index 673bf5c5fd..5895ef37d7 100644
--- a/vendor/symfony/http-kernel/DataCollector/ConfigDataCollector.php
+++ b/vendor/symfony/http-kernel/DataCollector/ConfigDataCollector.php
@@ -64,7 +64,7 @@ public function collect(Request $request, Response $response, \Exception $except
             'env' => isset($this->kernel) ? $this->kernel->getEnvironment() : 'n/a',
             'debug' => isset($this->kernel) ? $this->kernel->isDebug() : 'n/a',
             'php_version' => PHP_VERSION,
-            'php_architecture' => PHP_INT_SIZE * 8,
+            'php_architecture' => \PHP_INT_SIZE * 8,
             'php_intl_locale' => class_exists('Locale', false) && \Locale::getDefault() ? \Locale::getDefault() : 'n/a',
             'php_timezone' => date_default_timezone_get(),
             'xdebug_enabled' => \extension_loaded('xdebug'),
diff --git a/vendor/symfony/http-kernel/DependencyInjection/AddAnnotatedClassesToCachePass.php b/vendor/symfony/http-kernel/DependencyInjection/AddAnnotatedClassesToCachePass.php
index 8bb03bd0c7..b59949379d 100644
--- a/vendor/symfony/http-kernel/DependencyInjection/AddAnnotatedClassesToCachePass.php
+++ b/vendor/symfony/http-kernel/DependencyInjection/AddAnnotatedClassesToCachePass.php
@@ -136,10 +136,10 @@ private function patternsToRegexps($patterns)
 
     private function matchAnyRegexps($class, $regexps)
     {
-        $blacklisted = false !== strpos($class, 'Test');
+        $isTest = false !== strpos($class, 'Test');
 
         foreach ($regexps as $regex) {
-            if ($blacklisted && false === strpos($regex, 'Test')) {
+            if ($isTest && false === strpos($regex, 'Test')) {
                 continue;
             }
 
diff --git a/vendor/symfony/http-kernel/HttpCache/Store.php b/vendor/symfony/http-kernel/HttpCache/Store.php
index fd04a7b23d..72793f582d 100644
--- a/vendor/symfony/http-kernel/HttpCache/Store.php
+++ b/vendor/symfony/http-kernel/HttpCache/Store.php
@@ -152,8 +152,8 @@ public function lookup(Request $request)
         }
 
         $headers = $match[1];
-        if (file_exists($body = $this->getPath($headers['x-content-digest'][0]))) {
-            return $this->restoreResponse($headers, $body);
+        if (file_exists($path = $this->getPath($headers['x-content-digest'][0]))) {
+            return $this->restoreResponse($headers, $path);
         }
 
         // TODO the metaStore referenced an entity that doesn't exist in
@@ -177,15 +177,28 @@ public function write(Request $request, Response $response)
         $key = $this->getCacheKey($request);
         $storedEnv = $this->persistRequest($request);
 
-        $digest = $this->generateContentDigest($response);
-        $response->headers->set('X-Content-Digest', $digest);
+        if ($response->headers->has('X-Body-File')) {
+            // Assume the response came from disk, but at least perform some safeguard checks
+            if (!$response->headers->has('X-Content-Digest')) {
+                throw new \RuntimeException('A restored response must have the X-Content-Digest header.');
+            }
 
-        if (!$this->save($digest, $response->getContent(), false)) {
-            throw new \RuntimeException('Unable to store the entity.');
-        }
+            $digest = $response->headers->get('X-Content-Digest');
+            if ($this->getPath($digest) !== $response->headers->get('X-Body-File')) {
+                throw new \RuntimeException('X-Body-File and X-Content-Digest do not match.');
+            }
+            // Everything seems ok, omit writing content to disk
+        } else {
+            $digest = $this->generateContentDigest($response);
+            $response->headers->set('X-Content-Digest', $digest);
 
-        if (!$response->headers->has('Transfer-Encoding')) {
-            $response->headers->set('Content-Length', \strlen($response->getContent()));
+            if (!$this->save($digest, $response->getContent(), false)) {
+                throw new \RuntimeException('Unable to store the entity.');
+            }
+
+            if (!$response->headers->has('Transfer-Encoding')) {
+                $response->headers->set('Content-Length', \strlen($response->getContent()));
+            }
         }
 
         // read existing cache entries, remove non-varying, and add this one to the list
@@ -477,19 +490,19 @@ private function persistResponse(Response $response)
      * Restores a Response from the HTTP headers and body.
      *
      * @param array  $headers An array of HTTP headers for the Response
-     * @param string $body    The Response body
+     * @param string $path    Path to the Response body
      *
      * @return Response
      */
-    private function restoreResponse($headers, $body = null)
+    private function restoreResponse($headers, $path = null)
     {
         $status = $headers['X-Status'][0];
         unset($headers['X-Status']);
 
-        if (null !== $body) {
-            $headers['X-Body-File'] = [$body];
+        if (null !== $path) {
+            $headers['X-Body-File'] = [$path];
         }
 
-        return new Response($body, $status, $headers);
+        return new Response($path, $status, $headers);
     }
 }
diff --git a/vendor/symfony/http-kernel/Kernel.php b/vendor/symfony/http-kernel/Kernel.php
index 00382a95c1..e0aa029eb6 100644
--- a/vendor/symfony/http-kernel/Kernel.php
+++ b/vendor/symfony/http-kernel/Kernel.php
@@ -67,11 +67,11 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
     private $requestStackSize = 0;
     private $resetServices = false;
 
-    const VERSION = '3.4.41';
-    const VERSION_ID = 30441;
+    const VERSION = '3.4.44';
+    const VERSION_ID = 30444;
     const MAJOR_VERSION = 3;
     const MINOR_VERSION = 4;
-    const RELEASE_VERSION = 41;
+    const RELEASE_VERSION = 44;
     const EXTRA_VERSION = '';
 
     const END_OF_MAINTENANCE = '11/2020';
diff --git a/vendor/symfony/http-kernel/Tests/Controller/ContainerControllerResolverTest.php b/vendor/symfony/http-kernel/Tests/Controller/ContainerControllerResolverTest.php
index 4c4abf5aa4..8275154657 100644
--- a/vendor/symfony/http-kernel/Tests/Controller/ContainerControllerResolverTest.php
+++ b/vendor/symfony/http-kernel/Tests/Controller/ContainerControllerResolverTest.php
@@ -15,6 +15,7 @@
 use Psr\Log\LoggerInterface;
 use Symfony\Component\Debug\ErrorHandler;
 use Symfony\Component\DependencyInjection\Container;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpKernel\Controller\ContainerControllerResolver;
 
@@ -117,16 +118,10 @@ public function testNonConstructController()
         $this->expectException('LogicException');
         $this->expectExceptionMessage('Controller "Symfony\Component\HttpKernel\Tests\Controller\ImpossibleConstructController" cannot be fetched from the container because it is private. Did you forget to tag the service with "controller.service_arguments"?');
         $container = $this->getMockBuilder(Container::class)->getMock();
-        $container->expects($this->at(0))
+        $container->expects($this->exactly(2))
             ->method('has')
             ->with(ImpossibleConstructController::class)
-            ->willReturn(true)
-        ;
-
-        $container->expects($this->at(1))
-            ->method('has')
-            ->with(ImpossibleConstructController::class)
-            ->willReturn(false)
+            ->willReturnOnConsecutiveCalls(true, false)
         ;
 
         $container->expects($this->atLeastOnce())
@@ -181,18 +176,10 @@ public function testExceptionWhenUsingRemovedControllerService()
     {
         $this->expectException('LogicException');
         $this->expectExceptionMessage('Controller "app.my_controller" cannot be fetched from the container because it is private. Did you forget to tag the service with "controller.service_arguments"?');
-        $container = $this->getMockBuilder(Container::class)->getMock();
-        $container->expects($this->at(0))
-            ->method('has')
-            ->with('app.my_controller')
-            ->willReturn(false)
-        ;
 
-        $container->expects($this->atLeastOnce())
-            ->method('getRemovedIds')
-            ->with()
-            ->willReturn(['app.my_controller' => true])
-        ;
+        $container = new ContainerBuilder();
+        $container->register('app.my_controller');
+        $container->removeDefinition('app.my_controller');
 
         $resolver = $this->createControllerResolver(null, $container);
 
@@ -232,7 +219,7 @@ public function testGetControllerOnNonUndefinedFunction($controller, $exceptionN
         // All this logic needs to be duplicated, since calling parent::testGetControllerOnNonUndefinedFunction will override the expected exception and not use the regex
         $resolver = $this->createControllerResolver();
         $this->expectException($exceptionName);
-        $this->expectExceptionMessageRegExp($exceptionMessage);
+        $this->expectExceptionMessageMatches($exceptionMessage);
 
         $request = Request::create('/');
         $request->attributes->set('_controller', $controller);
diff --git a/vendor/symfony/http-kernel/Tests/DataCollector/ConfigDataCollectorTest.php b/vendor/symfony/http-kernel/Tests/DataCollector/ConfigDataCollectorTest.php
index a858eabe15..dc455915fa 100644
--- a/vendor/symfony/http-kernel/Tests/DataCollector/ConfigDataCollectorTest.php
+++ b/vendor/symfony/http-kernel/Tests/DataCollector/ConfigDataCollectorTest.php
@@ -31,9 +31,9 @@ public function testCollect()
         $this->assertTrue($c->isDebug());
         $this->assertSame('config', $c->getName());
         $this->assertSame('testkernel', $c->getAppName());
-        $this->assertRegExp('~^'.preg_quote($c->getPhpVersion(), '~').'~', PHP_VERSION);
-        $this->assertRegExp('~'.preg_quote((string) $c->getPhpVersionExtra(), '~').'$~', PHP_VERSION);
-        $this->assertSame(PHP_INT_SIZE * 8, $c->getPhpArchitecture());
+        $this->assertMatchesRegularExpression('~^'.preg_quote($c->getPhpVersion(), '~').'~', PHP_VERSION);
+        $this->assertMatchesRegularExpression('~'.preg_quote((string) $c->getPhpVersionExtra(), '~').'$~', PHP_VERSION);
+        $this->assertSame(\PHP_INT_SIZE * 8, $c->getPhpArchitecture());
         $this->assertSame(class_exists('Locale', false) && \Locale::getDefault() ? \Locale::getDefault() : 'n/a', $c->getPhpIntlLocale());
         $this->assertSame(date_default_timezone_get(), $c->getPhpTimezone());
         $this->assertSame(Kernel::VERSION, $c->getSymfonyVersion());
diff --git a/vendor/symfony/http-kernel/Tests/DataCollector/RequestDataCollectorTest.php b/vendor/symfony/http-kernel/Tests/DataCollector/RequestDataCollectorTest.php
index 38979bba72..9bf5bf968d 100644
--- a/vendor/symfony/http-kernel/Tests/DataCollector/RequestDataCollectorTest.php
+++ b/vendor/symfony/http-kernel/Tests/DataCollector/RequestDataCollectorTest.php
@@ -51,7 +51,7 @@ public function testCollect()
         $this->assertEquals(['name' => 'foo'], $c->getRouteParams());
         $this->assertSame([], $c->getSessionAttributes());
         $this->assertSame('en', $c->getLocale());
-        $this->assertContains(__FILE__, $attributes->get('resource'));
+        $this->assertContainsEquals(__FILE__, $attributes->get('resource'));
         $this->assertSame('stdClass', $attributes->get('object')->getType());
 
         $this->assertInstanceOf('Symfony\Component\HttpFoundation\ParameterBag', $c->getResponseHeaders());
diff --git a/vendor/symfony/http-kernel/Tests/Event/FilterControllerArgumentsEventTest.php b/vendor/symfony/http-kernel/Tests/Event/FilterControllerArgumentsEventTest.php
index abc51ac51e..53962347d0 100644
--- a/vendor/symfony/http-kernel/Tests/Event/FilterControllerArgumentsEventTest.php
+++ b/vendor/symfony/http-kernel/Tests/Event/FilterControllerArgumentsEventTest.php
@@ -12,6 +12,6 @@ class FilterControllerArgumentsEventTest extends TestCase
     public function testFilterControllerArgumentsEvent()
     {
         $filterController = new FilterControllerArgumentsEvent(new TestHttpKernel(), function () {}, ['test'], new Request(), 1);
-        $this->assertEquals($filterController->getArguments(), ['test']);
+        $this->assertEquals(['test'], $filterController->getArguments());
     }
 }
diff --git a/vendor/symfony/http-kernel/Tests/EventListener/TranslatorListenerTest.php b/vendor/symfony/http-kernel/Tests/EventListener/TranslatorListenerTest.php
index 77c2c1c694..79e0d6f1ac 100644
--- a/vendor/symfony/http-kernel/Tests/EventListener/TranslatorListenerTest.php
+++ b/vendor/symfony/http-kernel/Tests/EventListener/TranslatorListenerTest.php
@@ -45,13 +45,15 @@ public function testLocaleIsSetInOnKernelRequest()
     public function testDefaultLocaleIsUsedOnExceptionsInOnKernelRequest()
     {
         $this->translator
-            ->expects($this->at(0))
+            ->expects($this->exactly(2))
             ->method('setLocale')
-            ->willThrowException(new \InvalidArgumentException());
-        $this->translator
-            ->expects($this->at(1))
-            ->method('setLocale')
-            ->with($this->equalTo('en'));
+            ->withConsecutive(
+                ['fr'],
+                ['en']
+            )
+            ->willReturnOnConsecutiveCalls(
+                $this->throwException(new \InvalidArgumentException())
+            );
 
         $event = new GetResponseEvent($this->createHttpKernel(), $this->createRequest('fr'), HttpKernelInterface::MASTER_REQUEST);
         $this->listener->onKernelRequest($event);
@@ -82,13 +84,15 @@ public function testLocaleIsNotSetInOnKernelFinishRequestWhenParentRequestDoesNo
     public function testDefaultLocaleIsUsedOnExceptionsInOnKernelFinishRequest()
     {
         $this->translator
-            ->expects($this->at(0))
-            ->method('setLocale')
-            ->willThrowException(new \InvalidArgumentException());
-        $this->translator
-            ->expects($this->at(1))
+            ->expects($this->exactly(2))
             ->method('setLocale')
-            ->with($this->equalTo('en'));
+            ->withConsecutive(
+                ['fr'],
+                ['en']
+            )
+            ->willReturnOnConsecutiveCalls(
+                $this->throwException(new \InvalidArgumentException())
+            );
 
         $this->setMasterRequest($this->createRequest('fr'));
         $event = new FinishRequestEvent($this->createHttpKernel(), $this->createRequest('de'), HttpKernelInterface::SUB_REQUEST);
diff --git a/vendor/symfony/http-kernel/Tests/HttpCache/HttpCacheTest.php b/vendor/symfony/http-kernel/Tests/HttpCache/HttpCacheTest.php
index cac06a80e5..444db71a3e 100644
--- a/vendor/symfony/http-kernel/Tests/HttpCache/HttpCacheTest.php
+++ b/vendor/symfony/http-kernel/Tests/HttpCache/HttpCacheTest.php
@@ -654,7 +654,7 @@ public function testAssignsDefaultTtlWhenResponseHasNoFreshnessInformation()
         $this->assertTraceContains('miss');
         $this->assertTraceContains('store');
         $this->assertEquals('Hello World', $this->response->getContent());
-        $this->assertRegExp('/s-maxage=10/', $this->response->headers->get('Cache-Control'));
+        $this->assertMatchesRegularExpression('/s-maxage=10/', $this->response->headers->get('Cache-Control'));
 
         $this->cacheConfig['default_ttl'] = 10;
         $this->request('GET', '/');
@@ -663,7 +663,7 @@ public function testAssignsDefaultTtlWhenResponseHasNoFreshnessInformation()
         $this->assertTraceContains('fresh');
         $this->assertTraceNotContains('store');
         $this->assertEquals('Hello World', $this->response->getContent());
-        $this->assertRegExp('/s-maxage=10/', $this->response->headers->get('Cache-Control'));
+        $this->assertMatchesRegularExpression('/s-maxage=10/', $this->response->headers->get('Cache-Control'));
     }
 
     public function testAssignsDefaultTtlWhenResponseHasNoFreshnessInformationAndAfterTtlWasExpired()
@@ -676,7 +676,7 @@ public function testAssignsDefaultTtlWhenResponseHasNoFreshnessInformationAndAft
         $this->assertTraceContains('miss');
         $this->assertTraceContains('store');
         $this->assertEquals('Hello World', $this->response->getContent());
-        $this->assertRegExp('/s-maxage=(2|3)/', $this->response->headers->get('Cache-Control'));
+        $this->assertMatchesRegularExpression('/s-maxage=(2|3)/', $this->response->headers->get('Cache-Control'));
 
         $this->request('GET', '/');
         $this->assertHttpKernelIsNotCalled();
@@ -684,7 +684,7 @@ public function testAssignsDefaultTtlWhenResponseHasNoFreshnessInformationAndAft
         $this->assertTraceContains('fresh');
         $this->assertTraceNotContains('store');
         $this->assertEquals('Hello World', $this->response->getContent());
-        $this->assertRegExp('/s-maxage=(2|3)/', $this->response->headers->get('Cache-Control'));
+        $this->assertMatchesRegularExpression('/s-maxage=(2|3)/', $this->response->headers->get('Cache-Control'));
 
         // expires the cache
         $values = $this->getMetaStorageValues();
@@ -704,7 +704,7 @@ public function testAssignsDefaultTtlWhenResponseHasNoFreshnessInformationAndAft
         $this->assertTraceContains('invalid');
         $this->assertTraceContains('store');
         $this->assertEquals('Hello World', $this->response->getContent());
-        $this->assertRegExp('/s-maxage=(2|3)/', $this->response->headers->get('Cache-Control'));
+        $this->assertMatchesRegularExpression('/s-maxage=(2|3)/', $this->response->headers->get('Cache-Control'));
 
         $this->setNextResponse();
 
@@ -714,7 +714,7 @@ public function testAssignsDefaultTtlWhenResponseHasNoFreshnessInformationAndAft
         $this->assertTraceContains('fresh');
         $this->assertTraceNotContains('store');
         $this->assertEquals('Hello World', $this->response->getContent());
-        $this->assertRegExp('/s-maxage=(2|3)/', $this->response->headers->get('Cache-Control'));
+        $this->assertMatchesRegularExpression('/s-maxage=(2|3)/', $this->response->headers->get('Cache-Control'));
     }
 
     public function testAssignsDefaultTtlWhenResponseHasNoFreshnessInformationAndAfterTtlWasExpiredWithStatus304()
@@ -727,7 +727,7 @@ public function testAssignsDefaultTtlWhenResponseHasNoFreshnessInformationAndAft
         $this->assertTraceContains('miss');
         $this->assertTraceContains('store');
         $this->assertEquals('Hello World', $this->response->getContent());
-        $this->assertRegExp('/s-maxage=(2|3)/', $this->response->headers->get('Cache-Control'));
+        $this->assertMatchesRegularExpression('/s-maxage=(2|3)/', $this->response->headers->get('Cache-Control'));
 
         $this->request('GET', '/');
         $this->assertHttpKernelIsNotCalled();
@@ -755,7 +755,7 @@ public function testAssignsDefaultTtlWhenResponseHasNoFreshnessInformationAndAft
         $this->assertTraceContains('store');
         $this->assertTraceNotContains('miss');
         $this->assertEquals('Hello World', $this->response->getContent());
-        $this->assertRegExp('/s-maxage=(2|3)/', $this->response->headers->get('Cache-Control'));
+        $this->assertMatchesRegularExpression('/s-maxage=(2|3)/', $this->response->headers->get('Cache-Control'));
 
         $this->request('GET', '/');
         $this->assertHttpKernelIsNotCalled();
@@ -763,7 +763,7 @@ public function testAssignsDefaultTtlWhenResponseHasNoFreshnessInformationAndAft
         $this->assertTraceContains('fresh');
         $this->assertTraceNotContains('store');
         $this->assertEquals('Hello World', $this->response->getContent());
-        $this->assertRegExp('/s-maxage=(2|3)/', $this->response->headers->get('Cache-Control'));
+        $this->assertMatchesRegularExpression('/s-maxage=(2|3)/', $this->response->headers->get('Cache-Control'));
     }
 
     public function testDoesNotAssignDefaultTtlWhenResponseHasMustRevalidateDirective()
@@ -776,7 +776,7 @@ public function testDoesNotAssignDefaultTtlWhenResponseHasMustRevalidateDirectiv
         $this->assertEquals(200, $this->response->getStatusCode());
         $this->assertTraceContains('miss');
         $this->assertTraceNotContains('store');
-        $this->assertNotRegExp('/s-maxage/', $this->response->headers->get('Cache-Control'));
+        $this->assertDoesNotMatchRegularExpression('/s-maxage/', $this->response->headers->get('Cache-Control'));
         $this->assertEquals('Hello World', $this->response->getContent());
     }
 
diff --git a/vendor/symfony/http-kernel/Tests/HttpCache/HttpCacheTestCase.php b/vendor/symfony/http-kernel/Tests/HttpCache/HttpCacheTestCase.php
index 1eb4617447..3cbea5e4ee 100644
--- a/vendor/symfony/http-kernel/Tests/HttpCache/HttpCacheTestCase.php
+++ b/vendor/symfony/http-kernel/Tests/HttpCache/HttpCacheTestCase.php
@@ -91,7 +91,7 @@ public function assertTraceContains($trace)
         $traces = $this->cache->getTraces();
         $traces = current($traces);
 
-        $this->assertRegExp('/'.$trace.'/', implode(', ', $traces));
+        $this->assertMatchesRegularExpression('/'.$trace.'/', implode(', ', $traces));
     }
 
     public function assertTraceNotContains($trace)
@@ -99,7 +99,7 @@ public function assertTraceNotContains($trace)
         $traces = $this->cache->getTraces();
         $traces = current($traces);
 
-        $this->assertNotRegExp('/'.$trace.'/', implode(', ', $traces));
+        $this->assertDoesNotMatchRegularExpression('/'.$trace.'/', implode(', ', $traces));
     }
 
     public function assertExceptionsAreCaught()
diff --git a/vendor/symfony/http-kernel/Tests/HttpCache/StoreTest.php b/vendor/symfony/http-kernel/Tests/HttpCache/StoreTest.php
index 07c4154269..eee8970b96 100644
--- a/vendor/symfony/http-kernel/Tests/HttpCache/StoreTest.php
+++ b/vendor/symfony/http-kernel/Tests/HttpCache/StoreTest.php
@@ -118,6 +118,39 @@ public function testWritesResponseEvenIfXContentDigestIsPresent()
         $this->assertNotNull($response);
     }
 
+    public function testWritingARestoredResponseDoesNotCorruptCache()
+    {
+        /*
+         * This covers the regression reported in https://github.com/symfony/symfony/issues/37174.
+         *
+         * A restored response does *not* load the body, but only keep the file path in a special X-Body-File
+         * header. For reasons (?), the file path was also used as the restored response body.
+         * It would be up to others (HttpCache...?) to honor this header and actually load the response content
+         * from there.
+         *
+         * When a restored response was stored again, the Store itself would ignore the header. In the first
+         * step, this would compute a new Content Digest based on the file path in the restored response body;
+         * this is covered by "Checkpoint 1" below. But, since the X-Body-File header was left untouched (Checkpoint 2), downstream
+         * code (HttpCache...) would not immediately notice.
+         *
+         * Only upon performing the lookup for a second time, we'd get a Response where the (wrong) Content Digest
+         * is also reflected in the X-Body-File header, this time also producing wrong content when the downstream
+         * evaluates it.
+         */
+        $this->store->write($this->request, $this->response);
+        $digest = $this->response->headers->get('X-Content-Digest');
+        $path = $this->getStorePath($digest);
+
+        $response = $this->store->lookup($this->request);
+        $this->store->write($this->request, $response);
+        $this->assertEquals($digest, $response->headers->get('X-Content-Digest')); // Checkpoint 1
+        $this->assertEquals($path, $response->headers->get('X-Body-File')); // Checkpoint 2
+
+        $response = $this->store->lookup($this->request);
+        $this->assertEquals($digest, $response->headers->get('X-Content-Digest'));
+        $this->assertEquals($path, $response->headers->get('X-Body-File'));
+    }
+
     public function testFindsAStoredEntryWithLookup()
     {
         $this->storeSimpleEntry();
diff --git a/vendor/symfony/http-kernel/Tests/HttpKernelTest.php b/vendor/symfony/http-kernel/Tests/HttpKernelTest.php
index af81f021ed..97c58305db 100644
--- a/vendor/symfony/http-kernel/Tests/HttpKernelTest.php
+++ b/vendor/symfony/http-kernel/Tests/HttpKernelTest.php
@@ -314,8 +314,8 @@ public function testVerifyRequestStackPushPopDuringHandle()
         $request = new Request();
 
         $stack = $this->getMockBuilder('Symfony\Component\HttpFoundation\RequestStack')->setMethods(['push', 'pop'])->getMock();
-        $stack->expects($this->at(0))->method('push')->with($this->equalTo($request));
-        $stack->expects($this->at(1))->method('pop');
+        $stack->expects($this->once())->method('push')->with($this->equalTo($request));
+        $stack->expects($this->once())->method('pop');
 
         $dispatcher = new EventDispatcher();
         $kernel = $this->getHttpKernel($dispatcher, null, $stack);
diff --git a/vendor/symfony/http-kernel/Tests/KernelTest.php b/vendor/symfony/http-kernel/Tests/KernelTest.php
index e4e2e0727b..fd840bbb7b 100644
--- a/vendor/symfony/http-kernel/Tests/KernelTest.php
+++ b/vendor/symfony/http-kernel/Tests/KernelTest.php
@@ -15,6 +15,7 @@
 use Symfony\Component\Config\Loader\LoaderInterface;
 use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
 use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\Filesystem\Filesystem;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\Response;
@@ -78,7 +79,7 @@ public function testInitializeContainerClearsOldContainers()
         $containerDir = __DIR__.'/Fixtures/cache/custom/'.substr(\get_class($kernel->getContainer()), 0, 16);
         $this->assertTrue(unlink(__DIR__.'/Fixtures/cache/custom/FixturesCustomDebugProjectContainer.php.meta'));
         $this->assertFileExists($containerDir);
-        $this->assertFileNotExists($containerDir.'.legacy');
+        $this->assertFileDoesNotExist($containerDir.'.legacy');
 
         $kernel = new CustomProjectDirKernel(function ($container) { $container->register('foo', 'stdClass')->setPublic(true); });
         $kernel->boot();
@@ -86,8 +87,8 @@ public function testInitializeContainerClearsOldContainers()
         $this->assertFileExists($containerDir);
         $this->assertFileExists($containerDir.'.legacy');
 
-        $this->assertFileNotExists($legacyContainerDir);
-        $this->assertFileNotExists($legacyContainerDir.'.legacy');
+        $this->assertFileDoesNotExist($legacyContainerDir);
+        $this->assertFileDoesNotExist($legacyContainerDir.'.legacy');
     }
 
     public function testBootInitializesBundlesAndContainer()
@@ -219,9 +220,12 @@ public function testShutdownCallsShutdownOnAllBundles()
     public function testShutdownGivesNullContainerToAllBundles()
     {
         $bundle = $this->getMockBuilder('Symfony\Component\HttpKernel\Bundle\Bundle')->getMock();
-        $bundle->expects($this->at(3))
+        $bundle->expects($this->exactly(2))
             ->method('setContainer')
-            ->with(null);
+            ->withConsecutive(
+                [$this->isInstanceOf(ContainerInterface::class)],
+                [null]
+            );
 
         $kernel = $this->getKernel(['getBundles']);
         $kernel->expects($this->any())
diff --git a/vendor/symfony/http-kernel/Tests/Profiler/FileProfilerStorageTest.php b/vendor/symfony/http-kernel/Tests/Profiler/FileProfilerStorageTest.php
index 1cc05e41ec..4e23f13b02 100644
--- a/vendor/symfony/http-kernel/Tests/Profiler/FileProfilerStorageTest.php
+++ b/vendor/symfony/http-kernel/Tests/Profiler/FileProfilerStorageTest.php
@@ -205,9 +205,9 @@ public function testStoreTime()
 
         $records = $this->storage->find('', '', 3, 'GET', $start, time() + 3 * 60);
         $this->assertCount(3, $records, '->find() returns all previously added records');
-        $this->assertEquals($records[0]['token'], 'time_2', '->find() returns records ordered by time in descendant order');
-        $this->assertEquals($records[1]['token'], 'time_1', '->find() returns records ordered by time in descendant order');
-        $this->assertEquals($records[2]['token'], 'time_0', '->find() returns records ordered by time in descendant order');
+        $this->assertEquals('time_2', $records[0]['token'], '->find() returns records ordered by time in descendant order');
+        $this->assertEquals('time_1', $records[1]['token'], '->find() returns records ordered by time in descendant order');
+        $this->assertEquals('time_0', $records[2]['token'], '->find() returns records ordered by time in descendant order');
 
         $records = $this->storage->find('', '', 3, 'GET', $start, time() + 2 * 60);
         $this->assertCount(2, $records, '->find() should return only first two of the previously added records');
@@ -293,8 +293,8 @@ public function testStatusCode()
 
         $tokens = $this->storage->find('', '', 10, '');
         $this->assertCount(2, $tokens);
-        $this->assertContains($tokens[0]['status_code'], [200, 404]);
-        $this->assertContains($tokens[1]['status_code'], [200, 404]);
+        $this->assertContains((int) $tokens[0]['status_code'], [200, 404]);
+        $this->assertContains((int) $tokens[1]['status_code'], [200, 404]);
     }
 
     public function testMultiRowIndexFile()
diff --git a/web/core/lib/Drupal.php b/web/core/lib/Drupal.php
index 28863da052..2d5754aa94 100644
--- a/web/core/lib/Drupal.php
+++ b/web/core/lib/Drupal.php
@@ -82,7 +82,7 @@ class Drupal {
   /**
    * The current system version.
    */
-  const VERSION = '8.9.3';
+  const VERSION = '8.9.6';
 
   /**
    * Core API compatibility.
diff --git a/web/core/lib/Drupal/Component/Utility/Image.php b/web/core/lib/Drupal/Component/Utility/Image.php
index fcfedb1a26..f1368c1b83 100644
--- a/web/core/lib/Drupal/Component/Utility/Image.php
+++ b/web/core/lib/Drupal/Component/Utility/Image.php
@@ -30,8 +30,6 @@ class Image {
    *
    * @return bool
    *   TRUE if $dimensions was modified, FALSE otherwise.
-   *
-   * @see image_scale()
    */
   public static function scaleDimensions(array &$dimensions, $width = NULL, $height = NULL, $upscale = FALSE) {
     $aspect = $dimensions['height'] / $dimensions['width'];
diff --git a/web/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php b/web/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
index 99328413da..d2cf20a22a 100644
--- a/web/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
+++ b/web/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
@@ -345,7 +345,7 @@ protected function parseLibraryInfo($extension, $path) {
     $library_file = $path . '/' . $extension . '.libraries.yml';
     if (file_exists($this->root . '/' . $library_file)) {
       try {
-        $libraries = Yaml::decode(file_get_contents($this->root . '/' . $library_file));
+        $libraries = Yaml::decode(file_get_contents($this->root . '/' . $library_file)) ?? [];
       }
       catch (InvalidDataTypeException $e) {
         // Rethrow a more helpful exception to provide context.
diff --git a/web/core/lib/Drupal/Core/DependencyInjection/DeprecatedServicePropertyTrait.php b/web/core/lib/Drupal/Core/DependencyInjection/DeprecatedServicePropertyTrait.php
index b0681ec0b8..55c6bd63a5 100644
--- a/web/core/lib/Drupal/Core/DependencyInjection/DeprecatedServicePropertyTrait.php
+++ b/web/core/lib/Drupal/Core/DependencyInjection/DeprecatedServicePropertyTrait.php
@@ -8,7 +8,7 @@
 trait DeprecatedServicePropertyTrait {
 
   /**
-   * Alows to access deprecated/removed properties.
+   * Allows to access deprecated/removed properties.
    *
    * This method must be public.
    */
diff --git a/web/core/lib/Drupal/Core/EventSubscriber/ExceptionLoggingSubscriber.php b/web/core/lib/Drupal/Core/EventSubscriber/ExceptionLoggingSubscriber.php
index 7a39969bab..998213ea31 100644
--- a/web/core/lib/Drupal/Core/EventSubscriber/ExceptionLoggingSubscriber.php
+++ b/web/core/lib/Drupal/Core/EventSubscriber/ExceptionLoggingSubscriber.php
@@ -42,6 +42,7 @@ public function on403(GetResponseForExceptionEvent $event) {
     // why access was denied.
     $exception = $event->getException();
     $error = Error::decodeException($exception);
+    unset($error['@backtrace_string']);
     $error['@uri'] = $event->getRequest()->getRequestUri();
     $this->logger->get('access denied')->warning('Path: @uri. %type: @message in %function (line %line of %file).', $error);
   }
diff --git a/web/core/lib/Drupal/Core/Form/FormBuilder.php b/web/core/lib/Drupal/Core/Form/FormBuilder.php
index 5e8e22a604..4447534658 100644
--- a/web/core/lib/Drupal/Core/Form/FormBuilder.php
+++ b/web/core/lib/Drupal/Core/Form/FormBuilder.php
@@ -861,7 +861,8 @@ protected function buildFormAction() {
     //   https://www.drupal.org/node/2504709.
     $parsed = UrlHelper::parse($request_uri);
     unset($parsed['query'][static::AJAX_FORM_REQUEST], $parsed['query'][MainContentViewSubscriber::WRAPPER_FORMAT]);
-    return $parsed['path'] . ($parsed['query'] ? ('?' . UrlHelper::buildQuery($parsed['query'])) : '');
+    $action =  $parsed['path'] . ($parsed['query'] ? ('?' . UrlHelper::buildQuery($parsed['query'])) : '');
+    return UrlHelper::filterBadProtocol($action);
   }
 
   /**
diff --git a/web/core/lib/Drupal/Core/Logger/RfcLogLevel.php b/web/core/lib/Drupal/Core/Logger/RfcLogLevel.php
index cff99fa533..76a83ca469 100644
--- a/web/core/lib/Drupal/Core/Logger/RfcLogLevel.php
+++ b/web/core/lib/Drupal/Core/Logger/RfcLogLevel.php
@@ -10,13 +10,13 @@
  * Logging severity levels as defined in RFC 5424.
  *
  * The constant definitions of this class correspond to the logging severity
- * levels defined in RFC 5424, section 4.1.1. PHP supplies predefined LOG_*
+ * levels defined in RFC 5424, section 6.2.1. PHP supplies predefined LOG_*
  * constants for use in the syslog() function, but their values on Windows
  * builds do not correspond to RFC 5424. The associated PHP bug report was
  * closed with the comment, "And it's also not a bug, as Windows just have less
  * log levels," and "So the behavior you're seeing is perfectly normal."
  *
- * @see http://tools.ietf.org/html/rfc5424
+ * @see https://tools.ietf.org/html/rfc5424#section-6.2.1
  * @see http://bugs.php.net/bug.php?id=18090
  * @see http://php.net/manual/function.syslog.php
  * @see http://php.net/manual/network.constants.php
diff --git a/web/core/lib/Drupal/Core/Render/Element/Email.php b/web/core/lib/Drupal/Core/Render/Element/Email.php
index 84bb35265c..908d71ea6a 100644
--- a/web/core/lib/Drupal/Core/Render/Element/Email.php
+++ b/web/core/lib/Drupal/Core/Render/Element/Email.php
@@ -15,14 +15,14 @@
  *
  * Example usage:
  * @code
- * $form['email'] = array(
+ * $form['email'] = [
  *   '#type' => 'email',
  *   '#title' => $this->t('Email'),
  *   '#pattern' => '*@example.com',
- * );
- * @end
+ * ];
+ * @endcode
  *
- * @see \Drupal\Core\Render\Element\Render\Textfield
+ * @see \Drupal\Core\Render\Element\Textfield
  *
  * @FormElement("email")
  */
diff --git a/web/core/misc/ajax.es6.js b/web/core/misc/ajax.es6.js
index 6eeddf3df7..119642dba7 100644
--- a/web/core/misc/ajax.es6.js
+++ b/web/core/misc/ajax.es6.js
@@ -559,6 +559,7 @@
         }
       },
       dataType: 'json',
+      jsonp: false,
       type: 'POST',
     };
 
diff --git a/web/core/misc/ajax.js b/web/core/misc/ajax.js
index cc3936ca6a..b817b77b05 100644
--- a/web/core/misc/ajax.js
+++ b/web/core/misc/ajax.js
@@ -243,6 +243,7 @@ function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr
       },
 
       dataType: 'json',
+      jsonp: false,
       type: 'POST'
     };
 
diff --git a/web/core/misc/autocomplete.es6.js b/web/core/misc/autocomplete.es6.js
index 65f6332af6..1b5d879146 100644
--- a/web/core/misc/autocomplete.es6.js
+++ b/web/core/misc/autocomplete.es6.js
@@ -281,6 +281,7 @@
     },
     ajax: {
       dataType: 'json',
+      jsonp: false,
     },
   };
 
diff --git a/web/core/misc/autocomplete.js b/web/core/misc/autocomplete.js
index 52ddfd2ab4..fc90d77558 100644
--- a/web/core/misc/autocomplete.js
+++ b/web/core/misc/autocomplete.js
@@ -156,7 +156,8 @@
       isComposing: false
     },
     ajax: {
-      dataType: 'json'
+      dataType: 'json',
+      jsonp: false
     }
   };
 
diff --git a/web/core/modules/ban/tests/src/Functional/IpAddressBlockingTest.php b/web/core/modules/ban/tests/src/Functional/IpAddressBlockingTest.php
index 0df08b0f74..1b4ecd84b7 100644
--- a/web/core/modules/ban/tests/src/Functional/IpAddressBlockingTest.php
+++ b/web/core/modules/ban/tests/src/Functional/IpAddressBlockingTest.php
@@ -39,7 +39,7 @@ public function testIPAddressValidation() {
     $edit = [];
     $edit['ip'] = '1.2.3.3';
     $this->drupalPostForm('admin/config/people/ban', $edit, t('Add'));
-    $ip = $connection->query("SELECT iid from {ban_ip} WHERE ip = :ip", [':ip' => $edit['ip']])->fetchField();
+    $ip = $connection->select('ban_ip', 'bi')->fields('bi', ['iid'])->condition('ip', $edit['ip'])->execute()->fetchField();
     $this->assertNotEmpty($ip, 'IP address found in database.');
     $this->assertRaw(t('The IP address %ip has been banned.', ['%ip' => $edit['ip']]), 'IP address was banned.');
 
@@ -70,7 +70,7 @@ public function testIPAddressValidation() {
     // Pass an IP address as a URL parameter and submit it.
     $submit_ip = '1.2.3.4';
     $this->drupalPostForm('admin/config/people/ban/' . $submit_ip, [], t('Add'));
-    $ip = $connection->query("SELECT iid from {ban_ip} WHERE ip = :ip", [':ip' => $submit_ip])->fetchField();
+    $ip = $connection->select('ban_ip', 'bi')->fields('bi', ['iid'])->condition('ip', $submit_ip)->execute()->fetchField();
     $this->assertNotEmpty($ip, 'IP address found in database');
     $this->assertRaw(t('The IP address %ip has been banned.', ['%ip' => $submit_ip]), 'IP address was banned.');
 
diff --git a/web/core/modules/big_pipe/tests/src/Functional/BigPipeTest.php b/web/core/modules/big_pipe/tests/src/Functional/BigPipeTest.php
index d5bb0bcf04..5d6775c0ec 100644
--- a/web/core/modules/big_pipe/tests/src/Functional/BigPipeTest.php
+++ b/web/core/modules/big_pipe/tests/src/Functional/BigPipeTest.php
@@ -153,7 +153,7 @@ public function testBigPipe() {
     $this->assertBigPipeNoJsCookieExists(FALSE);
 
     $connection = Database::getConnection();
-    $log_count = $connection->query('SELECT COUNT(*) FROM {watchdog}')->fetchField();
+    $log_count = $connection->select('watchdog')->countQuery()->execute()->fetchField();
 
     // By not calling performMetaRefresh() here, we simulate JavaScript being
     // enabled, because as far as the BigPipe module is concerned, JavaScript is
@@ -191,10 +191,11 @@ public function testBigPipe() {
     $this->assertContains('big_pipe/big_pipe', explode(',', $this->getDrupalSettings()['ajaxPageState']['libraries']), 'BigPipe asset library is present.');
 
     // Verify that the two expected exceptions are logged as errors.
-    $this->assertEqual($log_count + 2, $connection->query('SELECT COUNT(*) FROM {watchdog}')->fetchField(), 'Two new watchdog entries.');
-    // Using the method queryRange() allows contrib database drivers the ability
-    // to insert their own limit and offset functionality.
-    $records = $connection->queryRange('SELECT * FROM {watchdog} ORDER BY wid DESC', 0, 2)->fetchAll();
+    $this->assertEqual($log_count + 2, (int) $connection->select('watchdog')->countQuery()->execute()->fetchField(), 'Two new watchdog entries.');
+    // Using dynamic select queries with the method range() allows contrib
+    // database drivers the ability to insert their own limit and offset
+    // functionality.
+    $records = $connection->select('watchdog', 'w')->fields('w')->orderBy('wid', 'DESC')->range(0, 2)->execute()->fetchAll();
     $this->assertEqual(RfcLogLevel::ERROR, $records[0]->severity);
     $this->assertStringContainsString('Oh noes!', (string) unserialize($records[0]->variables)['@message']);
     $this->assertEqual(RfcLogLevel::ERROR, $records[1]->severity);
diff --git a/web/core/modules/ckeditor/js/plugins/drupalimagecaption/plugin.es6.js b/web/core/modules/ckeditor/js/plugins/drupalimagecaption/plugin.es6.js
index 1e63c4b782..f90a77088d 100644
--- a/web/core/modules/ckeditor/js/plugins/drupalimagecaption/plugin.es6.js
+++ b/web/core/modules/ckeditor/js/plugins/drupalimagecaption/plugin.es6.js
@@ -215,6 +215,9 @@
                   'figcaption',
                 );
 
+                const captionFilter = new CKEDITOR.filter(widgetDefinition.editables.caption.allowedContent);
+                captionFilter.applyTo(caption);
+
                 // Use Drupal's data-placeholder attribute to insert a CSS-based,
                 // translation-ready placeholder for empty captions. Note that it
                 // also must to be done for new instances (see
diff --git a/web/core/modules/ckeditor/js/plugins/drupalimagecaption/plugin.js b/web/core/modules/ckeditor/js/plugins/drupalimagecaption/plugin.js
index 7cd215a705..2f43b9d9c6 100644
--- a/web/core/modules/ckeditor/js/plugins/drupalimagecaption/plugin.js
+++ b/web/core/modules/ckeditor/js/plugins/drupalimagecaption/plugin.js
@@ -139,6 +139,9 @@
               var figure = new CKEDITOR.htmlParser.element('figure');
               caption = new CKEDITOR.htmlParser.fragment.fromHtml(caption, 'figcaption');
 
+              var captionFilter = new CKEDITOR.filter(widgetDefinition.editables.caption.allowedContent);
+              captionFilter.applyTo(caption);
+
               caption.attributes['data-placeholder'] = placeholderText;
 
               element.replaceWith(figure);
diff --git a/web/core/modules/content_moderation/src/Plugin/views/filter/ModerationStateFilter.php b/web/core/modules/content_moderation/src/Plugin/views/filter/ModerationStateFilter.php
index 69309f00d3..4c7ea7c525 100644
--- a/web/core/modules/content_moderation/src/Plugin/views/filter/ModerationStateFilter.php
+++ b/web/core/modules/content_moderation/src/Plugin/views/filter/ModerationStateFilter.php
@@ -123,6 +123,7 @@ protected function opSimple() {
     $this->ensureMyTable();
 
     $entity_type = $this->entityTypeManager->getDefinition($this->getEntityType());
+    $bundle_condition = NULL;
     if ($entity_type->hasKey('bundle')) {
       // Get a list of bundles that are being moderated by the workflows
       // configured in this filter.
@@ -156,7 +157,8 @@ protected function opSimple() {
           $entity_base_table_alias = $this->query->addRelationship($entity_base_table, $join, $entity_revision_base_table);
         }
 
-        $this->query->addWhere($this->options['group'], "$entity_base_table_alias.{$entity_type->getKey('bundle')}", $moderated_bundles, 'IN');
+        $bundle_condition = new Condition('AND');
+        $bundle_condition->condition("$entity_base_table_alias.{$entity_type->getKey('bundle')}", $moderated_bundles, 'IN');
       }
       // Otherwise, force the query to return an empty result.
       else {
@@ -186,7 +188,14 @@ protected function opSimple() {
       $field->condition($and);
     }
 
-    $this->query->addWhere($this->options['group'], $field);
+    if ($bundle_condition) {
+      // The query must match the bundle AND the workflow/state conditions.
+      $bundle_condition->condition($field);
+      $this->query->addWhere($this->options['group'], $bundle_condition);
+    }
+    else {
+      $this->query->addWhere($this->options['group'], $field);
+    }
   }
 
   /**
diff --git a/web/core/modules/content_moderation/tests/modules/content_moderation_test_views/config/install/views.view.test_content_moderation_state_filter_base_table_filter_group_or.yml b/web/core/modules/content_moderation/tests/modules/content_moderation_test_views/config/install/views.view.test_content_moderation_state_filter_base_table_filter_group_or.yml
new file mode 100644
index 0000000000..5a45433c7b
--- /dev/null
+++ b/web/core/modules/content_moderation/tests/modules/content_moderation_test_views/config/install/views.view.test_content_moderation_state_filter_base_table_filter_group_or.yml
@@ -0,0 +1,268 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - content_moderation
+    - node
+    - user
+id: test_content_moderation_state_filter_base_table_filter_group_or
+label: test_content_moderation_state_filter_base_table_filter_group_or
+module: views
+description: ''
+tag: ''
+base_table: node_field_data
+base_field: nid
+display:
+  default:
+    display_plugin: default
+    id: default
+    display_title: Master
+    position: 0
+    display_options:
+      access:
+        type: perm
+        options:
+          perm: 'access content'
+      cache:
+        type: tag
+        options: {  }
+      query:
+        type: views_query
+        options:
+          disable_sql_rewrite: false
+          distinct: false
+          replica: false
+          query_comment: ''
+          query_tags: {  }
+      exposed_form:
+        type: basic
+        options:
+          submit_button: Apply
+          reset_button: false
+          reset_button_label: Reset
+          exposed_sorts_label: 'Sort by'
+          expose_sort_order: true
+          sort_asc_label: Asc
+          sort_desc_label: Desc
+      pager:
+        type: none
+        options:
+          offset: 0
+      style:
+        type: default
+        options:
+          grouping: {  }
+          row_class: ''
+          default_row_class: true
+          uses_fields: false
+      row:
+        type: fields
+        options:
+          inline: {  }
+          separator: ''
+          hide_empty: false
+          default_field_elements: true
+      fields:
+        nid:
+          id: nid
+          table: node_field_data
+          field: nid
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: ''
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: false
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: value
+          type: number_integer
+          settings:
+            thousand_separator: ''
+            prefix_suffix: false
+          group_column: value
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
+          entity_type: node
+          entity_field: nid
+          plugin_id: field
+      filters:
+        moderation_state:
+          id: moderation_state
+          table: node_field_data
+          field: moderation_state
+          relationship: none
+          group_type: group
+          admin_label: ''
+          operator: in
+          value: {  }
+          group: 1
+          exposed: true
+          expose:
+            operator_id: moderation_state_op
+            label: 'Default Revision State'
+            description: ''
+            use_operator: false
+            operator: moderation_state_op
+            identifier: default_revision_state
+            required: false
+            remember: false
+            multiple: false
+            remember_roles:
+              authenticated: authenticated
+              anonymous: '0'
+              administrator: '0'
+            reduce: false
+            operator_limit_selection: false
+            operator_list: {  }
+          is_grouped: false
+          group_info:
+            label: ''
+            description: ''
+            identifier: ''
+            optional: true
+            widget: select
+            multiple: false
+            remember: false
+            default_group: All
+            default_group_multiple: {  }
+            group_items: {  }
+          entity_type: node
+          plugin_id: moderation_state_filter
+        moderation_state_1:
+          id: moderation_state_1
+          table: node_field_data
+          field: moderation_state
+          relationship: none
+          group_type: group
+          admin_label: ''
+          operator: 'not empty'
+          value: {  }
+          group: 2
+          exposed: false
+          expose:
+            operator_id: ''
+            label: ''
+            description: ''
+            use_operator: false
+            operator: ''
+            identifier: ''
+            required: false
+            remember: false
+            multiple: false
+            remember_roles:
+              authenticated: authenticated
+            reduce: false
+            operator_limit_selection: false
+            operator_list: {  }
+          is_grouped: false
+          group_info:
+            label: ''
+            description: ''
+            identifier: ''
+            optional: true
+            widget: select
+            multiple: false
+            remember: false
+            default_group: All
+            default_group_multiple: {  }
+            group_items: {  }
+          entity_type: node
+          plugin_id: moderation_state_filter
+      sorts:
+        nid:
+          id: nid
+          table: node_field_data
+          field: nid
+          relationship: none
+          group_type: group
+          admin_label: ''
+          order: ASC
+          exposed: false
+          expose:
+            label: ''
+          entity_type: node
+          entity_field: nid
+          plugin_id: standard
+      header: {  }
+      footer: {  }
+      empty: {  }
+      relationships: {  }
+      arguments: {  }
+      display_extenders: {  }
+      filter_groups:
+        operator: AND
+        groups:
+          1: OR
+          2: OR
+    cache_metadata:
+      max-age: -1
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url
+        - 'user.node_grants:view'
+        - user.permissions
+      tags:
+        - 'config:workflow_list'
+  page_1:
+    display_plugin: page
+    id: page_1
+    display_title: Page
+    position: 1
+    display_options:
+      display_extenders: {  }
+      path: filter-test-path
+    cache_metadata:
+      max-age: -1
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url
+        - 'user.node_grants:view'
+        - user.permissions
+      tags:
+        - 'config:workflow_list'
diff --git a/web/core/modules/content_moderation/tests/src/Kernel/ViewsModerationStateFilterTest.php b/web/core/modules/content_moderation/tests/src/Kernel/ViewsModerationStateFilterTest.php
index 13f9c688de..328f7c8095 100644
--- a/web/core/modules/content_moderation/tests/src/Kernel/ViewsModerationStateFilterTest.php
+++ b/web/core/modules/content_moderation/tests/src/Kernel/ViewsModerationStateFilterTest.php
@@ -133,18 +133,26 @@ public function testStateFilterViewsRelationship() {
     $translated_forward_revision->moderation_state = 'translated_draft';
     $translated_forward_revision->save();
 
-    // The three default revisions are listed when no filter is specified.
-    $this->assertNodesWithFilters([$node, $second_node, $third_node], []);
-
-    // The default revision of node one and three are published.
-    $this->assertNodesWithFilters([$node, $third_node], [
-      'default_revision_state' => 'editorial-published',
-    ]);
-
-    // The default revision of node two is draft.
-    $this->assertNodesWithFilters([$second_node], [
-      'default_revision_state' => 'editorial-draft',
-    ]);
+    // Test the filter within an AND filter group (the default) and an OR filter
+    // group.
+    $base_table_views = [
+      'test_content_moderation_state_filter_base_table',
+      'test_content_moderation_state_filter_base_table_filter_group_or',
+    ];
+    foreach ($base_table_views as $view_id) {
+      // The three default revisions are listed when no filter is specified.
+      $this->assertNodesWithFilters([$node, $second_node, $third_node], [], $view_id);
+
+      // The default revision of node one and three are published.
+      $this->assertNodesWithFilters([$node, $third_node], [
+        'default_revision_state' => 'editorial-published',
+      ], $view_id);
+
+      // The default revision of node two is draft.
+      $this->assertNodesWithFilters([$second_node], [
+        'default_revision_state' => 'editorial-draft',
+      ], $view_id);
+    }
 
     // Test the same three revisions on a view displaying content revisions.
     // Both nodes have one draft revision.
diff --git a/web/core/modules/dblog/tests/src/Functional/DbLogResourceTest.php b/web/core/modules/dblog/tests/src/Functional/DbLogResourceTest.php
index d36ab8a7d0..86a800c907 100644
--- a/web/core/modules/dblog/tests/src/Functional/DbLogResourceTest.php
+++ b/web/core/modules/dblog/tests/src/Functional/DbLogResourceTest.php
@@ -64,7 +64,12 @@ public function testWatchdog() {
     // Write a log message to the DB.
     $this->container->get('logger.channel.rest')->notice('Test message');
     // Get the ID of the written message.
-    $id = Database::getConnection()->queryRange("SELECT wid FROM {watchdog} WHERE type = :type ORDER BY wid DESC", 0, 1, [':type' => 'rest'])
+    $id = Database::getConnection()->select('watchdog', 'w')
+      ->fields('w', ['wid'])
+      ->condition('type', 'rest')
+      ->orderBy('wid', 'DESC')
+      ->range(0, 1)
+      ->execute()
       ->fetchField();
 
     $this->initAuthentication();
diff --git a/web/core/modules/dblog/tests/src/Functional/DbLogTest.php b/web/core/modules/dblog/tests/src/Functional/DbLogTest.php
index e83ef261e0..b835a5debd 100644
--- a/web/core/modules/dblog/tests/src/Functional/DbLogTest.php
+++ b/web/core/modules/dblog/tests/src/Functional/DbLogTest.php
@@ -123,7 +123,9 @@ public function testLogEventPage() {
       'timestamp' => REQUEST_TIME,
     ];
     \Drupal::service('logger.dblog')->log(RfcLogLevel::NOTICE, 'Test message', $context);
-    $wid = Database::getConnection()->query('SELECT MAX(wid) FROM {watchdog}')->fetchField();
+    $query = Database::getConnection()->select('watchdog');
+    $query->addExpression('MAX(wid)');
+    $wid = $query->execute()->fetchField();
 
     // Verify the links appear correctly.
     $this->drupalGet('admin/reports/dblog/event/' . $wid);
@@ -153,7 +155,10 @@ public function test403LogEventPage() {
 
     $this->drupalLogin($this->adminUser);
 
-    $wid = Database::getConnection()->query("SELECT MAX(wid) FROM {watchdog} WHERE type='access denied'")->fetchField();
+    $query = Database::getConnection()->select('watchdog')
+      ->condition('type', 'access denied');
+    $query->addExpression('MAX(wid)');
+    $wid = $query->execute()->fetchField();
     $this->drupalGet('admin/reports/dblog/event/' . $wid);
 
     $table = $this->xpath("//table[@class='dblog-event']");
@@ -208,7 +213,9 @@ public function testLogEventPageWithMissingInfo() {
     $this->generateLogEntries(1, [
       'referer' => NULL,
     ]);
-    $wid = $connection->query('SELECT MAX(wid) FROM {watchdog}')->fetchField();
+    $query = $connection->select('watchdog');
+    $query->addExpression('MAX(wid)');
+    $wid = $query->execute()->fetchField();
     $this->drupalGet('admin/reports/dblog/event/' . $wid);
 
     // Verify table headers are present, even though the referrer is missing.
@@ -222,7 +229,9 @@ public function testLogEventPageWithMissingInfo() {
     $this->generateLogEntries(1, [
       'request_uri' => $request_uri,
     ]);
-    $wid = $connection->query('SELECT MAX(wid) FROM {watchdog}')->fetchField();
+    $query = $connection->select('watchdog');
+    $query->addExpression('MAX(wid)');
+    $wid = $query->execute()->fetchField();
     $this->drupalGet('admin/reports/dblog/event/' . $wid);
 
     // Verify table headers are present.
@@ -322,7 +331,9 @@ private function verifyReports($response = 200) {
     }
 
     // View the database log event page.
-    $wid = Database::getConnection()->query('SELECT MIN(wid) FROM {watchdog}')->fetchField();
+    $query = Database::getConnection()->select('watchdog');
+    $query->addExpression('MIN(wid)');
+    $wid = $query->execute()->fetchField();
     $this->drupalGet('admin/reports/dblog/event/' . $wid);
     $this->assertSession()->statusCodeEquals($response);
     if ($response == 200) {
@@ -335,7 +346,9 @@ private function verifyReports($response = 200) {
    */
   private function verifyBreadcrumbs() {
     // View the database log event page.
-    $wid = Database::getConnection()->query('SELECT MIN(wid) FROM {watchdog}')->fetchField();
+    $query = Database::getConnection()->select('watchdog');
+    $query->addExpression('MIN(wid)');
+    $wid = $query->execute()->fetchField();
     $this->drupalGet('admin/reports/dblog/event/' . $wid);
     $xpath = '//nav[@class="breadcrumb"]/ol/li[last()]/a';
     $this->assertEqual(current($this->xpath($xpath))->getText(), 'Recent log messages', 'DBLogs link displayed at breadcrumb in event page.');
@@ -384,7 +397,7 @@ private function verifyLinkEscaping() {
       'link' => $link,
     ]);
 
-    $result = Database::getConnection()->queryRange('SELECT wid FROM {watchdog} ORDER BY wid DESC', 0, 1);
+    $result = Database::getConnection()->select('watchdog', 'w')->fields('w', ['wid'])->orderBy('wid', 'DESC')->range(0, 1)->execute();
     $this->drupalGet('admin/reports/dblog/event/' . $result->fetchField());
 
     // Check if the link exists (unescaped).
@@ -418,7 +431,7 @@ private function doUser() {
     // Log out user.
     $this->drupalLogout();
     // Fetch the row IDs in watchdog that relate to the user.
-    $result = Database::getConnection()->query('SELECT wid FROM {watchdog} WHERE uid = :uid', [':uid' => $user->id()]);
+    $result = Database::getConnection()->select('watchdog', 'w')->fields('w', ['wid'])->condition('uid', $user->id())->execute();
     foreach ($result as $row) {
       $ids[] = $row->wid;
     }
@@ -590,7 +603,7 @@ public function testDBLogAddAndClear() {
     global $base_root;
     $connection = Database::getConnection();
     // Get a count of how many watchdog entries already exist.
-    $count = $connection->query('SELECT COUNT(*) FROM {watchdog}')->fetchField();
+    $count = $connection->select('watchdog')->countQuery()->execute()->fetchField();
     $log = [
       'channel'     => 'system',
       'message'     => 'Log entry added to test the doClearTest clear down.',
@@ -606,7 +619,7 @@ public function testDBLogAddAndClear() {
     // Add a watchdog entry.
     $this->container->get('logger.dblog')->log($log['severity'], $log['message'], $log);
     // Make sure the table count has actually been incremented.
-    $this->assertEqual($count + 1, $connection->query('SELECT COUNT(*) FROM {watchdog}')->fetchField(), new FormattableMarkup('\Drupal\dblog\Logger\DbLog->log() added an entry to the dblog :count', [':count' => $count]));
+    $this->assertEqual($count + 1, (int) $connection->select('watchdog')->countQuery()->execute()->fetchField(), new FormattableMarkup('\Drupal\dblog\Logger\DbLog->log() added an entry to the dblog :count', [':count' => $count]));
     // Log in the admin user.
     $this->drupalLogin($this->adminUser);
     // Post in order to clear the database table.
@@ -614,7 +627,7 @@ public function testDBLogAddAndClear() {
     // Confirm that the logs should be cleared.
     $this->drupalPostForm(NULL, [], 'Confirm');
     // Count the rows in watchdog that previously related to the deleted user.
-    $count = $connection->query('SELECT COUNT(*) FROM {watchdog}')->fetchField();
+    $count = $connection->select('watchdog')->countQuery()->execute()->fetchField();
     $this->assertEqual($count, 0, new FormattableMarkup('DBLog contains :count records after a clear.', [':count' => $count]));
   }
 
@@ -803,7 +816,9 @@ public function testTemporaryUser() {
 
     // Generate a single watchdog entry.
     $this->generateLogEntries(1, ['user' => $tempuser, 'uid' => $tempuser_uid]);
-    $wid = Database::getConnection()->query('SELECT MAX(wid) FROM {watchdog}')->fetchField();
+    $query = Database::getConnection()->select('watchdog');
+    $query->addExpression('MAX(wid)');
+    $wid = $query->execute()->fetchField();
 
     // Check if the full message displays on the details page.
     $this->drupalGet('admin/reports/dblog/event/' . $wid);
@@ -833,7 +848,9 @@ public function testOverviewLinks() {
 
     // Make sure HTML tags are filtered out in admin/reports/dblog/event/ too.
     $this->generateLogEntries(1, ['message' => "<script>alert('foo');</script> <strong>Lorem ipsum</strong>"]);
-    $wid = Database::getConnection()->query('SELECT MAX(wid) FROM {watchdog}')->fetchField();
+    $query = Database::getConnection()->select('watchdog');
+    $query->addExpression('MAX(wid)');
+    $wid = $query->execute()->fetchField();
     $this->drupalGet('admin/reports/dblog/event/' . $wid);
     $this->assertNoRaw("<script>alert('foo');</script>");
     $this->assertRaw("alert('foo'); <strong>Lorem ipsum</strong>");
@@ -864,7 +881,9 @@ public function testBacktrace() {
     $this->drupalLogin($this->adminUser);
     $this->drupalGet('/error-test/generate-warnings');
 
-    $wid = Database::getConnection()->query('SELECT MAX(wid) FROM {watchdog}')->fetchField();
+    $query = Database::getConnection()->select('watchdog');
+    $query->addExpression('MAX(wid)');
+    $wid = $query->execute()->fetchField();
     $this->drupalGet('admin/reports/dblog/event/' . $wid);
 
     $error_user_notice = [
diff --git a/web/core/modules/dblog/tests/src/Kernel/ConnectionFailureTest.php b/web/core/modules/dblog/tests/src/Kernel/ConnectionFailureTest.php
index 4914f9f4c9..b17c138d13 100644
--- a/web/core/modules/dblog/tests/src/Kernel/ConnectionFailureTest.php
+++ b/web/core/modules/dblog/tests/src/Kernel/ConnectionFailureTest.php
@@ -39,7 +39,10 @@ public function testConnectionFailureLogging() {
     // Re-establish the default database connection.
     $database = Database::getConnection();
 
-    $wid = $database->query("SELECT MAX(wid) FROM {watchdog} WHERE message = 'testConnectionFailureLogging'")->fetchField();
+    $query = $database->select('watchdog')
+      ->condition('message', 'testConnectionFailureLogging');
+    $query->addExpression('MAX(wid)');
+    $wid = $query->execute()->fetchField();
     $this->assertNotEmpty($wid, 'Watchdog entry has been stored in database.');
   }
 
diff --git a/web/core/modules/dblog/tests/src/Kernel/DbLogTest.php b/web/core/modules/dblog/tests/src/Kernel/DbLogTest.php
index b211cc7414..3d0af4cefa 100644
--- a/web/core/modules/dblog/tests/src/Kernel/DbLogTest.php
+++ b/web/core/modules/dblog/tests/src/Kernel/DbLogTest.php
@@ -40,7 +40,7 @@ public function testDbLogCron() {
     // Generate additional log entries.
     $this->generateLogEntries($row_limit + 10);
     // Verify that the database log row count exceeds the row limit.
-    $count = Database::getConnection()->query('SELECT COUNT(wid) FROM {watchdog}')->fetchField();
+    $count = Database::getConnection()->select('watchdog')->countQuery()->execute()->fetchField();
     $this->assertGreaterThan($row_limit, $count, new FormattableMarkup('Dblog row count of @count exceeds row limit of @limit', ['@count' => $count, '@limit' => $row_limit]));
 
     // Get the number of enabled modules. Cron adds a log entry for each module.
@@ -66,13 +66,17 @@ private function runCron() {
     // Get last ID to compare against; log entries get deleted, so we can't
     // reliably add the number of newly created log entries to the current count
     // to measure number of log entries created by cron.
-    $last_id = $connection->query('SELECT MAX(wid) FROM {watchdog}')->fetchField();
+    $query = $connection->select('watchdog');
+    $query->addExpression('MAX(wid)');
+    $last_id = $query->execute()->fetchField();
 
     // Run a cron job.
     $this->container->get('cron')->run();
 
     // Get last ID after cron was run.
-    $current_id = $connection->query('SELECT MAX(wid) FROM {watchdog}')->fetchField();
+    $query = $connection->select('watchdog');
+    $query->addExpression('MAX(wid)');
+    $current_id = $query->execute()->fetchField();
 
     return $current_id - $last_id;
   }
diff --git a/web/core/modules/field/tests/src/Kernel/BulkDeleteTest.php b/web/core/modules/field/tests/src/Kernel/BulkDeleteTest.php
index 2ab7b921e4..44964c89bb 100644
--- a/web/core/modules/field/tests/src/Kernel/BulkDeleteTest.php
+++ b/web/core/modules/field/tests/src/Kernel/BulkDeleteTest.php
@@ -344,10 +344,7 @@ public function testPurgeField() {
     // bundle.
     $actual_hooks = field_test_memorize();
     $hooks = [];
-    $entities = $this->entitiesByBundles[$bundle];
-    foreach ($entities as $id => $entity) {
-      $hooks['field_test_field_delete'][] = $entity;
-    }
+    $hooks['field_test_field_delete'] = $this->entitiesByBundles[$bundle];
     $this->checkHooksInvocations($hooks, $actual_hooks);
 
     // The field still exists, deleted.
@@ -395,10 +392,7 @@ public function testPurgeFieldStorage() {
     // bundle.
     $actual_hooks = field_test_memorize();
     $hooks = [];
-    $entities = $this->entitiesByBundles[$bundle];
-    foreach ($entities as $id => $entity) {
-      $hooks['field_test_field_delete'][] = $entity;
-    }
+    $hooks['field_test_field_delete'] = $this->entitiesByBundles[$bundle];
     $this->checkHooksInvocations($hooks, $actual_hooks);
 
     // The field still exists, deleted.
@@ -430,10 +424,7 @@ public function testPurgeFieldStorage() {
     // Check hooks invocations (same as above, for the 2nd bundle).
     $actual_hooks = field_test_memorize();
     $hooks = [];
-    $entities = $this->entitiesByBundles[$bundle];
-    foreach ($entities as $id => $entity) {
-      $hooks['field_test_field_delete'][] = $entity;
-    }
+    $hooks['field_test_field_delete'] = $this->entitiesByBundles[$bundle];
     $this->checkHooksInvocations($hooks, $actual_hooks);
 
     // The field and the storage still exist, deleted.
diff --git a/web/core/modules/file/src/Element/ManagedFile.php b/web/core/modules/file/src/Element/ManagedFile.php
index 8e7843fcbb..d1728b1202 100644
--- a/web/core/modules/file/src/Element/ManagedFile.php
+++ b/web/core/modules/file/src/Element/ManagedFile.php
@@ -96,6 +96,10 @@ public static function valueCallback(&$element, $input, FormStateInterface $form
           foreach ($input['fids'] as $fid) {
             if ($file = File::load($fid)) {
               $fids[] = $file->id();
+              if (!$file->access('download')) {
+                $force_default = TRUE;
+                break;
+              }
               // Temporary files that belong to other users should never be
               // allowed.
               if ($file->isTemporary()) {
diff --git a/web/core/modules/file/tests/src/Functional/FilePrivateTest.php b/web/core/modules/file/tests/src/Functional/FilePrivateTest.php
index d9f30d53fa..93c7523de1 100644
--- a/web/core/modules/file/tests/src/Functional/FilePrivateTest.php
+++ b/web/core/modules/file/tests/src/Functional/FilePrivateTest.php
@@ -92,11 +92,10 @@ public function testPrivateFile() {
     $this->drupalGet('node/' . $new_node->id() . '/edit');
     $this->getSession()->getPage()->find('css', 'input[name="' . $field_name . '[0][fids]"]')->setValue($node_file->id());
     $this->getSession()->getPage()->pressButton(t('Save'));
-    // Make sure the form submit failed - we stayed on the edit form.
-    $this->assertUrl('node/' . $new_node->id() . '/edit');
-    // Check that we got the expected constraint form error.
-    $constraint = new ReferenceAccessConstraint();
-    $this->assertRaw(new FormattableMarkup($constraint->message, ['%type' => 'file', '%id' => $node_file->id()]));
+    $this->assertUrl('node/' . $new_node->id());
+    // Make sure the submitted hidden file field is empty.
+    $new_node = \Drupal::entityTypeManager()->getStorage('node')->loadUnchanged($new_node->id());
+    $this->assertTrue($new_node->get($field_name)->isEmpty());
     // Attempt to reuse the existing file when creating a new node, and confirm
     // that access is still denied.
     $edit = [];
@@ -107,9 +106,10 @@ public function testPrivateFile() {
     $this->getSession()->getPage()->find('css', 'input[name="' . $field_name . '[0][fids]"]')->setValue($node_file->id());
     $this->getSession()->getPage()->pressButton(t('Save'));
     $new_node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
-    $this->assertTrue(empty($new_node), 'Node was not created.');
-    $this->assertUrl('node/add/' . $type_name);
-    $this->assertRaw(new FormattableMarkup($constraint->message, ['%type' => 'file', '%id' => $node_file->id()]));
+    $this->assertUrl('node/' . $new_node->id());
+    // Make sure the submitted hidden file field is empty.
+    $new_node = \Drupal::entityTypeManager()->getStorage('node')->loadUnchanged($new_node->id());
+    $this->assertTrue($new_node->get($field_name)->isEmpty());
 
     // Now make file_test_file_download() return everything.
     \Drupal::state()->set('file_test.allow_all', TRUE);
diff --git a/web/core/modules/filter/src/Element/TextFormat.php b/web/core/modules/filter/src/Element/TextFormat.php
index 75bcaeaab1..caa14c8c65 100644
--- a/web/core/modules/filter/src/Element/TextFormat.php
+++ b/web/core/modules/filter/src/Element/TextFormat.php
@@ -84,7 +84,7 @@ public static function processFormat(&$element, FormStateInterface $form_state,
 
     // Ensure that children appear as subkeys of this element.
     $element['#tree'] = TRUE;
-    $blacklist = [
+    $keys_not_to_copy = [
       // Make \Drupal::formBuilder()->doBuildForm() regenerate child properties.
       '#parents',
       '#id',
@@ -108,7 +108,7 @@ public static function processFormat(&$element, FormStateInterface $form_state,
     // Move this element into sub-element 'value'.
     unset($element['value']);
     foreach (Element::properties($element) as $key) {
-      if (!in_array($key, $blacklist)) {
+      if (!in_array($key, $keys_not_to_copy)) {
         $element['value'][$key] = $element[$key];
       }
     }
diff --git a/web/core/modules/filter/src/Entity/FilterFormat.php b/web/core/modules/filter/src/Entity/FilterFormat.php
index 604ce01ac2..abd9b6aae8 100644
--- a/web/core/modules/filter/src/Entity/FilterFormat.php
+++ b/web/core/modules/filter/src/Entity/FilterFormat.php
@@ -304,7 +304,7 @@ public function getHtmlRestrictions() {
         // with the existing set, to ensure we only end up with the tags that are
         // allowed by *all* filters with an "allowed html" setting.
         else {
-          // Track the union of forbidden (blacklisted) tags.
+          // Track the union of forbidden tags.
           if (isset($new_restrictions['forbidden_tags'])) {
             if (!isset($restrictions['forbidden_tags'])) {
               $restrictions['forbidden_tags'] = $new_restrictions['forbidden_tags'];
@@ -314,15 +314,15 @@ public function getHtmlRestrictions() {
             }
           }
 
-          // Track the intersection of allowed (whitelisted) tags.
+          // Track the intersection of allowed tags.
           if (isset($restrictions['allowed'])) {
             $intersection = $restrictions['allowed'];
             foreach ($intersection as $tag => $attributes) {
-              // If the current tag is not whitelisted by the new filter, then
-              // it's outside of the intersection.
+              // If the current tag is not allowed by the new filter, then it's
+              // outside of the intersection.
               if (!array_key_exists($tag, $new_restrictions['allowed'])) {
                 // The exception is the asterisk (which applies to all tags): it
-                // does not need to be whitelisted by every filter in order to be
+                // does not need to be allowed by every filter in order to be
                 // used; not every filter needs attribute restrictions on all tags.
                 if ($tag === '*') {
                   continue;
@@ -375,10 +375,10 @@ public function getHtmlRestrictions() {
         }
       }, NULL);
 
-      // Simplification: if we have both a (intersected) whitelist and a (unioned)
-      // blacklist, then remove any tags from the whitelist that also exist in the
-      // blacklist. Now the whitelist alone expresses all tag-level restrictions,
-      // and we can delete the blacklist.
+      // Simplification: if we have both allowed (intersected) and forbidden
+      // (unioned) tags, then remove any allowed tags that are also forbidden.
+      // Once complete, the list of allowed tags expresses all tag-level
+      // restrictions, and the list of forbidden tags can be removed.
       if (isset($restrictions['allowed']) && isset($restrictions['forbidden_tags'])) {
         foreach ($restrictions['forbidden_tags'] as $tag) {
           if (isset($restrictions['allowed'][$tag])) {
@@ -388,9 +388,9 @@ public function getHtmlRestrictions() {
         unset($restrictions['forbidden_tags']);
       }
 
-      // Simplification: if the only remaining allowed tag is the asterisk (which
-      // contains attribute restrictions that apply to all tags), and only
-      // whitelisting filters were used, then effectively nothing is allowed.
+      // Simplification: if the only remaining allowed tag is the asterisk
+      // (which contains attribute restrictions that apply to all tags), and
+      // there are no forbidden tags, then effectively nothing is allowed.
       if (isset($restrictions['allowed'])) {
         if (count($restrictions['allowed']) === 1 && array_key_exists('*', $restrictions['allowed']) && !isset($restrictions['forbidden_tags'])) {
           $restrictions['allowed'] = [];
diff --git a/web/core/modules/filter/src/FilterFormatInterface.php b/web/core/modules/filter/src/FilterFormatInterface.php
index 6008f3fa40..707776b39a 100644
--- a/web/core/modules/filter/src/FilterFormatInterface.php
+++ b/web/core/modules/filter/src/FilterFormatInterface.php
@@ -72,10 +72,10 @@ public function getFilterTypes();
    *
    * @return array|false
    *   A structured array as returned by FilterInterface::getHTMLRestrictions(),
-   *   but with the intersection of all filters in this text format.
-   *   Will either indicate blacklisting of tags or whitelisting of tags. In
-   *   the latter case, it's possible that restrictions on attributes are also
-   *   stored. FALSE means there are no HTML restrictions.
+   *   but with the intersection of all filters in this text format. The
+   *   restrictions will either forbid or allow a list of tags. In the latter
+   *   case, it's possible that restrictions on attributes are also stored.
+   *   FALSE means there are no HTML restrictions.
    */
   public function getHtmlRestrictions();
 
diff --git a/web/core/modules/filter/src/Plugin/Filter/FilterCaption.php b/web/core/modules/filter/src/Plugin/Filter/FilterCaption.php
index a03c95f5c8..b5a58563d3 100644
--- a/web/core/modules/filter/src/Plugin/Filter/FilterCaption.php
+++ b/web/core/modules/filter/src/Plugin/Filter/FilterCaption.php
@@ -4,9 +4,12 @@
 
 use Drupal\Component\Utility\Html;
 use Drupal\Component\Utility\Xss;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\filter\FilterPluginManager;
 use Drupal\filter\FilterProcessResult;
 use Drupal\filter\Plugin\FilterBase;
 use Drupal\filter\Render\FilteredMarkup;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Provides a filter to caption elements.
@@ -20,7 +23,43 @@
  *   type = Drupal\filter\Plugin\FilterInterface::TYPE_TRANSFORM_REVERSIBLE
  * )
  */
-class FilterCaption extends FilterBase {
+class FilterCaption extends FilterBase implements ContainerFactoryPluginInterface {
+
+  /**
+   * Filter manager.
+   *
+   * @var \Drupal\filter\FilterPluginManager
+   */
+  protected $filterManager;
+
+  /**
+   * Constructs a new FilterCaption.
+   *
+   * @param array $configuration
+   *   Configuration.
+   * @param string $plugin_id
+   *   Plugin ID.
+   * @param mixed $plugin_definition
+   *   Definition.
+   * @param \Drupal\filter\FilterPluginManager $filter_manager
+   *   Filter plugin manager.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, FilterPluginManager $filter_manager = NULL) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+    $this->filterManager = $filter_manager ?: \Drupal::service('plugin.manager.filter');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('plugin.manager.filter')
+    );
+  }
 
   /**
    * {@inheritdoc}
@@ -31,6 +70,13 @@ public function process($text, $langcode) {
     if (stristr($text, 'data-caption') !== FALSE) {
       $dom = Html::load($text);
       $xpath = new \DOMXPath($dom);
+      $html_filter = $this->filterManager->createInstance('filter_html', [
+        'settings' => [
+          'allowed_html' => '<a href hreflang target rel> <em> <strong> <cite> <code> <br>',
+          'filter_html_help' => FALSE,
+          'filter_html_nofollow' => FALSE,
+        ],
+      ]);
       foreach ($xpath->query('//*[@data-caption]') as $node) {
         // Read the data-caption attribute's value, then delete it.
         $caption = Html::escape($node->getAttribute('data-caption'));
@@ -39,10 +85,19 @@ public function process($text, $langcode) {
         // Sanitize caption: decode HTML encoding, limit allowed HTML tags; only
         // allow inline tags that are allowed by default, plus <br>.
         $caption = Html::decodeEntities($caption);
-        $caption = FilteredMarkup::create(Xss::filter($caption, ['a', 'em', 'strong', 'cite', 'code', 'br']));
+        $raw_caption = $caption;
+        $filtered_caption = $html_filter->process($caption, $langcode);
+        $result->addCacheableDependency($filtered_caption);
+        $caption = FilteredMarkup::create($filtered_caption->getProcessedText());
 
-        // The caption must be non-empty.
-        if (mb_strlen($caption) === 0) {
+        // The caption must be non-empty - however the Media Embed CKEditor
+        // plugin uses a single space to represent a newly added caption. The
+        // HTML filter will transform this into an empty string and prevent the
+        // content editor from adding a new caption. To allow for this we treat
+        // a raw caption value of ' ' as valid and adding the wrapping figure
+        // element.
+        // @see core/modules/media/js/plugins/drupalmedia/plugin.es6.js
+        if (mb_strlen($caption) === 0 && $raw_caption !== ' ') {
           continue;
         }
 
diff --git a/web/core/modules/filter/src/Plugin/Filter/FilterHtml.php b/web/core/modules/filter/src/Plugin/Filter/FilterHtml.php
index 86b8bbdeb1..9c1c9c2a90 100644
--- a/web/core/modules/filter/src/Plugin/Filter/FilterHtml.php
+++ b/web/core/modules/filter/src/Plugin/Filter/FilterHtml.php
@@ -113,7 +113,7 @@ public function filterAttributes($text) {
     $xpath = new \DOMXPath($html_dom);
     foreach ($restrictions['allowed'] as $allowed_tag => $tag_attributes) {
       // By default, no attributes are allowed for a tag, but due to the
-      // globally whitelisted attributes, it is impossible for a tag to actually
+      // globally allowed attributes, it is impossible for a tag to actually
       // completely disallow attributes.
       if ($tag_attributes === FALSE) {
         $tag_attributes = [];
@@ -149,23 +149,23 @@ public function filterAttributes($text) {
   }
 
   /**
-   * Filter attributes on an element by name and value according to a whitelist.
+   * Filters attributes on an element according to a list of allowed values.
    *
    * @param \DOMElement $element
    *   The element to be processed.
    * @param array $allowed_attributes
-   *   The attributes whitelist as an array of names and values.
+   *   The list of allowed attributes as an array of names and values.
    */
   protected function filterElementAttributes(\DOMElement $element, array $allowed_attributes) {
     $modified_attributes = [];
     foreach ($element->attributes as $name => $attribute) {
-      // Remove attributes not in the whitelist.
+      // Remove attributes not in the list of allowed attributes.
       $allowed_value = $this->findAllowedValue($allowed_attributes, $name);
       if (empty($allowed_value)) {
         $modified_attributes[$name] = FALSE;
       }
       elseif ($allowed_value !== TRUE) {
-        // Check the attribute values whitelist.
+        // Check the list of allowed attribute values.
         $attribute_values = preg_split('/\s+/', $attribute->value, -1, PREG_SPLIT_NO_EMPTY);
         $modified_attributes[$name] = [];
         foreach ($attribute_values as $value) {
@@ -247,8 +247,8 @@ public function getHTMLRestrictions() {
       return $this->restrictions;
     }
 
-    // Parse the allowed HTML setting, and gradually make the whitelist more
-    // specific.
+    // Parse the allowed HTML setting, and gradually make the list of allowed
+    // tags more specific.
     $restrictions = ['allowed' => []];
 
     // Make all the tags self-closing, so they will be parsed into direct
@@ -283,7 +283,7 @@ public function getHTMLRestrictions() {
           // but one allowed attribute value that some may be tempted to use
           // is specifically nonsensical: the asterisk. A prefix is required for
           // allowed attribute values with a wildcard. A wildcard by itself
-          // would mean whitelisting all possible attribute values. But in that
+          // would mean allowing all possible attribute values. But in that
           // case, one would not specify an attribute value at all.
           $allowed_attribute_values = array_filter($allowed_attribute_values, function ($value) use ($star_protector) {
             return $value !== '*';
@@ -311,14 +311,14 @@ public function getHTMLRestrictions() {
     // The 'style' and 'on*' ('onClick' etc.) attributes are always forbidden,
     // and are removed by Xss::filter().
     // The 'lang', and 'dir' attributes apply to all elements and are always
-    // allowed. The value whitelist for the 'dir' attribute is enforced by
-    // self::filterAttributes().  Note that those two attributes are in the
+    // allowed. The list of allowed values for the 'dir' attribute is enforced
+    // by self::filterAttributes(). Note that those two attributes are in the
     // short list of globally usable attributes in HTML5. They are always
     // allowed since the correct values of lang and dir may only be known to
     // the content author. Of the other global attributes, they are not usually
     // added by hand to content, and especially the class attribute can have
     // undesired visual effects by allowing content authors to apply any
-    // available style, so specific values should be explicitly whitelisted.
+    // available style, so specific values should be explicitly allowed.
     // @see http://www.w3.org/TR/html5/dom.html#global-attributes
     $restrictions['allowed']['*'] = [
       'style' => FALSE,
diff --git a/web/core/modules/filter/tests/src/Kernel/FilterKernelTest.php b/web/core/modules/filter/tests/src/Kernel/FilterKernelTest.php
index 5c2ea33a12..a0637e385d 100644
--- a/web/core/modules/filter/tests/src/Kernel/FilterKernelTest.php
+++ b/web/core/modules/filter/tests/src/Kernel/FilterKernelTest.php
@@ -404,8 +404,8 @@ public function testLineBreakFilter() {
    * @todo It is possible to add script, iframe etc. to allowed tags, but this
    *   makes HTML filter completely ineffective.
    *
-   * @todo Class, id, name and xmlns should be added to disallowed attributes,
-   *   or better a whitelist approach should be used for that too.
+   * @todo Class, id, name and xmlns should be added to the list of forbidden
+   *   attributes, or, better yet, use an allowed attribute list.
    */
   public function testHtmlFilter() {
     // Get FilterHtml object.
@@ -460,11 +460,11 @@ public function testHtmlFilter() {
     $f = (string) $filter->process('<br />', Language::LANGCODE_NOT_SPECIFIED);
     $this->assertNormalized($f, '<br />', 'HTML filter should allow self-closing line breaks.');
 
-    // All attributes of whitelisted tags are stripped by default.
+    // All attributes of allowed tags are stripped by default.
     $f = (string) $filter->process('<a kitten="cute" llama="awesome">link</a>', Language::LANGCODE_NOT_SPECIFIED);
     $this->assertNormalized($f, '<a>link</a>', 'HTML filter should remove attributes that are not explicitly allowed.');
 
-    // Now whitelist the "llama" attribute on <a>.
+    // Now allow the "llama" attribute on <a>.
     $filter->setConfiguration([
       'settings' => [
         'allowed_html' => '<a href llama> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd> <br>',
@@ -475,7 +475,7 @@ public function testHtmlFilter() {
     $f = (string) $filter->process('<a kitten="cute" llama="awesome">link</a>', Language::LANGCODE_NOT_SPECIFIED);
     $this->assertNormalized($f, '<a llama="awesome">link</a>', 'HTML filter keeps explicitly allowed attributes, and removes attributes that are not explicitly allowed.');
 
-    // Restrict the whitelisted "llama" attribute on <a> to only allow the value
+    // Restrict the allowed "llama" attribute on <a> to only allow the value
     // "majestical", or "epic".
     $filter->setConfiguration([
       'settings' => [
diff --git a/web/core/modules/jsonapi/jsonapi.api.php b/web/core/modules/jsonapi/jsonapi.api.php
index c011e77f79..2d09100e09 100644
--- a/web/core/modules/jsonapi/jsonapi.api.php
+++ b/web/core/modules/jsonapi/jsonapi.api.php
@@ -63,7 +63,7 @@
  *
  * @see https://github.com/json-api/json-api/pull/1268
  * @see https://github.com/json-api/json-api/pull/1311
- * @see https://www.drupal.org/project/jsonapi/issues/2955020
+ * @see https://www.drupal.org/project/drupal/issues/2955020
  *
  * By implementing revision support as a profile, the JSON:API module should be
  * maximally compatible with other systems.
@@ -117,7 +117,7 @@
  * It is not yet possible to request a collection of revisions. This is still
  * under development in issue [#3009588].
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3009588.
+ * @see https://www.drupal.org/project/drupal/issues/3009588.
  * @see https://tools.ietf.org/html/rfc5829
  * @see https://www.drupal.org/docs/8/modules/jsonapi/revisions
  *
diff --git a/web/core/modules/jsonapi/src/Access/EntityAccessChecker.php b/web/core/modules/jsonapi/src/Access/EntityAccessChecker.php
index d3d4fa06e0..1a5b3ea19c 100644
--- a/web/core/modules/jsonapi/src/Access/EntityAccessChecker.php
+++ b/web/core/modules/jsonapi/src/Access/EntityAccessChecker.php
@@ -31,7 +31,7 @@
  * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
  *   may change at any time and could break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class EntityAccessChecker {
@@ -238,7 +238,7 @@ public function checkEntityAccess(EntityInterface $entity, $operation, AccountIn
    *
    * @todo: remove when a generic revision access API exists in Drupal core, and
    * also remove the injected "node" and "media" services.
-   * @see https://www.drupal.org/project/jsonapi/issues/2992833#comment-12818386
+   * @see https://www.drupal.org/project/drupal/issues/2992833#comment-12818386
    */
   protected function checkRevisionViewAccess(EntityInterface $entity, AccountInterface $account) {
     assert($entity instanceof RevisionableInterface);
@@ -257,7 +257,7 @@ protected function checkRevisionViewAccess(EntityInterface $entity, AccountInter
 
       default:
         $reason = 'Only node and media revisions are supported by JSON:API.';
-        $reason .= ' For context, see https://www.drupal.org/project/jsonapi/issues/2992833#comment-12818258.';
+        $reason .= ' For context, see https://www.drupal.org/project/drupal/issues/2992833#comment-12818258.';
         $reason .= ' To contribute, see https://www.drupal.org/project/drupal/issues/2350939 and https://www.drupal.org/project/drupal/issues/2809177.';
         $access = AccessResult::neutral($reason);
     }
diff --git a/web/core/modules/jsonapi/src/Access/RelationshipFieldAccess.php b/web/core/modules/jsonapi/src/Access/RelationshipFieldAccess.php
index ff0e103745..244dee3e57 100644
--- a/web/core/modules/jsonapi/src/Access/RelationshipFieldAccess.php
+++ b/web/core/modules/jsonapi/src/Access/RelationshipFieldAccess.php
@@ -20,7 +20,7 @@
  * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
  *   may change at any time and could break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class RelationshipFieldAccess implements AccessInterface {
diff --git a/web/core/modules/jsonapi/src/Access/TemporaryQueryGuard.php b/web/core/modules/jsonapi/src/Access/TemporaryQueryGuard.php
index dd3b0a8e3d..a919611cc0 100644
--- a/web/core/modules/jsonapi/src/Access/TemporaryQueryGuard.php
+++ b/web/core/modules/jsonapi/src/Access/TemporaryQueryGuard.php
@@ -32,7 +32,7 @@
  * @see https://www.drupal.org/project/drupal/issues/2809177
  * @see https://www.drupal.org/project/drupal/issues/777578
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class TemporaryQueryGuard {
diff --git a/web/core/modules/jsonapi/src/Context/FieldResolver.php b/web/core/modules/jsonapi/src/Context/FieldResolver.php
index b67c1cc752..b1e6a025d8 100644
--- a/web/core/modules/jsonapi/src/Context/FieldResolver.php
+++ b/web/core/modules/jsonapi/src/Context/FieldResolver.php
@@ -67,7 +67,7 @@
  * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
  *   may change at any time and could break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class FieldResolver {
@@ -256,18 +256,21 @@ public static function resolveInternalIncludePath(ResourceType $resource_type, a
    *   The JSON:API resource type from which to resolve the field name.
    * @param string $external_field_name
    *   The public field name to map to a Drupal field name.
+   * @param string $operator
+   *   (optional) The operator of the condition for which the path should be
+   *   resolved.
    *
    * @return string
    *   The mapped field name.
    *
    * @throws \Drupal\Core\Http\Exception\CacheableBadRequestHttpException
    */
-  public function resolveInternalEntityQueryPath($resource_type, $external_field_name) {
+  public function resolveInternalEntityQueryPath($resource_type, $external_field_name, $operator = NULL) {
     $function_args = func_get_args();
     // @todo Remove this conditional block in drupal:9.0.0 and add a type hint
     // to the first argument of this method.
     // @see https://www.drupal.org/project/drupal/issues/3078045
-    if (count($function_args) === 3) {
+    if (count($function_args) === 3 && is_string($resource_type)) {
       @trigger_error('Passing the entity type ID and bundle to ' . __METHOD__ . ' is deprecated in drupal:8.8.0 and will throw a fatal error in drupal:9.0.0. Pass a JSON:API resource type instead. See https://www.drupal.org/node/3078036', E_USER_DEPRECATED);
       list($entity_type_id, $bundle, $external_field_name) = $function_args;
       $resource_type = $this->resourceTypeRepository->get($entity_type_id, $bundle);
@@ -368,7 +371,10 @@ public function resolveInternalEntityQueryPath($resource_type, $external_field_n
       // If there are no remaining path parts, the process is finished unless
       // the field has multiple properties, in which case one must be specified.
       if (empty($parts)) {
-        if ($property_specifier_needed) {
+        // If the operator is asserting the presence or absence of a
+        // relationship entirely, it does not make sense to require a property
+        // specifier.
+        if ($property_specifier_needed && (!$at_least_one_entity_reference_field || !in_array($operator, ['IS NULL', 'IS NOT NULL'], TRUE))) {
           $possible_specifiers = array_map(function ($specifier) use ($at_least_one_entity_reference_field) {
             return $at_least_one_entity_reference_field && $specifier !== 'id' ? "meta.$specifier" : $specifier;
           }, $candidate_property_names);
@@ -538,7 +544,7 @@ protected function getInternalName($field_name, array $resource_types) {
    */
   protected function isMemberFilterable($external_name, array $resource_types) {
     return array_reduce($resource_types, function ($carry, ResourceType $resource_type) use ($external_name) {
-      // @todo: remove the next line and uncomment the following one in https://www.drupal.org/project/jsonapi/issues/3017047.
+      // @todo: remove the next line and uncomment the following one in https://www.drupal.org/project/drupal/issues/3017047.
       return $carry ?: $external_name === 'id' || $resource_type->isFieldEnabled($resource_type->getInternalName($external_name));
       /*return $carry ?: in_array($external_name, ['id', 'type']) || $resource_type->isFieldEnabled($resource_type->getInternalName($external_name));*/
     }, FALSE);
@@ -640,7 +646,7 @@ protected static function getDataReferencePropertyName(array $candidate_definiti
         $prior_parts = array_slice($unresolved_path_parts, 0, count($unresolved_path_parts) - count($remaining_parts));
         return implode('.', array_merge($prior_parts, [$reference_name], $remaining_parts));
       }, $unique_reference_names);
-      // @todo Add test coverage for this in https://www.drupal.org/project/jsonapi/issues/2971281
+      // @todo Add test coverage for this in https://www.drupal.org/project/drupal/issues/2971281
       $message = sprintf('Ambiguous path. Try one of the following: %s, in place of the given path: %s', implode(', ', $choices), implode('.', $unresolved_path_parts));
       $cacheability = (new CacheableMetadata())->addCacheContexts(['url.query_args:filter', 'url.query_args:sort']);
       throw new CacheableBadRequestHttpException($cacheability, $message);
diff --git a/web/core/modules/jsonapi/src/Controller/EntityResource.php b/web/core/modules/jsonapi/src/Controller/EntityResource.php
index 4bd865bc0a..30d322774e 100644
--- a/web/core/modules/jsonapi/src/Controller/EntityResource.php
+++ b/web/core/modules/jsonapi/src/Controller/EntityResource.php
@@ -65,7 +65,7 @@
  * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
  *   may change at any time and could break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class EntityResource {
@@ -307,7 +307,7 @@ public function createIndividual(ResourceType $resource_type, Request $request)
    */
   public function patchIndividual(ResourceType $resource_type, EntityInterface $entity, Request $request) {
     if ($entity instanceof RevisionableInterface && !($entity->isLatestRevision() && $entity->isDefaultRevision())) {
-      throw new BadRequestHttpException('Updating a resource object that has a working copy is not yet supported. See https://www.drupal.org/project/jsonapi/issues/2795279.');
+      throw new BadRequestHttpException('Updating a resource object that has a working copy is not yet supported. See https://www.drupal.org/project/drupal/issues/2795279.');
     }
 
     $parsed_entity = $this->deserialize($resource_type, $request, JsonApiDocumentTopLevel::class);
@@ -408,7 +408,7 @@ public function getCollection(ResourceType $resource_type, Request $request) {
     catch (\LogicException $e) {
       // Ensure good DX when an entity query involves a config entity type.
       // For example: getting users with a particular role, which is a config
-      // entity type: https://www.drupal.org/project/jsonapi/issues/2959445.
+      // entity type: https://www.drupal.org/project/drupal/issues/2959445.
       // @todo Remove the message parsing in https://www.drupal.org/project/drupal/issues/3028967.
       if (strpos($e->getMessage(), 'Getting the base fields is not supported for entity type') === 0) {
         preg_match('/entity type (.*)\./', $e->getMessage(), $matches);
diff --git a/web/core/modules/jsonapi/src/Controller/EntryPoint.php b/web/core/modules/jsonapi/src/Controller/EntryPoint.php
index a564580523..29a4276572 100644
--- a/web/core/modules/jsonapi/src/Controller/EntryPoint.php
+++ b/web/core/modules/jsonapi/src/Controller/EntryPoint.php
@@ -23,7 +23,7 @@
  * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
  *   may change at any time and could break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class EntryPoint extends ControllerBase {
diff --git a/web/core/modules/jsonapi/src/Controller/FileUpload.php b/web/core/modules/jsonapi/src/Controller/FileUpload.php
index b4a5800ca2..c11244a799 100644
--- a/web/core/modules/jsonapi/src/Controller/FileUpload.php
+++ b/web/core/modules/jsonapi/src/Controller/FileUpload.php
@@ -34,7 +34,7 @@
  * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
  *   may change at any time and could break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class FileUpload {
@@ -179,7 +179,7 @@ public function handleFileUploadForNewResource(Request $request, ResourceType $r
       throw new UnprocessableEntityHttpException($message);
     }
 
-    // @todo Remove line below in favor of commented line in https://www.drupal.org/project/jsonapi/issues/2878463.
+    // @todo Remove line below in favor of commented line in https://www.drupal.org/project/drupal/issues/2878463.
     $self_link = new Link(new CacheableMetadata(), Url::fromRoute('jsonapi.file--file.individual', ['entity' => $file->uuid()]), 'self');
     /* $self_link = new Link(new CacheableMetadata(), $this->entity->toUrl('jsonapi'), ['self']); */
     $links = new LinkCollection(['self' => $self_link]);
diff --git a/web/core/modules/jsonapi/src/DependencyInjection/Compiler/RegisterSerializationClassesCompilerPass.php b/web/core/modules/jsonapi/src/DependencyInjection/Compiler/RegisterSerializationClassesCompilerPass.php
index 7c7d21e146..7587cb3242 100644
--- a/web/core/modules/jsonapi/src/DependencyInjection/Compiler/RegisterSerializationClassesCompilerPass.php
+++ b/web/core/modules/jsonapi/src/DependencyInjection/Compiler/RegisterSerializationClassesCompilerPass.php
@@ -17,7 +17,7 @@
  * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
  *   may change at any time and could break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class RegisterSerializationClassesCompilerPass extends DrupalRegisterSerializationClassesCompilerPass {
diff --git a/web/core/modules/jsonapi/src/Encoder/JsonEncoder.php b/web/core/modules/jsonapi/src/Encoder/JsonEncoder.php
index 2f7f04f6f2..fdc83ff2b4 100644
--- a/web/core/modules/jsonapi/src/Encoder/JsonEncoder.php
+++ b/web/core/modules/jsonapi/src/Encoder/JsonEncoder.php
@@ -10,7 +10,7 @@
  * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
  *   may change at any time and could break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class JsonEncoder extends SerializationJsonEncoder {
diff --git a/web/core/modules/jsonapi/src/Entity/EntityValidationTrait.php b/web/core/modules/jsonapi/src/Entity/EntityValidationTrait.php
index 8dca70b273..99291254ca 100644
--- a/web/core/modules/jsonapi/src/Entity/EntityValidationTrait.php
+++ b/web/core/modules/jsonapi/src/Entity/EntityValidationTrait.php
@@ -12,7 +12,7 @@
  * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
  *   may change at any time and could break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 trait EntityValidationTrait {
diff --git a/web/core/modules/jsonapi/src/EventSubscriber/DefaultExceptionSubscriber.php b/web/core/modules/jsonapi/src/EventSubscriber/DefaultExceptionSubscriber.php
index 0220ef55dd..b7ad921c9e 100644
--- a/web/core/modules/jsonapi/src/EventSubscriber/DefaultExceptionSubscriber.php
+++ b/web/core/modules/jsonapi/src/EventSubscriber/DefaultExceptionSubscriber.php
@@ -18,7 +18,7 @@
  * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
  *   may change at any time and could break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class DefaultExceptionSubscriber extends SerializationDefaultExceptionSubscriber {
diff --git a/web/core/modules/jsonapi/src/EventSubscriber/JsonApiRequestValidator.php b/web/core/modules/jsonapi/src/EventSubscriber/JsonApiRequestValidator.php
index d030784e83..02e7ac7716 100644
--- a/web/core/modules/jsonapi/src/EventSubscriber/JsonApiRequestValidator.php
+++ b/web/core/modules/jsonapi/src/EventSubscriber/JsonApiRequestValidator.php
@@ -16,7 +16,7 @@
  * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
  *   may change at any time and could break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class JsonApiRequestValidator implements EventSubscriberInterface {
diff --git a/web/core/modules/jsonapi/src/EventSubscriber/ResourceResponseSubscriber.php b/web/core/modules/jsonapi/src/EventSubscriber/ResourceResponseSubscriber.php
index 9bf6aaa43a..d04cb211d6 100644
--- a/web/core/modules/jsonapi/src/EventSubscriber/ResourceResponseSubscriber.php
+++ b/web/core/modules/jsonapi/src/EventSubscriber/ResourceResponseSubscriber.php
@@ -19,7 +19,7 @@
  * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
  *   may change at any time and could break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  *
  * This is 99% identical to:
diff --git a/web/core/modules/jsonapi/src/EventSubscriber/ResourceResponseValidator.php b/web/core/modules/jsonapi/src/EventSubscriber/ResourceResponseValidator.php
index 1502a21910..9db86dbc98 100644
--- a/web/core/modules/jsonapi/src/EventSubscriber/ResourceResponseValidator.php
+++ b/web/core/modules/jsonapi/src/EventSubscriber/ResourceResponseValidator.php
@@ -20,7 +20,7 @@
  * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
  *   may change at any time and could break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  *
  * @see \Drupal\rest\EventSubscriber\ResourceResponseSubscriber
diff --git a/web/core/modules/jsonapi/src/Exception/EntityAccessDeniedHttpException.php b/web/core/modules/jsonapi/src/Exception/EntityAccessDeniedHttpException.php
index 3365326aac..74ab245e51 100644
--- a/web/core/modules/jsonapi/src/Exception/EntityAccessDeniedHttpException.php
+++ b/web/core/modules/jsonapi/src/Exception/EntityAccessDeniedHttpException.php
@@ -18,7 +18,7 @@
  * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
  *   may change at any time and could break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class EntityAccessDeniedHttpException extends CacheableAccessDeniedHttpException implements ResourceIdentifierInterface {
@@ -71,7 +71,7 @@ public function __construct($entity, AccessResultInterface $entity_access, $poin
       $error['reason'] = $entity_access->getReason();
     }
     $this->error = $error;
-    // @todo: remove this ternary operation in https://www.drupal.org/project/jsonapi/issues/2997594.
+    // @todo: remove this ternary operation in https://www.drupal.org/project/drupal/issues/2997594.
     $this->resourceIdentifier = $entity ? ResourceIdentifier::fromEntity($entity) : NULL;
   }
 
diff --git a/web/core/modules/jsonapi/src/Exception/UnprocessableHttpEntityException.php b/web/core/modules/jsonapi/src/Exception/UnprocessableHttpEntityException.php
index 95e496779e..b9d5a6f583 100644
--- a/web/core/modules/jsonapi/src/Exception/UnprocessableHttpEntityException.php
+++ b/web/core/modules/jsonapi/src/Exception/UnprocessableHttpEntityException.php
@@ -18,7 +18,7 @@
  * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
  *   may change at any time and could break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class UnprocessableHttpEntityException extends HttpException {
diff --git a/web/core/modules/jsonapi/src/IncludeResolver.php b/web/core/modules/jsonapi/src/IncludeResolver.php
index d8a283df0d..ad0e36ca40 100644
--- a/web/core/modules/jsonapi/src/IncludeResolver.php
+++ b/web/core/modules/jsonapi/src/IncludeResolver.php
@@ -24,7 +24,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class IncludeResolver {
diff --git a/web/core/modules/jsonapi/src/JsonApiResource/Data.php b/web/core/modules/jsonapi/src/JsonApiResource/Data.php
index 57dd0ad675..61cf72ca40 100644
--- a/web/core/modules/jsonapi/src/JsonApiResource/Data.php
+++ b/web/core/modules/jsonapi/src/JsonApiResource/Data.php
@@ -11,7 +11,7 @@
  * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
  *   may change at any time and could break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 abstract class Data implements \IteratorAggregate, \Countable {
diff --git a/web/core/modules/jsonapi/src/JsonApiResource/ErrorCollection.php b/web/core/modules/jsonapi/src/JsonApiResource/ErrorCollection.php
index 2396641abd..d43febdd6e 100644
--- a/web/core/modules/jsonapi/src/JsonApiResource/ErrorCollection.php
+++ b/web/core/modules/jsonapi/src/JsonApiResource/ErrorCollection.php
@@ -11,7 +11,7 @@
  * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
  *   may change at any time and could break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  *
  * (The spec says the top-level `data` and `errors` members MUST NOT coexist.)
diff --git a/web/core/modules/jsonapi/src/JsonApiResource/IncludedData.php b/web/core/modules/jsonapi/src/JsonApiResource/IncludedData.php
index a1566641a6..e0938a1f9a 100644
--- a/web/core/modules/jsonapi/src/JsonApiResource/IncludedData.php
+++ b/web/core/modules/jsonapi/src/JsonApiResource/IncludedData.php
@@ -11,7 +11,7 @@
  * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
  *   may change at any time and could break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class IncludedData extends ResourceObjectData {
diff --git a/web/core/modules/jsonapi/src/JsonApiResource/JsonApiDocumentTopLevel.php b/web/core/modules/jsonapi/src/JsonApiResource/JsonApiDocumentTopLevel.php
index 5fc7291f96..df58c32c50 100644
--- a/web/core/modules/jsonapi/src/JsonApiResource/JsonApiDocumentTopLevel.php
+++ b/web/core/modules/jsonapi/src/JsonApiResource/JsonApiDocumentTopLevel.php
@@ -8,7 +8,7 @@
  * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
  *   may change at any time and could break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  *
  * @see http://jsonapi.org/format/#document-top-level
diff --git a/web/core/modules/jsonapi/src/JsonApiResource/LabelOnlyResourceObject.php b/web/core/modules/jsonapi/src/JsonApiResource/LabelOnlyResourceObject.php
index 157b9de1f2..1beaa23056 100644
--- a/web/core/modules/jsonapi/src/JsonApiResource/LabelOnlyResourceObject.php
+++ b/web/core/modules/jsonapi/src/JsonApiResource/LabelOnlyResourceObject.php
@@ -12,7 +12,7 @@
  * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
  *   may change at any time and could break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 final class LabelOnlyResourceObject extends ResourceObject {
diff --git a/web/core/modules/jsonapi/src/JsonApiResource/Link.php b/web/core/modules/jsonapi/src/JsonApiResource/Link.php
index f098572a65..4f82215719 100644
--- a/web/core/modules/jsonapi/src/JsonApiResource/Link.php
+++ b/web/core/modules/jsonapi/src/JsonApiResource/Link.php
@@ -15,7 +15,7 @@
  * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
  *   may change at any time and could break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  *
  * @see https://tools.ietf.org/html/rfc8288
diff --git a/web/core/modules/jsonapi/src/JsonApiResource/LinkCollection.php b/web/core/modules/jsonapi/src/JsonApiResource/LinkCollection.php
index 098f580b71..3215888693 100644
--- a/web/core/modules/jsonapi/src/JsonApiResource/LinkCollection.php
+++ b/web/core/modules/jsonapi/src/JsonApiResource/LinkCollection.php
@@ -10,7 +10,7 @@
  * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
  *   may change at any time and could break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 final class LinkCollection implements \IteratorAggregate {
diff --git a/web/core/modules/jsonapi/src/JsonApiResource/NullIncludedData.php b/web/core/modules/jsonapi/src/JsonApiResource/NullIncludedData.php
index 46b4e6ab5b..6d5da0c1c6 100644
--- a/web/core/modules/jsonapi/src/JsonApiResource/NullIncludedData.php
+++ b/web/core/modules/jsonapi/src/JsonApiResource/NullIncludedData.php
@@ -8,7 +8,7 @@
  * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
  *   may change at any time and could break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class NullIncludedData extends IncludedData {
diff --git a/web/core/modules/jsonapi/src/JsonApiResource/OmittedData.php b/web/core/modules/jsonapi/src/JsonApiResource/OmittedData.php
index 1e57348e0e..77fd81ce9e 100644
--- a/web/core/modules/jsonapi/src/JsonApiResource/OmittedData.php
+++ b/web/core/modules/jsonapi/src/JsonApiResource/OmittedData.php
@@ -11,7 +11,7 @@
  * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
  *   may change at any time and could break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class OmittedData extends ResourceObjectData {
diff --git a/web/core/modules/jsonapi/src/JsonApiResource/Relationship.php b/web/core/modules/jsonapi/src/JsonApiResource/Relationship.php
index 6e89907a98..b5a383ea89 100644
--- a/web/core/modules/jsonapi/src/JsonApiResource/Relationship.php
+++ b/web/core/modules/jsonapi/src/JsonApiResource/Relationship.php
@@ -16,7 +16,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class Relationship implements TopLevelDataInterface {
diff --git a/web/core/modules/jsonapi/src/JsonApiResource/RelationshipData.php b/web/core/modules/jsonapi/src/JsonApiResource/RelationshipData.php
index e4bfa8a2c3..2c2aec5078 100644
--- a/web/core/modules/jsonapi/src/JsonApiResource/RelationshipData.php
+++ b/web/core/modules/jsonapi/src/JsonApiResource/RelationshipData.php
@@ -10,7 +10,7 @@
  * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
  *   may change at any time and could break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class RelationshipData extends Data {
diff --git a/web/core/modules/jsonapi/src/JsonApiResource/ResourceIdentifier.php b/web/core/modules/jsonapi/src/JsonApiResource/ResourceIdentifier.php
index b6bca7e3b4..20ca39a856 100644
--- a/web/core/modules/jsonapi/src/JsonApiResource/ResourceIdentifier.php
+++ b/web/core/modules/jsonapi/src/JsonApiResource/ResourceIdentifier.php
@@ -28,12 +28,12 @@
  * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
  *   may change at any time and could break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  *
  * @see http://jsonapi.org/format/#document-resource-object-relationships
  * @see https://github.com/json-api/json-api/pull/1156#issuecomment-325377995
- * @see https://www.drupal.org/project/jsonapi/issues/2864680
+ * @see https://www.drupal.org/project/drupal/issues/2864680
  */
 class ResourceIdentifier implements ResourceIdentifierInterface {
 
diff --git a/web/core/modules/jsonapi/src/JsonApiResource/ResourceIdentifierInterface.php b/web/core/modules/jsonapi/src/JsonApiResource/ResourceIdentifierInterface.php
index 872da7dc06..f2e5e6c42d 100644
--- a/web/core/modules/jsonapi/src/JsonApiResource/ResourceIdentifierInterface.php
+++ b/web/core/modules/jsonapi/src/JsonApiResource/ResourceIdentifierInterface.php
@@ -13,7 +13,7 @@
  * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
  *   may change at any time and could break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 interface ResourceIdentifierInterface {
diff --git a/web/core/modules/jsonapi/src/JsonApiResource/ResourceIdentifierTrait.php b/web/core/modules/jsonapi/src/JsonApiResource/ResourceIdentifierTrait.php
index e4942cfb8f..b7b65586e5 100644
--- a/web/core/modules/jsonapi/src/JsonApiResource/ResourceIdentifierTrait.php
+++ b/web/core/modules/jsonapi/src/JsonApiResource/ResourceIdentifierTrait.php
@@ -8,7 +8,7 @@
  * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
  *   may change at any time and could break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  *
  * @see \Drupal\jsonapi\JsonApiResource\ResourceIdentifierInterface
diff --git a/web/core/modules/jsonapi/src/JsonApiResource/ResourceObject.php b/web/core/modules/jsonapi/src/JsonApiResource/ResourceObject.php
index cce7d45a31..34f64ef839 100644
--- a/web/core/modules/jsonapi/src/JsonApiResource/ResourceObject.php
+++ b/web/core/modules/jsonapi/src/JsonApiResource/ResourceObject.php
@@ -27,7 +27,7 @@
  * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
  *   may change at any time and could break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class ResourceObject implements CacheableDependencyInterface, ResourceIdentifierInterface {
diff --git a/web/core/modules/jsonapi/src/JsonApiResource/ResourceObjectData.php b/web/core/modules/jsonapi/src/JsonApiResource/ResourceObjectData.php
index 5fadfb0356..be630e96f8 100644
--- a/web/core/modules/jsonapi/src/JsonApiResource/ResourceObjectData.php
+++ b/web/core/modules/jsonapi/src/JsonApiResource/ResourceObjectData.php
@@ -11,7 +11,7 @@
  * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
  *   may change at any time and could break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class ResourceObjectData extends Data implements TopLevelDataInterface {
diff --git a/web/core/modules/jsonapi/src/JsonApiResource/TopLevelDataInterface.php b/web/core/modules/jsonapi/src/JsonApiResource/TopLevelDataInterface.php
index a01da15682..558548f3ca 100644
--- a/web/core/modules/jsonapi/src/JsonApiResource/TopLevelDataInterface.php
+++ b/web/core/modules/jsonapi/src/JsonApiResource/TopLevelDataInterface.php
@@ -8,7 +8,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 interface TopLevelDataInterface {
diff --git a/web/core/modules/jsonapi/src/JsonApiSpec.php b/web/core/modules/jsonapi/src/JsonApiSpec.php
index a6c8ffa321..c59286fcf5 100644
--- a/web/core/modules/jsonapi/src/JsonApiSpec.php
+++ b/web/core/modules/jsonapi/src/JsonApiSpec.php
@@ -8,7 +8,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  *
  * @see http://jsonapi.org/format
diff --git a/web/core/modules/jsonapi/src/JsonapiServiceProvider.php b/web/core/modules/jsonapi/src/JsonapiServiceProvider.php
index 4696ed567f..e3b0f6d0cc 100644
--- a/web/core/modules/jsonapi/src/JsonapiServiceProvider.php
+++ b/web/core/modules/jsonapi/src/JsonapiServiceProvider.php
@@ -14,7 +14,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class JsonapiServiceProvider implements ServiceModifierInterface, ServiceProviderInterface {
diff --git a/web/core/modules/jsonapi/src/Normalizer/ConfigEntityDenormalizer.php b/web/core/modules/jsonapi/src/Normalizer/ConfigEntityDenormalizer.php
index 39288abac9..de74db67aa 100644
--- a/web/core/modules/jsonapi/src/Normalizer/ConfigEntityDenormalizer.php
+++ b/web/core/modules/jsonapi/src/Normalizer/ConfigEntityDenormalizer.php
@@ -11,7 +11,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 final class ConfigEntityDenormalizer extends EntityDenormalizerBase {
diff --git a/web/core/modules/jsonapi/src/Normalizer/ContentEntityDenormalizer.php b/web/core/modules/jsonapi/src/Normalizer/ContentEntityDenormalizer.php
index 287f2cb140..aa56f8ab9c 100644
--- a/web/core/modules/jsonapi/src/Normalizer/ContentEntityDenormalizer.php
+++ b/web/core/modules/jsonapi/src/Normalizer/ContentEntityDenormalizer.php
@@ -12,7 +12,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 final class ContentEntityDenormalizer extends EntityDenormalizerBase {
diff --git a/web/core/modules/jsonapi/src/Normalizer/EntityAccessDeniedHttpExceptionNormalizer.php b/web/core/modules/jsonapi/src/Normalizer/EntityAccessDeniedHttpExceptionNormalizer.php
index 0d18dcdea0..5dd2b6e988 100644
--- a/web/core/modules/jsonapi/src/Normalizer/EntityAccessDeniedHttpExceptionNormalizer.php
+++ b/web/core/modules/jsonapi/src/Normalizer/EntityAccessDeniedHttpExceptionNormalizer.php
@@ -16,7 +16,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  *
  * @see http://jsonapi.org/format/#error-objects
diff --git a/web/core/modules/jsonapi/src/Normalizer/EntityDenormalizerBase.php b/web/core/modules/jsonapi/src/Normalizer/EntityDenormalizerBase.php
index 65f25995bf..edfeaa19fd 100644
--- a/web/core/modules/jsonapi/src/Normalizer/EntityDenormalizerBase.php
+++ b/web/core/modules/jsonapi/src/Normalizer/EntityDenormalizerBase.php
@@ -15,7 +15,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 abstract class EntityDenormalizerBase extends NormalizerBase implements DenormalizerInterface {
diff --git a/web/core/modules/jsonapi/src/Normalizer/EntityReferenceFieldNormalizer.php b/web/core/modules/jsonapi/src/Normalizer/EntityReferenceFieldNormalizer.php
index c79d56ae1a..de46d4d369 100644
--- a/web/core/modules/jsonapi/src/Normalizer/EntityReferenceFieldNormalizer.php
+++ b/web/core/modules/jsonapi/src/Normalizer/EntityReferenceFieldNormalizer.php
@@ -19,7 +19,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class EntityReferenceFieldNormalizer extends FieldNormalizer {
diff --git a/web/core/modules/jsonapi/src/Normalizer/FieldItemNormalizer.php b/web/core/modules/jsonapi/src/Normalizer/FieldItemNormalizer.php
index 183fac0730..f3afb42992 100644
--- a/web/core/modules/jsonapi/src/Normalizer/FieldItemNormalizer.php
+++ b/web/core/modules/jsonapi/src/Normalizer/FieldItemNormalizer.php
@@ -20,7 +20,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class FieldItemNormalizer extends NormalizerBase implements DenormalizerInterface {
diff --git a/web/core/modules/jsonapi/src/Normalizer/FieldNormalizer.php b/web/core/modules/jsonapi/src/Normalizer/FieldNormalizer.php
index b33677c178..74b78db50e 100644
--- a/web/core/modules/jsonapi/src/Normalizer/FieldNormalizer.php
+++ b/web/core/modules/jsonapi/src/Normalizer/FieldNormalizer.php
@@ -15,7 +15,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class FieldNormalizer extends NormalizerBase implements DenormalizerInterface {
diff --git a/web/core/modules/jsonapi/src/Normalizer/HttpExceptionNormalizer.php b/web/core/modules/jsonapi/src/Normalizer/HttpExceptionNormalizer.php
index 4613815815..0b91b4d92f 100644
--- a/web/core/modules/jsonapi/src/Normalizer/HttpExceptionNormalizer.php
+++ b/web/core/modules/jsonapi/src/Normalizer/HttpExceptionNormalizer.php
@@ -14,7 +14,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  *
  * @see http://jsonapi.org/format/#error-objects
@@ -112,7 +112,7 @@ protected function buildErrorObjects(HttpException $exception) {
    *   URL pointing to the specific RFC-2616 section. Or NULL if it is an HTTP
    *   status code that is defined in another RFC.
    *
-   * @see https://www.drupal.org/project/jsonapi/issues/2832211#comment-11826234
+   * @see https://www.drupal.org/project/drupal/issues/2832211#comment-11826234
    *
    * @internal
    */
diff --git a/web/core/modules/jsonapi/src/Normalizer/JsonApiDocumentTopLevelNormalizer.php b/web/core/modules/jsonapi/src/Normalizer/JsonApiDocumentTopLevelNormalizer.php
index b6abaf7eaa..ae5cbe0dc3 100644
--- a/web/core/modules/jsonapi/src/Normalizer/JsonApiDocumentTopLevelNormalizer.php
+++ b/web/core/modules/jsonapi/src/Normalizer/JsonApiDocumentTopLevelNormalizer.php
@@ -28,7 +28,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  *
  * @see \Drupal\jsonapi\JsonApiResource\JsonApiDocumentTopLevel
@@ -217,7 +217,7 @@ public function normalize($object, $format = NULL, array $context = []) {
    * @return \Drupal\jsonapi\Normalizer\Value\CacheableNormalization
    *   The normalized document.
    *
-   * @todo: refactor this to use CacheableNormalization::aggregate in https://www.drupal.org/project/jsonapi/issues/3036284.
+   * @todo: refactor this to use CacheableNormalization::aggregate in https://www.drupal.org/project/drupal/issues/3036284.
    */
   protected function normalizeErrorDocument(JsonApiDocumentTopLevel $document, $format, array $context = []) {
     $normalized_values = array_map(function (HttpExceptionInterface $exception) use ($format, $context) {
@@ -245,7 +245,7 @@ protected function normalizeErrorDocument(JsonApiDocumentTopLevel $document, $fo
    * @return \Drupal\jsonapi\Normalizer\Value\CacheableNormalization|\Drupal\jsonapi\Normalizer\Value\CacheableOmission
    *   The normalized omissions.
    *
-   * @todo: refactor this to use link collections in https://www.drupal.org/project/jsonapi/issues/3036279.
+   * @todo: refactor this to use link collections in https://www.drupal.org/project/drupal/issues/3036279.
    */
   protected function normalizeOmissionsLinks(OmittedData $omissions, $format, array $context = []) {
     $normalized_omissions = array_map(function (HttpExceptionInterface $exception) use ($format, $context) {
diff --git a/web/core/modules/jsonapi/src/Normalizer/LinkCollectionNormalizer.php b/web/core/modules/jsonapi/src/Normalizer/LinkCollectionNormalizer.php
index a883389d39..2c3f5b71de 100644
--- a/web/core/modules/jsonapi/src/Normalizer/LinkCollectionNormalizer.php
+++ b/web/core/modules/jsonapi/src/Normalizer/LinkCollectionNormalizer.php
@@ -24,7 +24,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class LinkCollectionNormalizer extends NormalizerBase {
diff --git a/web/core/modules/jsonapi/src/Normalizer/NormalizerBase.php b/web/core/modules/jsonapi/src/Normalizer/NormalizerBase.php
index 241feac691..37f639bdb7 100644
--- a/web/core/modules/jsonapi/src/Normalizer/NormalizerBase.php
+++ b/web/core/modules/jsonapi/src/Normalizer/NormalizerBase.php
@@ -11,7 +11,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 abstract class NormalizerBase extends SerializationNormalizerBase {
diff --git a/web/core/modules/jsonapi/src/Normalizer/ResourceIdentifierNormalizer.php b/web/core/modules/jsonapi/src/Normalizer/ResourceIdentifierNormalizer.php
index c1327bdda1..b2ee9cac9a 100644
--- a/web/core/modules/jsonapi/src/Normalizer/ResourceIdentifierNormalizer.php
+++ b/web/core/modules/jsonapi/src/Normalizer/ResourceIdentifierNormalizer.php
@@ -18,7 +18,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class ResourceIdentifierNormalizer extends NormalizerBase implements DenormalizerInterface {
diff --git a/web/core/modules/jsonapi/src/Normalizer/ResourceObjectNormalizer.php b/web/core/modules/jsonapi/src/Normalizer/ResourceObjectNormalizer.php
index 10a5e4cca5..8a21f42020 100644
--- a/web/core/modules/jsonapi/src/Normalizer/ResourceObjectNormalizer.php
+++ b/web/core/modules/jsonapi/src/Normalizer/ResourceObjectNormalizer.php
@@ -17,7 +17,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class ResourceObjectNormalizer extends NormalizerBase {
diff --git a/web/core/modules/jsonapi/src/Normalizer/UnprocessableHttpEntityExceptionNormalizer.php b/web/core/modules/jsonapi/src/Normalizer/UnprocessableHttpEntityExceptionNormalizer.php
index 35834dd789..aca1088623 100644
--- a/web/core/modules/jsonapi/src/Normalizer/UnprocessableHttpEntityExceptionNormalizer.php
+++ b/web/core/modules/jsonapi/src/Normalizer/UnprocessableHttpEntityExceptionNormalizer.php
@@ -16,7 +16,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  *
  * @see http://jsonapi.org/format/#error-objects
diff --git a/web/core/modules/jsonapi/src/Normalizer/Value/CacheableNormalization.php b/web/core/modules/jsonapi/src/Normalizer/Value/CacheableNormalization.php
index 538422284e..fbc77e89b1 100644
--- a/web/core/modules/jsonapi/src/Normalizer/Value/CacheableNormalization.php
+++ b/web/core/modules/jsonapi/src/Normalizer/Value/CacheableNormalization.php
@@ -13,7 +13,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class CacheableNormalization implements CacheableDependencyInterface {
diff --git a/web/core/modules/jsonapi/src/Normalizer/Value/CacheableOmission.php b/web/core/modules/jsonapi/src/Normalizer/Value/CacheableOmission.php
index 9a8310dc44..e3a290723a 100644
--- a/web/core/modules/jsonapi/src/Normalizer/Value/CacheableOmission.php
+++ b/web/core/modules/jsonapi/src/Normalizer/Value/CacheableOmission.php
@@ -10,7 +10,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 final class CacheableOmission extends CacheableNormalization {
diff --git a/web/core/modules/jsonapi/src/Normalizer/Value/HttpExceptionNormalizerValue.php b/web/core/modules/jsonapi/src/Normalizer/Value/HttpExceptionNormalizerValue.php
index 83cf3beb02..67a61bfd80 100644
--- a/web/core/modules/jsonapi/src/Normalizer/Value/HttpExceptionNormalizerValue.php
+++ b/web/core/modules/jsonapi/src/Normalizer/Value/HttpExceptionNormalizerValue.php
@@ -8,7 +8,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class HttpExceptionNormalizerValue extends CacheableNormalization {}
diff --git a/web/core/modules/jsonapi/src/ParamConverter/EntityUuidConverter.php b/web/core/modules/jsonapi/src/ParamConverter/EntityUuidConverter.php
index 75f7181796..f853c15e40 100644
--- a/web/core/modules/jsonapi/src/ParamConverter/EntityUuidConverter.php
+++ b/web/core/modules/jsonapi/src/ParamConverter/EntityUuidConverter.php
@@ -17,7 +17,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  *
  * @see \Drupal\Core\ParamConverter\EntityConverter
diff --git a/web/core/modules/jsonapi/src/ParamConverter/ResourceTypeConverter.php b/web/core/modules/jsonapi/src/ParamConverter/ResourceTypeConverter.php
index ab4569b9d5..d0dba4dd1f 100644
--- a/web/core/modules/jsonapi/src/ParamConverter/ResourceTypeConverter.php
+++ b/web/core/modules/jsonapi/src/ParamConverter/ResourceTypeConverter.php
@@ -12,7 +12,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class ResourceTypeConverter implements ParamConverterInterface {
diff --git a/web/core/modules/jsonapi/src/Query/EntityCondition.php b/web/core/modules/jsonapi/src/Query/EntityCondition.php
index 3e2d460b2c..dea06c132d 100644
--- a/web/core/modules/jsonapi/src/Query/EntityCondition.php
+++ b/web/core/modules/jsonapi/src/Query/EntityCondition.php
@@ -11,7 +11,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class EntityCondition {
diff --git a/web/core/modules/jsonapi/src/Query/EntityConditionGroup.php b/web/core/modules/jsonapi/src/Query/EntityConditionGroup.php
index fcefe2a278..8a529bf312 100644
--- a/web/core/modules/jsonapi/src/Query/EntityConditionGroup.php
+++ b/web/core/modules/jsonapi/src/Query/EntityConditionGroup.php
@@ -8,7 +8,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class EntityConditionGroup {
diff --git a/web/core/modules/jsonapi/src/Query/Filter.php b/web/core/modules/jsonapi/src/Query/Filter.php
index e87f0081a4..ab134317c4 100644
--- a/web/core/modules/jsonapi/src/Query/Filter.php
+++ b/web/core/modules/jsonapi/src/Query/Filter.php
@@ -12,7 +12,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class Filter {
@@ -157,7 +157,8 @@ public static function createFromQueryParameter($parameter, ResourceType $resour
     foreach ($expanded as &$filter_item) {
       if (isset($filter_item[static::CONDITION_KEY][EntityCondition::PATH_KEY])) {
         $unresolved = $filter_item[static::CONDITION_KEY][EntityCondition::PATH_KEY];
-        $filter_item[static::CONDITION_KEY][EntityCondition::PATH_KEY] = $field_resolver->resolveInternalEntityQueryPath($resource_type, $unresolved);
+        $operator = $filter_item[static::CONDITION_KEY][EntityCondition::OPERATOR_KEY];
+        $filter_item[static::CONDITION_KEY][EntityCondition::PATH_KEY] = $field_resolver->resolveInternalEntityQueryPath($resource_type, $unresolved, $operator);
       }
     }
     return new static(static::buildEntityConditionGroup($expanded));
diff --git a/web/core/modules/jsonapi/src/Query/OffsetPage.php b/web/core/modules/jsonapi/src/Query/OffsetPage.php
index 70a752ef2c..988cc69a50 100644
--- a/web/core/modules/jsonapi/src/Query/OffsetPage.php
+++ b/web/core/modules/jsonapi/src/Query/OffsetPage.php
@@ -11,7 +11,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class OffsetPage {
diff --git a/web/core/modules/jsonapi/src/Query/Sort.php b/web/core/modules/jsonapi/src/Query/Sort.php
index c127a9230a..3f01638e91 100644
--- a/web/core/modules/jsonapi/src/Query/Sort.php
+++ b/web/core/modules/jsonapi/src/Query/Sort.php
@@ -11,7 +11,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class Sort {
diff --git a/web/core/modules/jsonapi/src/ResourceResponse.php b/web/core/modules/jsonapi/src/ResourceResponse.php
index b73165d170..cf6ddac7a9 100644
--- a/web/core/modules/jsonapi/src/ResourceResponse.php
+++ b/web/core/modules/jsonapi/src/ResourceResponse.php
@@ -17,7 +17,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  *
  * @see \Drupal\rest\ModifiedResourceResponse
diff --git a/web/core/modules/jsonapi/src/ResourceType/ResourceType.php b/web/core/modules/jsonapi/src/ResourceType/ResourceType.php
index 10e2c0fb65..07d92c7387 100644
--- a/web/core/modules/jsonapi/src/ResourceType/ResourceType.php
+++ b/web/core/modules/jsonapi/src/ResourceType/ResourceType.php
@@ -15,7 +15,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  *
  * @see \Drupal\jsonapi\ResourceType\ResourceTypeRepository
diff --git a/web/core/modules/jsonapi/src/ResourceType/ResourceTypeAttribute.php b/web/core/modules/jsonapi/src/ResourceType/ResourceTypeAttribute.php
index 19f71c192f..f606516c9c 100644
--- a/web/core/modules/jsonapi/src/ResourceType/ResourceTypeAttribute.php
+++ b/web/core/modules/jsonapi/src/ResourceType/ResourceTypeAttribute.php
@@ -8,7 +8,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  *
  * @see \Drupal\jsonapi\ResourceType\ResourceTypeRepository
diff --git a/web/core/modules/jsonapi/src/ResourceType/ResourceTypeField.php b/web/core/modules/jsonapi/src/ResourceType/ResourceTypeField.php
index 987f496384..c6a1922f8e 100644
--- a/web/core/modules/jsonapi/src/ResourceType/ResourceTypeField.php
+++ b/web/core/modules/jsonapi/src/ResourceType/ResourceTypeField.php
@@ -8,7 +8,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  *
  * @see \Drupal\jsonapi\ResourceType\ResourceTypeRepository
diff --git a/web/core/modules/jsonapi/src/ResourceType/ResourceTypeRelationship.php b/web/core/modules/jsonapi/src/ResourceType/ResourceTypeRelationship.php
index 8e782a527c..2ae37bd698 100644
--- a/web/core/modules/jsonapi/src/ResourceType/ResourceTypeRelationship.php
+++ b/web/core/modules/jsonapi/src/ResourceType/ResourceTypeRelationship.php
@@ -8,7 +8,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  *
  * @see \Drupal\jsonapi\ResourceType\ResourceTypeRepository
diff --git a/web/core/modules/jsonapi/src/ResourceType/ResourceTypeRepository.php b/web/core/modules/jsonapi/src/ResourceType/ResourceTypeRepository.php
index 724264732f..226c6703d8 100644
--- a/web/core/modules/jsonapi/src/ResourceType/ResourceTypeRepository.php
+++ b/web/core/modules/jsonapi/src/ResourceType/ResourceTypeRepository.php
@@ -33,7 +33,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  *
  * @see \Drupal\jsonapi\ResourceType\ResourceType
diff --git a/web/core/modules/jsonapi/src/ResourceType/ResourceTypeRepositoryInterface.php b/web/core/modules/jsonapi/src/ResourceType/ResourceTypeRepositoryInterface.php
index 6468aaff06..8a66abf5a5 100644
--- a/web/core/modules/jsonapi/src/ResourceType/ResourceTypeRepositoryInterface.php
+++ b/web/core/modules/jsonapi/src/ResourceType/ResourceTypeRepositoryInterface.php
@@ -8,7 +8,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 interface ResourceTypeRepositoryInterface {
diff --git a/web/core/modules/jsonapi/src/Revisions/InvalidVersionIdentifierException.php b/web/core/modules/jsonapi/src/Revisions/InvalidVersionIdentifierException.php
index d30f4a8596..f56a3aa8d5 100644
--- a/web/core/modules/jsonapi/src/Revisions/InvalidVersionIdentifierException.php
+++ b/web/core/modules/jsonapi/src/Revisions/InvalidVersionIdentifierException.php
@@ -8,7 +8,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class InvalidVersionIdentifierException extends \InvalidArgumentException {}
diff --git a/web/core/modules/jsonapi/src/Revisions/NegotiatorBase.php b/web/core/modules/jsonapi/src/Revisions/NegotiatorBase.php
index 0adc78afba..2253090353 100644
--- a/web/core/modules/jsonapi/src/Revisions/NegotiatorBase.php
+++ b/web/core/modules/jsonapi/src/Revisions/NegotiatorBase.php
@@ -11,7 +11,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 abstract class NegotiatorBase implements VersionNegotiatorInterface {
diff --git a/web/core/modules/jsonapi/src/Revisions/ResourceVersionRouteEnhancer.php b/web/core/modules/jsonapi/src/Revisions/ResourceVersionRouteEnhancer.php
index 50cb8b8c5d..853261346c 100644
--- a/web/core/modules/jsonapi/src/Revisions/ResourceVersionRouteEnhancer.php
+++ b/web/core/modules/jsonapi/src/Revisions/ResourceVersionRouteEnhancer.php
@@ -18,7 +18,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 final class ResourceVersionRouteEnhancer implements EnhancerInterface {
@@ -103,7 +103,7 @@ public function enhance(array $defaults, Request $request) {
         /* Uncomment the next line and remove the following one when https://www.drupal.org/project/drupal/issues/3002352 lands in core. */
         /* throw new CacheableHttpException($cacheability, 501, 'Resource versioning is not yet supported for this resource type.'); */
         $message = 'JSON:API does not yet support resource versioning for this resource type.';
-        $message .= ' For context, see https://www.drupal.org/project/jsonapi/issues/2992833#comment-12818258.';
+        $message .= ' For context, see https://www.drupal.org/project/drupal/issues/2992833#comment-12818258.';
         $message .= ' To contribute, see https://www.drupal.org/project/drupal/issues/2350939 and https://www.drupal.org/project/drupal/issues/2809177.';
         throw new CacheableHttpException($cacheability, 501, $message, NULL, []);
       }
diff --git a/web/core/modules/jsonapi/src/Revisions/VersionById.php b/web/core/modules/jsonapi/src/Revisions/VersionById.php
index 4337d37528..36c9825d3a 100644
--- a/web/core/modules/jsonapi/src/Revisions/VersionById.php
+++ b/web/core/modules/jsonapi/src/Revisions/VersionById.php
@@ -10,7 +10,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class VersionById extends NegotiatorBase implements VersionNegotiatorInterface {
diff --git a/web/core/modules/jsonapi/src/Revisions/VersionByRel.php b/web/core/modules/jsonapi/src/Revisions/VersionByRel.php
index f825b6533f..0033c1429a 100644
--- a/web/core/modules/jsonapi/src/Revisions/VersionByRel.php
+++ b/web/core/modules/jsonapi/src/Revisions/VersionByRel.php
@@ -11,7 +11,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class VersionByRel extends NegotiatorBase {
diff --git a/web/core/modules/jsonapi/src/Revisions/VersionNegotiator.php b/web/core/modules/jsonapi/src/Revisions/VersionNegotiator.php
index 157efa529f..76bd43f0f1 100644
--- a/web/core/modules/jsonapi/src/Revisions/VersionNegotiator.php
+++ b/web/core/modules/jsonapi/src/Revisions/VersionNegotiator.php
@@ -13,7 +13,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  *
  * @see \Drupal\jsonapi\Revisions\VersionNegotiatorInterface
diff --git a/web/core/modules/jsonapi/src/Revisions/VersionNegotiatorInterface.php b/web/core/modules/jsonapi/src/Revisions/VersionNegotiatorInterface.php
index 03a9d8023d..a796468615 100644
--- a/web/core/modules/jsonapi/src/Revisions/VersionNegotiatorInterface.php
+++ b/web/core/modules/jsonapi/src/Revisions/VersionNegotiatorInterface.php
@@ -10,7 +10,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  *
  * @see \Drupal\jsonapi\Revisions\VersionNegotiator
diff --git a/web/core/modules/jsonapi/src/Revisions/VersionNotFoundException.php b/web/core/modules/jsonapi/src/Revisions/VersionNotFoundException.php
index cd6fb4b60e..72d0e38346 100644
--- a/web/core/modules/jsonapi/src/Revisions/VersionNotFoundException.php
+++ b/web/core/modules/jsonapi/src/Revisions/VersionNotFoundException.php
@@ -8,7 +8,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class VersionNotFoundException extends \InvalidArgumentException {
diff --git a/web/core/modules/jsonapi/src/Routing/RouteEnhancer.php b/web/core/modules/jsonapi/src/Routing/RouteEnhancer.php
index 0c3b1b477e..1a663fa31b 100644
--- a/web/core/modules/jsonapi/src/Routing/RouteEnhancer.php
+++ b/web/core/modules/jsonapi/src/Routing/RouteEnhancer.php
@@ -12,7 +12,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class RouteEnhancer implements EnhancerInterface {
diff --git a/web/core/modules/jsonapi/src/Routing/Routes.php b/web/core/modules/jsonapi/src/Routing/Routes.php
index e592f007ae..6910ae7008 100644
--- a/web/core/modules/jsonapi/src/Routing/Routes.php
+++ b/web/core/modules/jsonapi/src/Routing/Routes.php
@@ -19,7 +19,7 @@
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 class Routes implements ContainerInjectionInterface {
diff --git a/web/core/modules/jsonapi/src/Serializer/Serializer.php b/web/core/modules/jsonapi/src/Serializer/Serializer.php
index 67c07c473e..709cf77094 100644
--- a/web/core/modules/jsonapi/src/Serializer/Serializer.php
+++ b/web/core/modules/jsonapi/src/Serializer/Serializer.php
@@ -12,12 +12,12 @@
  * Backwards compatibility is in no way guaranteed and will almost certainly be
  * broken in the future.
  *
- * @link https://www.drupal.org/project/jsonapi/issues/2923779#comment-12407443
+ * @link https://www.drupal.org/project/drupal/issues/2923779#comment-12407443
  *
  * @internal JSON:API maintains no PHP API since its API is the HTTP API. This
  *   class may change at any time and this will break any dependencies on it.
  *
- * @see https://www.drupal.org/project/jsonapi/issues/3032787
+ * @see https://www.drupal.org/project/drupal/issues/3032787
  * @see jsonapi.api.php
  */
 final class Serializer extends SymfonySerializer {
diff --git a/web/core/modules/jsonapi/tests/src/Functional/BlockContentTest.php b/web/core/modules/jsonapi/tests/src/Functional/BlockContentTest.php
index d5e51e7a8d..41ac26024e 100644
--- a/web/core/modules/jsonapi/tests/src/Functional/BlockContentTest.php
+++ b/web/core/modules/jsonapi/tests/src/Functional/BlockContentTest.php
@@ -200,7 +200,7 @@ protected function getExpectedCacheContexts(array $sparse_fieldset = NULL) {
    * {@inheritdoc}
    */
   public function testRelated() {
-    $this->markTestSkipped('Remove this in https://www.drupal.org/project/jsonapi/issues/2940339');
+    $this->markTestSkipped('Remove this in https://www.drupal.org/project/drupal/issues/2940339');
   }
 
   /**
diff --git a/web/core/modules/jsonapi/tests/src/Functional/CommentTest.php b/web/core/modules/jsonapi/tests/src/Functional/CommentTest.php
index 4fd1bb786e..6d5efc59fe 100644
--- a/web/core/modules/jsonapi/tests/src/Functional/CommentTest.php
+++ b/web/core/modules/jsonapi/tests/src/Functional/CommentTest.php
@@ -392,7 +392,7 @@ protected static function entityAccess(EntityInterface $entity, $operation, Acco
    * {@inheritdoc}
    */
   public function testRelated() {
-    $this->markTestSkipped('Remove this in https://www.drupal.org/project/jsonapi/issues/2940339');
+    $this->markTestSkipped('Remove this in https://www.drupal.org/project/drupal/issues/2940339');
   }
 
   /**
diff --git a/web/core/modules/jsonapi/tests/src/Functional/ConfigurableLanguageTest.php b/web/core/modules/jsonapi/tests/src/Functional/ConfigurableLanguageTest.php
index fd03d53349..5f9b68cd6f 100644
--- a/web/core/modules/jsonapi/tests/src/Functional/ConfigurableLanguageTest.php
+++ b/web/core/modules/jsonapi/tests/src/Functional/ConfigurableLanguageTest.php
@@ -117,10 +117,10 @@ protected function getExpectedCacheContexts(array $sparse_fieldset = NULL) {
   /**
    * Test a GET request for a default config entity, which has a _core key.
    *
-   * @see https://www.drupal.org/project/jsonapi/issues/2915539
+   * @see https://www.drupal.org/project/drupal/issues/2915539
    */
   public function testGetIndividualDefaultConfig() {
-    // @todo Remove line below in favor of commented line in https://www.drupal.org/project/jsonapi/issues/2878463.
+    // @todo Remove line below in favor of commented line in https://www.drupal.org/project/drupal/issues/2878463.
     $url = Url::fromRoute('jsonapi.configurable_language--configurable_language.individual', ['entity' => ConfigurableLanguage::load('en')->uuid()]);
     /* $url = ConfigurableLanguage::load('en')->toUrl('jsonapi'); */
 
diff --git a/web/core/modules/jsonapi/tests/src/Functional/ExternalNormalizersTest.php b/web/core/modules/jsonapi/tests/src/Functional/ExternalNormalizersTest.php
index 33f6aab0de..117a108b3c 100644
--- a/web/core/modules/jsonapi/tests/src/Functional/ExternalNormalizersTest.php
+++ b/web/core/modules/jsonapi/tests/src/Functional/ExternalNormalizersTest.php
@@ -145,7 +145,7 @@ public function testFormatAgnosticNormalizers($test_module, $expected_value_json
     $this->assertSame(static::VALUE_ORIGINAL, $denormalized_entity->field_test->value);
 
     // Asserts the expected JSON:API normalization.
-    // @todo Remove line below in favor of commented line in https://www.drupal.org/project/jsonapi/issues/2878463.
+    // @todo Remove line below in favor of commented line in https://www.drupal.org/project/drupal/issues/2878463.
     $url = Url::fromRoute('jsonapi.entity_test--entity_test.individual', ['entity' => $this->entity->uuid()]);
     // $url = $this->entity->toUrl('jsonapi');
     $client = $this->getSession()->getDriver()->getClient()->getClient();
diff --git a/web/core/modules/jsonapi/tests/src/Functional/JsonApiRegressionTest.php b/web/core/modules/jsonapi/tests/src/Functional/JsonApiRegressionTest.php
index f2da5ad366..01069960e5 100644
--- a/web/core/modules/jsonapi/tests/src/Functional/JsonApiRegressionTest.php
+++ b/web/core/modules/jsonapi/tests/src/Functional/JsonApiRegressionTest.php
@@ -51,7 +51,7 @@ class JsonApiRegressionTest extends JsonApiFunctionalTestBase {
   /**
    * Ensure filtering on relationships works with bundle-specific target types.
    *
-   * @see https://www.drupal.org/project/jsonapi/issues/2953207
+   * @see https://www.drupal.org/project/drupal/issues/2953207
    */
   public function testBundleSpecificTargetEntityTypeFromIssue2953207() {
     // Set up data model.
@@ -87,7 +87,7 @@ public function testBundleSpecificTargetEntityTypeFromIssue2953207() {
   /**
    * Ensure deep nested include works on multi target entity type field.
    *
-   * @see https://www.drupal.org/project/jsonapi/issues/2973681
+   * @see https://www.drupal.org/project/drupal/issues/2973681
    */
   public function testDeepNestedIncludeMultiTargetEntityTypeFieldFromIssue2973681() {
     // Set up data model.
@@ -151,7 +151,7 @@ public function testDeepNestedIncludeMultiTargetEntityTypeFieldFromIssue2973681(
   /**
    * Ensure POST and PATCH works for bundle-less relationship routes.
    *
-   * @see https://www.drupal.org/project/jsonapi/issues/2976371
+   * @see https://www.drupal.org/project/drupal/issues/2976371
    */
   public function testBundlelessRelationshipMutationFromIssue2973681() {
     $this->config('jsonapi.settings')->set('read_only', FALSE)->save(TRUE);
@@ -202,7 +202,7 @@ public function testBundlelessRelationshipMutationFromIssue2973681() {
   /**
    * Ensures GETting terms works when multiple vocabularies exist.
    *
-   * @see https://www.drupal.org/project/jsonapi/issues/2977879
+   * @see https://www.drupal.org/project/drupal/issues/2977879
    */
   public function testGetTermWhenMultipleVocabulariesExistFromIssue2977879() {
     // Set up data model.
@@ -238,7 +238,7 @@ public function testGetTermWhenMultipleVocabulariesExistFromIssue2977879() {
   /**
    * Cannot PATCH an entity with dangling references in an ER field.
    *
-   * @see https://www.drupal.org/project/jsonapi/issues/2968972
+   * @see https://www.drupal.org/project/drupal/issues/2968972
    */
   public function testDanglingReferencesInAnEntityReferenceFieldFromIssue2968972() {
     $this->config('jsonapi.settings')->set('read_only', FALSE)->save(TRUE);
@@ -309,7 +309,7 @@ public function testDanglingReferencesInAnEntityReferenceFieldFromIssue2968972()
   /**
    * Ensures GETting node collection + hook_node_grants() implementations works.
    *
-   * @see https://www.drupal.org/project/jsonapi/issues/2984964
+   * @see https://www.drupal.org/project/drupal/issues/2984964
    */
   public function testGetNodeCollectionWithHookNodeGrantsImplementationsFromIssue2984964() {
     // Set up data model.
@@ -340,7 +340,7 @@ public function testGetNodeCollectionWithHookNodeGrantsImplementationsFromIssue2
   /**
    * Cannot GET an entity with dangling references in an ER field.
    *
-   * @see https://www.drupal.org/project/jsonapi/issues/2984647
+   * @see https://www.drupal.org/project/drupal/issues/2984647
    */
   public function testDanglingReferencesInAnEntityReferenceFieldFromIssue2984647() {
     // Set up data model.
@@ -470,7 +470,7 @@ public function testDanglingReferencesInAnEntityReferenceFieldFromIssue2984647()
    * Adding a new relationship field should cause new routes to be immediately
    * regenerated. The site builder should not need to manually rebuild caches.
    *
-   * @see https://www.drupal.org/project/jsonapi/issues/2984886
+   * @see https://www.drupal.org/project/drupal/issues/2984886
    */
   public function testThatRoutesAreRebuiltAfterDataModelChangesFromIssue2984886() {
     $user = $this->drupalCreateUser(['access content']);
@@ -526,7 +526,7 @@ public function testThatRoutesAreRebuiltAfterDataModelChangesFromIssue2984886()
   /**
    * Ensures denormalizing relationships with aliased field names works.
    *
-   * @see https://www.drupal.org/project/jsonapi/issues/3007113
+   * @see https://www.drupal.org/project/drupal/issues/3007113
    * @see https://www.drupal.org/project/jsonapi_extras/issues/3004582#comment-12817261
    */
   public function testDenormalizeAliasedRelationshipFromIssue2953207() {
@@ -584,7 +584,7 @@ public function testDenormalizeAliasedRelationshipFromIssue2953207() {
   /**
    * Ensures that Drupal's page cache is effective.
    *
-   * @see https://www.drupal.org/project/jsonapi/issues/3009596
+   * @see https://www.drupal.org/project/drupal/issues/3009596
    */
   public function testPageCacheFromIssue3009596() {
     $anonymous_role = Role::load(RoleInterface::ANONYMOUS_ID);
@@ -619,7 +619,7 @@ public function testPageCacheFromIssue3009596() {
   /**
    * Ensures that filtering by a sequential internal ID named 'id' is possible.
    *
-   * @see https://www.drupal.org/project/jsonapi/issues/3015759
+   * @see https://www.drupal.org/project/drupal/issues/3015759
    */
   public function testFilterByIdFromIssue3015759() {
     // Set up data model.
@@ -659,7 +659,7 @@ public function testFilterByIdFromIssue3015759() {
   /**
    * Ensures datetime fields are normalized using the correct timezone.
    *
-   * @see https://www.drupal.org/project/jsonapi/issues/2999438
+   * @see https://www.drupal.org/project/drupal/issues/2999438
    */
   public function testPatchingDateTimeNormalizedWrongTimeZoneIssue3021194() {
     // Set up data model.
@@ -708,7 +708,7 @@ public function testPatchingDateTimeNormalizedWrongTimeZoneIssue3021194() {
   /**
    * Ensures PATCHing datetime (both date-only & date+time) fields is possible.
    *
-   * @see https://www.drupal.org/project/jsonapi/issues/3021194
+   * @see https://www.drupal.org/project/drupal/issues/3021194
    */
   public function testPatchingDateTimeFieldsFromIssue3021194() {
     $this->config('jsonapi.settings')->set('read_only', FALSE)->save(TRUE);
@@ -791,7 +791,7 @@ public function testPatchingDateTimeFieldsFromIssue3021194() {
   /**
    * Ensure includes are respected even when POSTing.
    *
-   * @see https://www.drupal.org/project/jsonapi/issues/3026030
+   * @see https://www.drupal.org/project/drupal/issues/3026030
    */
   public function testPostToIncludeUrlDoesNotReturnIncludeFromIssue3026030() {
     $this->config('jsonapi.settings')->set('read_only', FALSE)->save(TRUE);
@@ -828,7 +828,7 @@ public function testPostToIncludeUrlDoesNotReturnIncludeFromIssue3026030() {
   /**
    * Ensure includes are respected even when PATCHing.
    *
-   * @see https://www.drupal.org/project/jsonapi/issues/3026030
+   * @see https://www.drupal.org/project/drupal/issues/3026030
    */
   public function testPatchToIncludeUrlDoesNotReturnIncludeFromIssue3026030() {
     $this->config('jsonapi.settings')->set('read_only', FALSE)->save(TRUE);
@@ -874,7 +874,7 @@ public function testPatchToIncludeUrlDoesNotReturnIncludeFromIssue3026030() {
   /**
    * Ensure `@FieldType=map` fields are normalized correctly.
    *
-   * @see https://www.drupal.org/project/jsonapi/issues/3040590
+   * @see https://www.drupal.org/project/drupal/issues/3040590
    */
   public function testMapFieldTypeNormalizationFromIssue3040590() {
     $this->assertTrue($this->container->get('module_installer')->install(['entity_test'], TRUE), 'Installed modules.');
@@ -918,6 +918,62 @@ public function testMapFieldTypeNormalizationFromIssue3040590() {
     $this->assertSame(['foo' => 'bar'], $data['data'][0]['attributes']['data']);
   }
 
+  /**
+   * Ensure filtering for entities with empty entity reference fields works.
+   *
+   * @see https://www.drupal.org/project/drupal/issues/3025372
+   */
+  public function testEmptyRelationshipFilteringFromIssue3025372() {
+    // Set up data model.
+    $this->drupalCreateContentType(['type' => 'folder']);
+    $this->createEntityReferenceField(
+      'node',
+      'folder',
+      'field_parent_folder',
+      NULL,
+      'node',
+      'default',
+      [
+        'target_bundles' => ['folder'],
+      ],
+      FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED
+    );
+    $this->rebuildAll();
+
+    // Create data.
+    $node = Node::create([
+      'title' => 'root folder',
+      'type' => 'folder',
+    ]);
+    $node->save();
+
+    // Test.
+    $user = $this->drupalCreateUser(['access content']);
+    $url = Url::fromRoute('jsonapi.node--folder.collection');
+    $request_options = [
+      RequestOptions::HEADERS => [
+        'Content-Type' => 'application/vnd.api+json',
+        'Accept' => 'application/vnd.api+json',
+      ],
+      RequestOptions::AUTH => [$user->getAccountName(), $user->pass_raw],
+    ];
+    $response = $this->request('GET', $url, $request_options);
+    $this->assertSame(200, $response->getStatusCode(), (string) $response->getBody());
+    $this->assertSame($node->uuid(), Json::decode((string) $response->getBody())['data'][0]['id']);
+    $response = $this->request('GET', $url->setOption('query', [
+      'filter[test][condition][path]' => 'field_parent_folder',
+      'filter[test][condition][operator]' => 'IS NULL',
+    ]), $request_options);
+    $this->assertSame(200, $response->getStatusCode(), (string) $response->getBody());
+    $this->assertSame($node->uuid(), Json::decode((string) $response->getBody())['data'][0]['id']);
+    $response = $this->request('GET', $url->setOption('query', [
+      'filter[test][condition][path]' => 'field_parent_folder',
+      'filter[test][condition][operator]' => 'IS NOT NULL',
+    ]), $request_options);
+    $this->assertSame(200, $response->getStatusCode(), (string) $response->getBody());
+    $this->assertEmpty(Json::decode((string) $response->getBody())['data']);
+  }
+
   /**
    * Tests that the response still has meaningful error messages.
    */
@@ -1198,8 +1254,8 @@ public function testLeakCacheMetadataInOmitted() {
   /**
    * Tests that "virtual/missing" resources can exist for renamed fields.
    *
-   * @see https://www.drupal.org/project/jsonapi/issues/3034786
-   * @see https://www.drupal.org/project/jsonapi_extras/issues/3035544
+   * @see https://www.drupal.org/project/drupal/issues/3034786
+   * @see https://www.drupal.org/project/drupal/issues/3035544
    */
   public function testAliasedFieldsWithVirtualRelationships() {
     // Set up the data model.
diff --git a/web/core/modules/jsonapi/tests/src/Functional/MediaTest.php b/web/core/modules/jsonapi/tests/src/Functional/MediaTest.php
index f604ca6092..62ac530711 100644
--- a/web/core/modules/jsonapi/tests/src/Functional/MediaTest.php
+++ b/web/core/modules/jsonapi/tests/src/Functional/MediaTest.php
@@ -348,7 +348,7 @@ protected function getExpectedUnauthorizedAccessCacheability() {
    */
   public function testPostIndividual() {
     // @todo Mimic \Drupal\Tests\rest\Functional\EntityResource\Media\MediaResourceTestBase::testPost()
-    // @todo Later, use https://www.drupal.org/project/jsonapi/issues/2958554 to upload files rather than the REST module.
+    // @todo Later, use https://www.drupal.org/project/drupal/issues/2958554 to upload files rather than the REST module.
     parent::testPostIndividual();
   }
   // @codingStandardsIgnoreEnd
diff --git a/web/core/modules/jsonapi/tests/src/Functional/MenuLinkContentTest.php b/web/core/modules/jsonapi/tests/src/Functional/MenuLinkContentTest.php
index fdb07f71dd..cf3ce8de31 100644
--- a/web/core/modules/jsonapi/tests/src/Functional/MenuLinkContentTest.php
+++ b/web/core/modules/jsonapi/tests/src/Functional/MenuLinkContentTest.php
@@ -176,7 +176,7 @@ protected function getExpectedUnauthorizedAccessMessage($method) {
    * {@inheritdoc}
    */
   public function testRelated() {
-    $this->markTestSkipped('Remove this in https://www.drupal.org/project/jsonapi/issues/2940339');
+    $this->markTestSkipped('Remove this in https://www.drupal.org/project/drupal/issues/2940339');
   }
 
   /**
diff --git a/web/core/modules/jsonapi/tests/src/Functional/NodeTest.php b/web/core/modules/jsonapi/tests/src/Functional/NodeTest.php
index 266e220023..76c198a0ad 100644
--- a/web/core/modules/jsonapi/tests/src/Functional/NodeTest.php
+++ b/web/core/modules/jsonapi/tests/src/Functional/NodeTest.php
@@ -271,7 +271,7 @@ public function testPatchPath() {
     $this->setUpAuthorization('PATCH');
     $this->config('jsonapi.settings')->set('read_only', FALSE)->save(TRUE);
 
-    // @todo Remove line below in favor of commented line in https://www.drupal.org/project/jsonapi/issues/2878463.
+    // @todo Remove line below in favor of commented line in https://www.drupal.org/project/drupal/issues/2878463.
     $url = Url::fromRoute(sprintf('jsonapi.%s.individual', static::$resourceTypeName), ['entity' => $this->entity->uuid()]);
     // $url = $this->entity->toUrl('jsonapi');
 
@@ -311,14 +311,14 @@ public function testGetIndividual() {
     // Unpublish node.
     $this->entity->setUnpublished()->save();
 
-    // @todo Remove line below in favor of commented line in https://www.drupal.org/project/jsonapi/issues/2878463.
+    // @todo Remove line below in favor of commented line in https://www.drupal.org/project/drupal/issues/2878463.
     $url = Url::fromRoute(sprintf('jsonapi.%s.individual', static::$resourceTypeName), ['entity' => $this->entity->uuid()]);
     // $url = $this->entity->toUrl('jsonapi');
     $request_options = $this->getAuthenticationRequestOptions();
 
     // 403 when accessing own unpublished node.
     $response = $this->request('GET', $url, $request_options);
-    // @todo Remove $expected + assertResourceResponse() in favor of the commented line below once https://www.drupal.org/project/jsonapi/issues/2943176 lands.
+    // @todo Remove $expected + assertResourceResponse() in favor of the commented line below once https://www.drupal.org/project/drupal/issues/2943176 lands.
     $expected_document = [
       'jsonapi' => static::$jsonApiMember,
       'errors' => [
@@ -374,7 +374,7 @@ protected function assertCacheableNormalizations() {
     ]);
     // After saving the entity the normalization should not be cached.
     $this->assertFalse($cache);
-    // @todo Remove line below in favor of commented line in https://www.drupal.org/project/jsonapi/issues/2878463.
+    // @todo Remove line below in favor of commented line in https://www.drupal.org/project/drupal/issues/2878463.
     $url = Url::fromRoute(sprintf('jsonapi.%s.individual', static::$resourceTypeName), ['entity' => $uuid]);
     // $url = $this->entity->toUrl('jsonapi');
     $request_options = $this->getAuthenticationRequestOptions();
diff --git a/web/core/modules/jsonapi/tests/src/Functional/ResourceTestBase.php b/web/core/modules/jsonapi/tests/src/Functional/ResourceTestBase.php
index c38211d813..1a01ff22a1 100644
--- a/web/core/modules/jsonapi/tests/src/Functional/ResourceTestBase.php
+++ b/web/core/modules/jsonapi/tests/src/Functional/ResourceTestBase.php
@@ -906,7 +906,7 @@ public function testGetIndividual() {
     // - to first test all mistakes a developer might make, and assert that the
     //   error responses provide a good DX
     // - to eventually result in a well-formed request that succeeds.
-    // @todo Remove line below in favor of commented line in https://www.drupal.org/project/jsonapi/issues/2878463.
+    // @todo Remove line below in favor of commented line in https://www.drupal.org/project/drupal/issues/2878463.
     $url = Url::fromRoute(sprintf('jsonapi.%s.individual', static::$resourceTypeName), ['entity' => $this->entity->uuid()]);
     // $url = $this->entity->toUrl('jsonapi');
     $request_options = [];
@@ -975,9 +975,10 @@ public function testGetIndividual() {
     // contain a flattened response. Otherwise performance suffers.
     // @see \Drupal\jsonapi\EventSubscriber\ResourceResponseSubscriber::flattenResponse()
     $cache_items = $this->container->get('database')
-      ->query("SELECT cid, data FROM {cache_dynamic_page_cache} WHERE cid LIKE :pattern", [
-        ':pattern' => '%[route]=jsonapi.%',
-      ])
+      ->select('cache_dynamic_page_cache', 'cdp')
+      ->fields('cdp', ['cid', 'data'])
+      ->condition('cid', '%[route]=jsonapi.%', 'LIKE')
+      ->execute()
       ->fetchAllAssoc('cid');
     $this->assertTrue(count($cache_items) >= 2);
     $found_cache_redirect = FALSE;
@@ -1985,7 +1986,7 @@ public function testPostIndividual() {
     if (get_class($this->entityStorage) !== ContentEntityNullStorage::class) {
       $created_entity = $this->entityLoadUnchanged(static::$firstCreatedEntityId);
       $uuid = $created_entity->uuid();
-      // @todo Remove line below in favor of commented line in https://www.drupal.org/project/jsonapi/issues/2878463.
+      // @todo Remove line below in favor of commented line in https://www.drupal.org/project/drupal/issues/2878463.
       $location = Url::fromRoute(sprintf('jsonapi.%s.individual', static::$resourceTypeName), ['entity' => $uuid]);
       if (static::$resourceTypeIsVersionable) {
         assert($created_entity instanceof RevisionableInterface);
@@ -2037,7 +2038,7 @@ public function testPostIndividual() {
     if ($this->entity->getEntityType()->getStorageClass() !== ContentEntityNullStorage::class && $this->entity->getEntityType()->hasKey('uuid')) {
       $second_created_entity = $this->entityStorage->load(static::$secondCreatedEntityId);
       $uuid = $second_created_entity->uuid();
-      // @todo Remove line below in favor of commented line in https://www.drupal.org/project/jsonapi/issues/2878463.
+      // @todo Remove line below in favor of commented line in https://www.drupal.org/project/drupal/issues/2878463.
       $location = Url::fromRoute(sprintf('jsonapi.%s.individual', static::$resourceTypeName), ['entity' => $uuid]);
       /* $location = $this->entityStorage->load(static::$secondCreatedEntityId)->toUrl('jsonapi')->setAbsolute(TRUE)->toString(); */
       if (static::$resourceTypeIsVersionable) {
@@ -2117,7 +2118,7 @@ public function testPatchIndividual() {
     // - to first test all mistakes a developer might make, and assert that the
     //   error responses provide a good DX
     // - to eventually result in a well-formed request that succeeds.
-    // @todo Remove line below in favor of commented line in https://www.drupal.org/project/jsonapi/issues/2878463.
+    // @todo Remove line below in favor of commented line in https://www.drupal.org/project/drupal/issues/2878463.
     $url = Url::fromRoute(sprintf('jsonapi.%s.individual', static::$resourceTypeName), ['entity' => $this->entity->uuid()]);
     // $url = $this->entity->toUrl('jsonapi');
     $request_options = [];
@@ -2370,7 +2371,7 @@ public function testPatchIndividual() {
     $updated_entity->setNewRevision();
     $updated_entity->save();
     $actual_response = $this->request('PATCH', $url, $request_options);
-    $this->assertResourceErrorResponse(400, 'Updating a resource object that has a working copy is not yet supported. See https://www.drupal.org/project/jsonapi/issues/2795279.', $url, $actual_response);
+    $this->assertResourceErrorResponse(400, 'Updating a resource object that has a working copy is not yet supported. See https://www.drupal.org/project/drupal/issues/2795279.', $url, $actual_response);
 
     // Allow PATCHing an unpublished default revision.
     $updated_entity->set('moderation_state', 'archived');
@@ -2411,7 +2412,7 @@ public function testDeleteIndividual() {
     // - to first test all mistakes a developer might make, and assert that the
     //   error responses provide a good DX
     // - to eventually result in a well-formed request that succeeds.
-    // @todo Remove line below in favor of commented line in https://www.drupal.org/project/jsonapi/issues/2878463.
+    // @todo Remove line below in favor of commented line in https://www.drupal.org/project/drupal/issues/2878463.
     $url = Url::fromRoute(sprintf('jsonapi.%s.individual', static::$resourceTypeName), ['entity' => $this->entity->uuid()]);
     // $url = $this->entity->toUrl('jsonapi');
     $request_options = [];
@@ -2694,7 +2695,7 @@ public function testRevisions() {
       $request_options = NestedArray::mergeDeep($request_options, $this->getAuthenticationRequestOptions());
       $response = $this->request('GET', $url, $request_options);
       $detail = 'JSON:API does not yet support resource versioning for this resource type.';
-      $detail .= ' For context, see https://www.drupal.org/project/jsonapi/issues/2992833#comment-12818258.';
+      $detail .= ' For context, see https://www.drupal.org/project/drupal/issues/2992833#comment-12818258.';
       $detail .= ' To contribute, see https://www.drupal.org/project/drupal/issues/2350939 and https://www.drupal.org/project/drupal/issues/2809177.';
       $expected_cache_contexts = [
         'url.path',
@@ -2731,7 +2732,7 @@ public function testRevisions() {
     $entity->save();
     $latest_revision_id = (int) $entity->getRevisionId();
 
-    // @todo Remove line below in favor of commented line in https://www.drupal.org/project/jsonapi/issues/2878463.
+    // @todo Remove line below in favor of commented line in https://www.drupal.org/project/drupal/issues/2878463.
     $url = Url::fromRoute(sprintf('jsonapi.%s.individual', static::$resourceTypeName), ['entity' => $this->entity->uuid()])->setAbsolute();
     // $url = $this->entity->toUrl('jsonapi');
     $collection_url = Url::fromRoute(sprintf('jsonapi.%s.collection', static::$resourceTypeName))->setAbsolute();
diff --git a/web/core/modules/jsonapi/tests/src/Functional/TermTest.php b/web/core/modules/jsonapi/tests/src/Functional/TermTest.php
index f5f20aeec2..94805ec51c 100644
--- a/web/core/modules/jsonapi/tests/src/Functional/TermTest.php
+++ b/web/core/modules/jsonapi/tests/src/Functional/TermTest.php
@@ -372,7 +372,7 @@ public function testPatchPath() {
     $this->setUpAuthorization('PATCH');
     $this->config('jsonapi.settings')->set('read_only', FALSE)->save(TRUE);
 
-    // @todo Remove line below in favor of commented line in https://www.drupal.org/project/jsonapi/issues/2878463.
+    // @todo Remove line below in favor of commented line in https://www.drupal.org/project/drupal/issues/2878463.
     $url = Url::fromRoute(sprintf('jsonapi.%s.individual', static::$resourceTypeName), ['entity' => $this->entity->uuid()]);
     // $url = $this->entity->toUrl('jsonapi');
     $request_options = [];
@@ -438,7 +438,7 @@ public function testGetIndividualTermWithParent(array $parent_term_ids) {
     // Modify the entity under test to use the provided parent terms.
     $this->entity->set('parent', $parent_term_ids)->save();
 
-    // @todo Remove line below in favor of commented line in https://www.drupal.org/project/jsonapi/issues/2878463.
+    // @todo Remove line below in favor of commented line in https://www.drupal.org/project/drupal/issues/2878463.
     $url = Url::fromRoute(sprintf('jsonapi.%s.individual', static::$resourceTypeName), ['entity' => $this->entity->uuid()]);
     // $url = $this->entity->toUrl('jsonapi');
     $request_options = [];
@@ -473,7 +473,7 @@ public function providerTestGetIndividualTermWithParent() {
    * {@inheritdoc}
    */
   public function testRelated() {
-    $this->markTestSkipped('Remove this in https://www.drupal.org/project/jsonapi/issues/2940339');
+    $this->markTestSkipped('Remove this in https://www.drupal.org/project/drupal/issues/2940339');
   }
 
   /**
diff --git a/web/core/modules/jsonapi/tests/src/Functional/Update/ReadOnlyModeUpdateTest.php b/web/core/modules/jsonapi/tests/src/Functional/Update/ReadOnlyModeUpdateTest.php
index dabc0df37e..c48dd28d4b 100644
--- a/web/core/modules/jsonapi/tests/src/Functional/Update/ReadOnlyModeUpdateTest.php
+++ b/web/core/modules/jsonapi/tests/src/Functional/Update/ReadOnlyModeUpdateTest.php
@@ -8,7 +8,7 @@
  * Tests that existing sites have the new read-only mode to "off".
  *
  * @see jsonapi_update_8701()
- * @see https://www.drupal.org/project/jsonapi/issues/3039568
+ * @see https://www.drupal.org/project/drupal/issues/3039568
  *
  * @group jsonapi
  * @group Update
diff --git a/web/core/modules/jsonapi/tests/src/Functional/UserTest.php b/web/core/modules/jsonapi/tests/src/Functional/UserTest.php
index f4ce93f2aa..98a1815588 100644
--- a/web/core/modules/jsonapi/tests/src/Functional/UserTest.php
+++ b/web/core/modules/jsonapi/tests/src/Functional/UserTest.php
@@ -203,7 +203,7 @@ protected function getExpectedUnauthorizedAccessMessage($method) {
    * Tests PATCHing security-sensitive base fields of the logged in account.
    */
   public function testPatchDxForSecuritySensitiveBaseFields() {
-    // @todo Remove line below in favor of commented line in https://www.drupal.org/project/jsonapi/issues/2878463.
+    // @todo Remove line below in favor of commented line in https://www.drupal.org/project/drupal/issues/2878463.
     $url = Url::fromRoute(sprintf('jsonapi.user--user.individual'), ['entity' => $this->account->uuid()]);
     /* $url = $this->account->toUrl('jsonapi'); */
 
@@ -321,7 +321,7 @@ protected function assertRpcLogin($username, $password) {
    * Tests PATCHing security-sensitive base fields to change other users.
    */
   public function testPatchSecurityOtherUser() {
-    // @todo Remove line below in favor of commented line in https://www.drupal.org/project/jsonapi/issues/2878463.
+    // @todo Remove line below in favor of commented line in https://www.drupal.org/project/drupal/issues/2878463.
     $url = Url::fromRoute(sprintf('jsonapi.user--user.individual'), ['entity' => $this->account->uuid()]);
     /* $url = $this->account->toUrl('jsonapi'); */
 
@@ -379,7 +379,7 @@ public function testGetMailFieldOnlyVisibleToOwner() {
     $this->grantPermissionsToTestedRole(['access user profiles']);
 
     $collection_url = Url::fromRoute('jsonapi.user--user.collection', [], ['query' => ['sort' => 'drupal_internal__uid']]);
-    // @todo Remove line below in favor of commented line in https://www.drupal.org/project/jsonapi/issues/2878463.
+    // @todo Remove line below in favor of commented line in https://www.drupal.org/project/drupal/issues/2878463.
     $user_a_url = Url::fromRoute(sprintf('jsonapi.user--user.individual'), ['entity' => $user_a->uuid()]);
     /* $user_a_url = $user_a->toUrl('jsonapi'); */
     $request_options = [];
diff --git a/web/core/modules/jsonapi/tests/src/Kernel/Normalizer/JsonApiDocumentTopLevelNormalizerTest.php b/web/core/modules/jsonapi/tests/src/Kernel/Normalizer/JsonApiDocumentTopLevelNormalizerTest.php
index 0d2f093f01..6c97b71683 100644
--- a/web/core/modules/jsonapi/tests/src/Kernel/Normalizer/JsonApiDocumentTopLevelNormalizerTest.php
+++ b/web/core/modules/jsonapi/tests/src/Kernel/Normalizer/JsonApiDocumentTopLevelNormalizerTest.php
@@ -302,7 +302,7 @@ public function testNormalize() {
    * @covers ::normalize
    */
   public function testNormalizeRelated() {
-    $this->markTestIncomplete('This fails and should be fixed by https://www.drupal.org/project/jsonapi/issues/2922121');
+    $this->markTestIncomplete('This fails and should be fixed by https://www.drupal.org/project/drupal/issues/2922121');
 
     list($request, $resource_type) = $this->generateProphecies('node', 'article', 'uid');
     $request->query = new ParameterBag([
diff --git a/web/core/modules/jsonapi/tests/src/Kernel/Query/FilterTest.php b/web/core/modules/jsonapi/tests/src/Kernel/Query/FilterTest.php
index f8ecc22355..afe8ee6a69 100644
--- a/web/core/modules/jsonapi/tests/src/Kernel/Query/FilterTest.php
+++ b/web/core/modules/jsonapi/tests/src/Kernel/Query/FilterTest.php
@@ -413,7 +413,7 @@ public function testCreateFromQueryParameterNested() {
    */
   protected function getFieldResolverMock(ResourceType $resource_type) {
     $field_resolver = $this->prophesize(FieldResolver::class);
-    $field_resolver->resolveInternalEntityQueryPath($resource_type, Argument::any())->willReturnArgument(1);
+    $field_resolver->resolveInternalEntityQueryPath($resource_type, Argument::any(), Argument::any())->willReturnArgument(1);
     return $field_resolver->reveal();
   }
 
diff --git a/web/core/modules/locale/tests/src/Functional/LocaleImportFunctionalTest.php b/web/core/modules/locale/tests/src/Functional/LocaleImportFunctionalTest.php
index 526db97c0a..5575cad6d5 100644
--- a/web/core/modules/locale/tests/src/Functional/LocaleImportFunctionalTest.php
+++ b/web/core/modules/locale/tests/src/Functional/LocaleImportFunctionalTest.php
@@ -202,7 +202,11 @@ public function testStandalonePoFile() {
 
     // The database should now contain 6 customized strings (two imported
     // strings are not translated).
-    $count = Database::getConnection()->query('SELECT COUNT(*) FROM {locales_target} WHERE customized = :custom', [':custom' => 1])->fetchField();
+    $count = Database::getConnection()->select('locales_target')
+      ->condition('customized', 1)
+      ->countQuery()
+      ->execute()
+      ->fetchField();
     $this->assertEqual($count, 6, 'Customized translations successfully imported.');
 
     // Try importing a .po file with overriding strings, and ensure existing
diff --git a/web/core/modules/locale/tests/src/Functional/LocalePluralFormatTest.php b/web/core/modules/locale/tests/src/Functional/LocalePluralFormatTest.php
index 552273cfa7..54b442b8ec 100644
--- a/web/core/modules/locale/tests/src/Functional/LocalePluralFormatTest.php
+++ b/web/core/modules/locale/tests/src/Functional/LocalePluralFormatTest.php
@@ -197,7 +197,12 @@ public function testPluralEditDateFormatter() {
     // not save our source string for performance optimization if we do not ask
     // specifically for a language.
     \Drupal::translation()->formatPlural(1, '1 second', '@count seconds', [], ['langcode' => 'fr'])->render();
-    $lid = Database::getConnection()->query("SELECT lid FROM {locales_source} WHERE source = :source AND context = ''", [':source' => "1 second" . PoItem::DELIMITER . "@count seconds"])->fetchField();
+    $lid = Database::getConnection()->select('locales_source', 'ls')
+      ->fields('ls', ['lid'])
+      ->condition('source', "1 second" . PoItem::DELIMITER . "@count seconds")
+      ->condition('context', '')
+      ->execute()
+      ->fetchField();
     // Look up editing page for this plural string and check fields.
     $search = [
       'string' => '1 second',
@@ -282,7 +287,12 @@ public function testPluralEditExport() {
 
     $connection = Database::getConnection();
     // Edit langcode hr translations and see if that took effect.
-    $lid = $connection->query("SELECT lid FROM {locales_source} WHERE source = :source AND context = ''", [':source' => "1 hour" . PoItem::DELIMITER . "@count hours"])->fetchField();
+    $lid = $connection->select('locales_source', 'ls')
+      ->fields('ls', ['lid'])
+      ->condition('source', "1 hour" . PoItem::DELIMITER . "@count hours")
+      ->condition('context', '')
+      ->execute()
+      ->fetchField();
     $edit = [
       "strings[$lid][translations][1]" => '@count sata edited',
     ];
@@ -308,7 +318,12 @@ public function testPluralEditExport() {
     // not save our source string for performance optimization if we do not ask
     // specifically for a language.
     \Drupal::translation()->formatPlural(1, '1 day', '@count days', [], ['langcode' => 'fr'])->render();
-    $lid = $connection->query("SELECT lid FROM {locales_source} WHERE source = :source AND context = ''", [':source' => "1 day" . PoItem::DELIMITER . "@count days"])->fetchField();
+    $lid = $connection->select('locales_source', 'ls')
+      ->fields('ls', ['lid'])
+      ->condition('source', "1 day" . PoItem::DELIMITER . "@count days")
+      ->condition('context', '')
+      ->execute()
+      ->fetchField();
     // Look up editing page for this plural string and check fields.
     $search = [
       'string' => '1 day',
diff --git a/web/core/modules/locale/tests/src/Functional/LocaleUpdateBase.php b/web/core/modules/locale/tests/src/Functional/LocaleUpdateBase.php
index 2e2d82b633..5a42977975 100644
--- a/web/core/modules/locale/tests/src/Functional/LocaleUpdateBase.php
+++ b/web/core/modules/locale/tests/src/Functional/LocaleUpdateBase.php
@@ -301,7 +301,13 @@ protected function setCurrentTranslations() {
    *   (optional) A message to display with the assertion.
    */
   protected function assertTranslation($source, $translation, $langcode, $message = '') {
-    $db_translation = Database::getConnection()->query('SELECT translation FROM {locales_target} lt INNER JOIN {locales_source} ls ON ls.lid = lt.lid WHERE ls.source = :source AND lt.language = :langcode', [':source' => $source, ':langcode' => $langcode])->fetchField();
+    $query = Database::getConnection()->select('locales_target', 'lt');
+    $query->innerJoin('locales_source', 'ls', 'ls.lid = lt.lid');
+    $db_translation = $query->fields('lt', ['translation'])
+      ->condition('ls.source', $source)
+      ->condition('lt.language', $langcode)
+      ->execute()
+      ->fetchField();
     $db_translation = $db_translation == FALSE ? '' : $db_translation;
     $this->assertEqual($translation, $db_translation, $message ? $message : new FormattableMarkup('Correct translation of %source (%language)', ['%source' => $source, '%language' => $langcode]));
   }
diff --git a/web/core/modules/locale/tests/src/Functional/LocaleUpdateTest.php b/web/core/modules/locale/tests/src/Functional/LocaleUpdateTest.php
index d1b12c17f4..366667a6cc 100644
--- a/web/core/modules/locale/tests/src/Functional/LocaleUpdateTest.php
+++ b/web/core/modules/locale/tests/src/Functional/LocaleUpdateTest.php
@@ -359,14 +359,22 @@ public function testEnableLanguage() {
 
     // Check if the language data is added to the database.
     $connection = Database::getConnection();
-    $result = $connection->query("SELECT project FROM {locale_file} WHERE langcode='nl'")->fetchField();
+    $result = $connection->select('locale_file', 'lf')
+      ->fields('lf', ['project'])
+      ->condition('langcode', 'nl')
+      ->execute()
+      ->fetchField();
     $this->assertNotEmpty($result, 'Files added to file history');
 
     // Remove a language.
     $this->drupalPostForm('admin/config/regional/language/delete/nl', [], t('Delete'));
 
     // Check if the language data is removed from the database.
-    $result = $connection->query("SELECT project FROM {locale_file} WHERE langcode='nl'")->fetchField();
+    $result = $connection->select('locale_file', 'lf')
+      ->fields('lf', ['project'])
+      ->condition('langcode', 'nl')
+      ->execute()
+      ->fetchField();
     $this->assertFalse($result, 'Files removed from file history');
 
     // Check that the Dutch translation is gone.
diff --git a/web/core/modules/migrate_drupal/tests/fixtures/drupal6.php b/web/core/modules/migrate_drupal/tests/fixtures/drupal6.php
index a6e4ab7610..28a47bfa2c 100644
--- a/web/core/modules/migrate_drupal/tests/fixtures/drupal6.php
+++ b/web/core/modules/migrate_drupal/tests/fixtures/drupal6.php
@@ -2274,6 +2274,20 @@
   'field_image_list' => '1',
   'field_image_data' => 'a:2:{s:3:"alt";s:0:"";s:5:"title";s:0:"";}',
 ))
+->values(array(
+  'vid' => '5',
+  'nid' => '1',
+  'field_image_fid' => '2',
+  'field_image_list' => '1',
+  'field_image_data' => 'a:2:{s:3:"alt";s:0:"";s:5:"title";s:0:"";}',
+))
+->values(array(
+  'vid' => '2001',
+  'nid' => '1',
+  'field_image_fid' => '2',
+  'field_image_list' => '1',
+  'field_image_data' => 'a:2:{s:3:"alt";s:0:"";s:5:"title";s:0:"";}',
+))
 ->execute();
 $connection->schema()->createTable('content_field_multivalue', array(
   'fields' => array(
@@ -2389,12 +2403,6 @@
   'field_test_value' => 'This is a shared text field',
   'field_test_format' => '1',
 ))
-->values(array(
-  'vid' => '2',
-  'nid' => '1',
-  'field_test_value' => 'This is a shared text field',
-  'field_test_format' => '1',
-))
 ->values(array(
   'vid' => '3',
   'nid' => '2',
@@ -2403,9 +2411,9 @@
 ))
 ->values(array(
   'vid' => '5',
-  'nid' => '2',
-  'field_test_value' => NULL,
-  'field_test_format' => NULL,
+  'nid' => '1',
+  'field_test_value' => 'This is a shared text field',
+  'field_test_format' => '1',
 ))
 ->values(array(
   'vid' => '12',
@@ -2413,6 +2421,12 @@
   'field_test_value' => 'text for default value',
   'field_test_format' => '1',
 ))
+->values(array(
+  'vid' => '2001',
+  'nid' => '1',
+  'field_test_value' => 'This is a shared text field',
+  'field_test_format' => '1',
+))
 ->execute();
 $connection->schema()->createTable('content_field_test_text_single_checkbox', array(
   'fields' => array(
@@ -2470,14 +2484,19 @@
 ))
 ->values(array(
   'vid' => '5',
-  'nid' => '2',
-  'field_test_text_single_checkbox_value' => NULL,
+  'nid' => '1',
+  'field_test_text_single_checkbox_value' => '0',
 ))
 ->values(array(
   'vid' => '12',
   'nid' => '9',
   'field_test_text_single_checkbox_value' => '0',
 ))
+->values(array(
+  'vid' => '2001',
+  'nid' => '1',
+  'field_test_text_single_checkbox_value' => '0',
+))
 ->execute();
 $connection->schema()->createTable('content_field_test_two', array(
   'fields' => array(
@@ -2534,10 +2553,10 @@
   'field_test_two_value' => '10',
 ))
 ->values(array(
-  'vid' => '2',
+  'vid' => '1',
   'nid' => '1',
-  'delta' => '0',
-  'field_test_two_value' => NULL,
+  'delta' => '1',
+  'field_test_two_value' => '20',
 ))
 ->values(array(
   'vid' => '3',
@@ -2547,9 +2566,15 @@
 ))
 ->values(array(
   'vid' => '5',
-  'nid' => '2',
+  'nid' => '1',
   'delta' => '0',
-  'field_test_two_value' => NULL,
+  'field_test_two_value' => '10',
+))
+->values(array(
+  'vid' => '5',
+  'nid' => '1',
+  'delta' => '1',
+  'field_test_two_value' => '20',
 ))
 ->values(array(
   'vid' => '12',
@@ -2558,7 +2583,13 @@
   'field_test_two_value' => NULL,
 ))
 ->values(array(
-  'vid' => '1',
+  'vid' => '2001',
+  'nid' => '1',
+  'delta' => '0',
+  'field_test_two_value' => '10',
+))
+->values(array(
+  'vid' => '2001',
   'nid' => '1',
   'delta' => '1',
   'field_test_two_value' => '20',
@@ -3939,38 +3970,6 @@
   'field_test_datetime_value2' => NULL,
   'field_test_string_selectlist_value' => NULL,
 ))
-->values(array(
-  'nid' => '1',
-  'vid' => '2',
-  'uid' => '1',
-  'field_test_three_value' => '42.42',
-  'field_test_identical1_value' => '1',
-  'field_test_identical2_value' => '1',
-  'field_test_link_url' => 'https://www.drupal.org/project/drupal',
-  'field_test_link_title' => 'Drupal project page',
-  'field_test_link_attributes' => 's:32:"a:1:{s:6:"target";s:6:"_blank";}";',
-  'field_test_date_value' => '2013-01-02T04:05:00',
-  'field_test_datestamp_value' => '1391357160',
-  'field_test_datetime_value' => '2015-03-04 06:07:00',
-  'field_test_email_email' => 'PrincessRuwenne@example.com',
-  'field_test_filefield_fid' => NULL,
-  'field_test_filefield_list' => NULL,
-  'field_test_filefield_data' => NULL,
-  'field_test_four_value' => NULL,
-  'field_test_integer_selectlist_value' => NULL,
-  'field_test_float_single_checkbox_value' => NULL,
-  'field_test_decimal_radio_buttons_value' => NULL,
-  'field_test_phone_value' => NULL,
-  'field_test_exclude_unset_value' => NULL,
-  'field_test_exclude_unset_format' => NULL,
-  'field_test_imagefield_fid' => NULL,
-  'field_test_imagefield_list' => NULL,
-  'field_test_imagefield_data' => NULL,
-  'field_test_text_single_checkbox2_value' => NULL,
-  'field_test_datestamp_value2' => NULL,
-  'field_test_datetime_value2' => NULL,
-  'field_test_string_selectlist_value' => NULL,
-))
 ->values(array(
   'nid' => '2',
   'vid' => '3',
@@ -4004,33 +4003,33 @@
   'field_test_string_selectlist_value' => NULL,
 ))
 ->values(array(
-  'nid' => '2',
+  'nid' => '1',
   'vid' => '5',
   'uid' => '1',
-  'field_test_three_value' => '23.20',
+  'field_test_three_value' => '42.42',
   'field_test_identical1_value' => '1',
   'field_test_identical2_value' => '1',
-  'field_test_link_url' => 'http://groups.drupal.org/',
-  'field_test_link_title' => 'Drupal Groups',
-  'field_test_link_attributes' => 's:6:"a:0:{}";',
-  'field_test_date_value' => NULL,
-  'field_test_datestamp_value' => NULL,
-  'field_test_datetime_value' => NULL,
-  'field_test_email_email' => NULL,
-  'field_test_filefield_fid' => NULL,
-  'field_test_filefield_list' => NULL,
-  'field_test_filefield_data' => NULL,
+  'field_test_link_url' => 'https://www.drupal.org/project/drupal',
+  'field_test_link_title' => 'Drupal project page',
+  'field_test_link_attributes' => 's:32:"a:1:{s:6:"target";s:6:"_blank";}";',
+  'field_test_date_value' => '2013-01-02T04:05:00',
+  'field_test_datestamp_value' => '1391357160',
+  'field_test_datetime_value' => '2015-03-04 06:07:00',
+  'field_test_email_email' => 'PrincessRuwenne@example.com',
+  'field_test_filefield_fid' => '5',
+  'field_test_filefield_list' => '1',
+  'field_test_filefield_data' => 'a:1:{s:11:"description";s:4:"desc";}',
   'field_test_four_value' => NULL,
-  'field_test_integer_selectlist_value' => NULL,
-  'field_test_float_single_checkbox_value' => NULL,
+  'field_test_integer_selectlist_value' => '3412',
+  'field_test_float_single_checkbox_value' => '3',
   'field_test_decimal_radio_buttons_value' => NULL,
   'field_test_phone_value' => NULL,
-  'field_test_exclude_unset_value' => NULL,
-  'field_test_exclude_unset_format' => NULL,
+  'field_test_exclude_unset_value' => 'This is a field with exclude unset.',
+  'field_test_exclude_unset_format' => '1',
   'field_test_imagefield_fid' => NULL,
   'field_test_imagefield_list' => NULL,
   'field_test_imagefield_data' => NULL,
-  'field_test_text_single_checkbox2_value' => NULL,
+  'field_test_text_single_checkbox2_value' => 'Hello',
   'field_test_datestamp_value2' => NULL,
   'field_test_datetime_value2' => NULL,
   'field_test_string_selectlist_value' => NULL,
@@ -4067,6 +4066,38 @@
   'field_test_datetime_value2' => '2015-03-04 06:07:00',
   'field_test_string_selectlist_value' => NULL,
 ))
+->values(array(
+  'nid' => '1',
+  'vid' => '2001',
+  'uid' => '1',
+  'field_test_three_value' => '42.42',
+  'field_test_identical1_value' => '1',
+  'field_test_identical2_value' => '1',
+  'field_test_link_url' => 'https://www.drupal.org/project/drupal',
+  'field_test_link_title' => 'Drupal project page',
+  'field_test_link_attributes' => 's:32:"a:1:{s:6:"target";s:6:"_blank";}";',
+  'field_test_date_value' => '2013-01-02T04:05:00',
+  'field_test_datestamp_value' => '1391357160',
+  'field_test_datetime_value' => '2015-03-04 06:07:00',
+  'field_test_email_email' => 'PrincessRuwenne@example.com',
+  'field_test_filefield_fid' => '5',
+  'field_test_filefield_list' => '1',
+  'field_test_filefield_data' => 'a:1:{s:11:"description";s:4:"desc";}',
+  'field_test_four_value' => NULL,
+  'field_test_integer_selectlist_value' => '3412',
+  'field_test_float_single_checkbox_value' => '3',
+  'field_test_decimal_radio_buttons_value' => NULL,
+  'field_test_phone_value' => NULL,
+  'field_test_exclude_unset_value' => 'This is a field with exclude unset.',
+  'field_test_exclude_unset_format' => '1',
+  'field_test_imagefield_fid' => NULL,
+  'field_test_imagefield_list' => NULL,
+  'field_test_imagefield_data' => NULL,
+  'field_test_text_single_checkbox2_value' => 'Hello',
+  'field_test_datestamp_value2' => NULL,
+  'field_test_datetime_value2' => NULL,
+  'field_test_string_selectlist_value' => NULL,
+))
 ->execute();
 $connection->schema()->createTable('content_type_test_page', array(
   'fields' => array(
@@ -44470,7 +44501,7 @@
 ))
 ->values(array(
   'nid' => '1',
-  'vid' => '1',
+  'vid' => '2001',
   'type' => 'story',
   'language' => '',
   'title' => 'Test title rev 3',
@@ -48083,6 +48114,16 @@
   'vid' => '3',
   'tid' => '3',
 ))
+->values(array(
+  'nid' => '1',
+  'vid' => '2001',
+  'tid' => '1',
+))
+->values(array(
+  'nid' => '1',
+  'vid' => '2001',
+  'tid' => '2',
+))
 ->values(array(
   'nid' => '1',
   'vid' => '2001',
@@ -48283,6 +48324,14 @@
   'list' => '0',
   'weight' => '1',
 ))
+->values(array(
+  'fid' => '1',
+  'nid' => '1',
+  'vid' => '5',
+  'description' => 'file 1-1-1',
+  'list' => '0',
+  'weight' => '-1',
+))
 ->values(array(
   'fid' => '3',
   'nid' => '12',
@@ -48291,6 +48340,14 @@
   'list' => '0',
   'weight' => '0',
 ))
+->values(array(
+  'fid' => '1',
+  'nid' => '1',
+  'vid' => '2001',
+  'description' => 'file 1-1-1',
+  'list' => '0',
+  'weight' => '-1',
+))
 ->execute();
 $connection->schema()->createTable('url_alias', array(
   'fields' => array(
diff --git a/web/core/modules/node/tests/src/Functional/NodeCreationTest.php b/web/core/modules/node/tests/src/Functional/NodeCreationTest.php
index faef2af13b..161e8df6ef 100644
--- a/web/core/modules/node/tests/src/Functional/NodeCreationTest.php
+++ b/web/core/modules/node/tests/src/Functional/NodeCreationTest.php
@@ -294,7 +294,9 @@ protected static function getWatchdogIdsForTestExceptionRollback() {
     // PostgreSQL doesn't support bytea LIKE queries, so we need to unserialize
     // first to check for the rollback exception message.
     $matches = [];
-    $query = Database::getConnection()->query("SELECT wid, variables FROM {watchdog}");
+    $query = Database::getConnection()->select('watchdog', 'w')
+      ->fields('w', ['wid', 'variables'])
+      ->execute();
     foreach ($query as $row) {
       $variables = (array) unserialize($row->variables);
       if (isset($variables['@message']) && $variables['@message'] === 'Test exception for rollback.') {
diff --git a/web/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeTest.php b/web/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeTest.php
index 1e951d0e47..5f64bf6e90 100644
--- a/web/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeTest.php
+++ b/web/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeTest.php
@@ -52,24 +52,24 @@ public function testNode() {
     $node = Node::load(1);
     $this->assertIdentical('1', $node->id(), 'Node 1 loaded.');
     $this->assertIdentical('und', $node->langcode->value);
-    $this->assertIdentical('test', $node->body->value);
-    $this->assertIdentical('test', $node->body->summary);
+    $this->assertIdentical('body test rev 3', $node->body->value);
+    $this->assertIdentical('teaser test rev 3', $node->body->summary);
     $this->assertIdentical('filtered_html', $node->body->format);
     $this->assertIdentical('story', $node->getType(), 'Node has the correct bundle.');
-    $this->assertIdentical('Test title', $node->getTitle(), 'Node has the correct title.');
+    $this->assertIdentical('Test title rev 3', $node->getTitle(), 'Node has the correct title.');
     $this->assertIdentical('1390095702', $node->getCreatedTime(), 'Node has the correct created time.');
     $this->assertIdentical(FALSE, $node->isSticky());
     $this->assertIdentical('1', $node->getOwnerId());
-    $this->assertIdentical('1390095702', $node->getRevisionCreationTime());
+    $this->assertIdentical('1420861423', $node->getRevisionCreationTime());
 
     /** @var \Drupal\node\NodeInterface $node_revision */
-    $node_revision = \Drupal::entityTypeManager()->getStorage('node')->loadRevision(1);
-    $this->assertIdentical('Test title', $node_revision->getTitle());
-    $this->assertIdentical('1', $node_revision->getRevisionUser()->id(), 'Node revision has the correct user');
+    $node_revision = \Drupal::entityTypeManager()->getStorage('node')->loadRevision(2001);
+    $this->assertIdentical('Test title rev 3', $node_revision->getTitle());
+    $this->assertIdentical('2', $node_revision->getRevisionUser()->id(), 'Node revision has the correct user');
     $this->assertSame('1', $node_revision->id(), 'Node 1 loaded.');
-    $this->assertSame('1', $node_revision->getRevisionId(), 'Node 1 revision 1 loaded.');
+    $this->assertSame('2001', $node_revision->getRevisionId(), 'Node 1 revision 2001 loaded.');
     // This is empty on the first revision.
-    $this->assertIdentical(NULL, $node_revision->revision_log->value);
+    $this->assertIdentical('modified rev 3', $node_revision->revision_log->value);
     $this->assertIdentical('This is a shared text field', $node->field_test->value);
     $this->assertIdentical('filtered_html', $node->field_test->format);
     $this->assertIdentical('10', $node->field_test_two->value);
diff --git a/web/core/modules/node/tests/src/Kernel/NodeAccessRecordsTest.php b/web/core/modules/node/tests/src/Kernel/NodeAccessRecordsTest.php
index a5a5d6ae53..bc36ae92ec 100644
--- a/web/core/modules/node/tests/src/Kernel/NodeAccessRecordsTest.php
+++ b/web/core/modules/node/tests/src/Kernel/NodeAccessRecordsTest.php
@@ -30,7 +30,11 @@ public function testNodeAccessRecords() {
 
     // Check to see if grants added by node_test_node_access_records made it in.
     $connection = Database::getConnection();
-    $records = $connection->query('SELECT realm, gid FROM {node_access} WHERE nid = :nid', [':nid' => $node1->id()])->fetchAll();
+    $records = $connection->select('node_access', 'na')
+      ->fields('na', ['realm', 'gid'])
+      ->condition('nid', $node1->id())
+      ->execute()
+      ->fetchAll();
     $this->assertCount(1, $records, 'Returned the correct number of rows.');
     $this->assertEqual($records[0]->realm, 'test_article_realm', 'Grant with article_realm acquired for node without alteration.');
     $this->assertEqual($records[0]->gid, 1, 'Grant with gid = 1 acquired for node without alteration.');
@@ -40,7 +44,11 @@ public function testNodeAccessRecords() {
     $this->assertNotEmpty(Node::load($node2->id()), 'Unpromoted basic page node created.');
 
     // Check to see if grants added by node_test_node_access_records made it in.
-    $records = $connection->query('SELECT realm, gid FROM {node_access} WHERE nid = :nid', [':nid' => $node2->id()])->fetchAll();
+    $records = $connection->select('node_access', 'na')
+      ->fields('na', ['realm', 'gid'])
+      ->condition('nid', $node2->id())
+      ->execute()
+      ->fetchAll();
     $this->assertCount(1, $records, 'Returned the correct number of rows.');
     $this->assertEqual($records[0]->realm, 'test_page_realm', 'Grant with page_realm acquired for node without alteration.');
     $this->assertEqual($records[0]->gid, 1, 'Grant with gid = 1 acquired for node without alteration.');
@@ -50,7 +58,11 @@ public function testNodeAccessRecords() {
     $this->assertNotEmpty(Node::load($node3->id()), 'Unpromoted, unpublished basic page node created.');
 
     // Check to see if grants added by node_test_node_access_records made it in.
-    $records = $connection->query('SELECT realm, gid FROM {node_access} WHERE nid = :nid', [':nid' => $node3->id()])->fetchAll();
+    $records = $connection->select('node_access', 'na')
+      ->fields('na', ['realm', 'gid'])
+      ->condition('nid', $node3->id())
+      ->execute()
+      ->fetchAll();
     $this->assertCount(1, $records, 'Returned the correct number of rows.');
     $this->assertEqual($records[0]->realm, 'test_page_realm', 'Grant with page_realm acquired for node without alteration.');
     $this->assertEqual($records[0]->gid, 1, 'Grant with gid = 1 acquired for node without alteration.');
@@ -61,7 +73,11 @@ public function testNodeAccessRecords() {
 
     // Check to see if grant added by node_test_node_access_records was altered
     // by node_test_node_access_records_alter.
-    $records = $connection->query('SELECT realm, gid FROM {node_access} WHERE nid = :nid', [':nid' => $node4->id()])->fetchAll();
+    $records = $connection->select('node_access', 'na')
+      ->fields('na', ['realm', 'gid'])
+      ->condition('nid', $node4->id())
+      ->execute()
+      ->fetchAll();
     $this->assertCount(1, $records, 'Returned the correct number of rows.');
     $this->assertEqual($records[0]->realm, 'test_alter_realm', 'Altered grant with alter_realm acquired for node.');
     $this->assertEqual($records[0]->gid, 2, 'Altered grant with gid = 2 acquired for node.');
@@ -80,7 +96,11 @@ public function testNodeAccessRecords() {
     // Check that core does not grant access to an unpublished node when an
     // empty $grants array is returned.
     $node6 = $this->drupalCreateNode(['status' => 0, 'disable_node_access' => TRUE]);
-    $records = $connection->query('SELECT realm, gid FROM {node_access} WHERE nid = :nid', [':nid' => $node6->id()])->fetchAll();
+    $records = $connection->select('node_access', 'na')
+      ->fields('na', ['realm', 'gid'])
+      ->condition('nid', $node6->id())
+      ->execute()
+      ->fetchAll();
     $this->assertCount(0, $records, 'Returned no records for unpublished node.');
   }
 
diff --git a/web/core/modules/rdf/rdf.module b/web/core/modules/rdf/rdf.module
index 92cc337fc1..cbd696e05d 100644
--- a/web/core/modules/rdf/rdf.module
+++ b/web/core/modules/rdf/rdf.module
@@ -237,12 +237,13 @@ function rdf_comment_storage_load($comments) {
       ->getPreparedFieldMapping('created');
     /** @var \Drupal\comment\CommentInterface $comment*/
     $comment->rdf_data['date'] = rdf_rdfa_attributes($created_mapping, $comment->get('created')->first()->toArray());
-    $entity = $comment->getCommentedEntity();
-    // The current function is a storage level hook, so avoid to bubble
-    // bubbleable metadata, because it can be outside of a render context.
-    $comment->rdf_data['entity_uri'] = $entity->toUrl()->toString(TRUE)->getGeneratedUrl();
-    if ($comment->hasParentComment()) {
-      $comment->rdf_data['pid_uri'] = $comment->getParentComment()->toUrl()->toString(TRUE)->getGeneratedUrl();
+    if ($entity = $comment->getCommentedEntity()) {
+      // The current function is a storage level hook, so avoid to bubble
+      // bubbleable metadata, because it can be outside of a render context.
+      $comment->rdf_data['entity_uri'] = $entity->toUrl()->toString(TRUE)->getGeneratedUrl();
+    }
+    if ($parent = $comment->getParentComment()) {
+      $comment->rdf_data['pid_uri'] = $parent->toUrl()->toString(TRUE)->getGeneratedUrl();
     }
   }
 }
diff --git a/web/core/modules/rdf/tests/src/Functional/CommentAttributesTest.php b/web/core/modules/rdf/tests/src/Functional/CommentAttributesTest.php
index 129e348ae9..2cf2366628 100644
--- a/web/core/modules/rdf/tests/src/Functional/CommentAttributesTest.php
+++ b/web/core/modules/rdf/tests/src/Functional/CommentAttributesTest.php
@@ -7,6 +7,7 @@
 use Drupal\comment\CommentManagerInterface;
 use Drupal\Tests\comment\Functional\CommentTestBase;
 use Drupal\Tests\rdf\Traits\RdfParsingTrait;
+use Drupal\user\Entity\User;
 use Drupal\user\RoleInterface;
 use Drupal\comment\Entity\Comment;
 
@@ -24,7 +25,7 @@ class CommentAttributesTest extends CommentTestBase {
    *
    * @var array
    */
-  public static $modules = ['views', 'node', 'comment', 'rdf'];
+  public static $modules = ['views', 'node', 'comment', 'rdf', 'user_hooks_test'];
 
   /**
    * {@inheritdoc}
@@ -148,6 +149,9 @@ public function testNumberOfCommentsRdfaMarkup() {
    * Tests comment author link markup has not been broken by RDF.
    */
   public function testCommentRdfAuthorMarkup() {
+    // Set to test the altered display name.
+    \Drupal::state()->set('user_hooks_test_user_format_name_alter', TRUE);
+
     // Post a comment as a registered user.
     $this->saveComment($this->node->id(), $this->webUser->id());
 
@@ -158,7 +162,7 @@ public function testCommentRdfAuthorMarkup() {
     // Ensure that the author link still works properly after the author output
     // is modified by the RDF module.
     $this->drupalGet('node/' . $this->node->id());
-    $this->assertSession()->linkExists($this->webUser->getAccountName());
+    $this->assertSession()->linkExistsExact($this->webUser->getDisplayName());
     $this->assertLinkByHref('user/' . $this->webUser->id());
   }
 
@@ -169,6 +173,9 @@ public function testCommentRdfAuthorMarkup() {
    * on comments from registered and anonymous users.
    */
   public function testCommentRdfaMarkup() {
+    // Set to test the altered display name.
+    \Drupal::state()->set('user_hooks_test_user_format_name_alter', TRUE);
+
     // Posts comment #1 on behalf of registered user.
     $comment1 = $this->saveComment($this->node->id(), $this->webUser->id());
 
@@ -187,12 +194,13 @@ public function testCommentRdfaMarkup() {
     $anonymous_user['homepage'] = 'http://example.org/';
     $comment2 = $this->saveComment($this->node->id(), 0, $anonymous_user);
 
+    $anonymous = User::load(0);
     // Tests comment #2 as anonymous user.
-    $this->_testBasicCommentRdfaMarkup($comment2, $anonymous_user);
+    $this->_testBasicCommentRdfaMarkup($comment2, $anonymous);
 
     // Tests comment #2 as logged in user.
     $this->drupalLogin($this->webUser);
-    $this->_testBasicCommentRdfaMarkup($comment2, $anonymous_user);
+    $this->_testBasicCommentRdfaMarkup($comment2, $anonymous);
   }
 
   /**
@@ -240,7 +248,7 @@ public function testCommentReplyOfRdfaMarkup() {
    * @param $account
    *   An array containing information about an anonymous user.
    */
-  public function _testBasicCommentRdfaMarkup(CommentInterface $comment, $account = []) {
+  public function _testBasicCommentRdfaMarkup(CommentInterface $comment, $account = NULL) {
     $this->drupalGet($this->node->toUrl());
     $comment_uri = $comment->toUrl('canonical', ['absolute' => TRUE])->toString();
 
@@ -303,7 +311,7 @@ public function _testBasicCommentRdfaMarkup(CommentInterface $comment, $account
     }
 
     // Author name.
-    $name = empty($account["name"]) ? $this->webUser->getAccountName() : $account["name"] . " (not verified)";
+    $name = $account ? $account->getDisplayName() . " (not verified)" : $this->webUser->getDisplayName();
     $expected_value = [
       'type' => 'literal',
       'value' => $name,
diff --git a/web/core/modules/rdf/tests/src/Functional/UserAttributesTest.php b/web/core/modules/rdf/tests/src/Functional/UserAttributesTest.php
index ee5102aecb..abece849eb 100644
--- a/web/core/modules/rdf/tests/src/Functional/UserAttributesTest.php
+++ b/web/core/modules/rdf/tests/src/Functional/UserAttributesTest.php
@@ -20,7 +20,7 @@ class UserAttributesTest extends BrowserTestBase {
    *
    * @var array
    */
-  public static $modules = ['rdf', 'node'];
+  public static $modules = ['rdf', 'node', 'user_hooks_test'];
 
   /**
    * {@inheritdoc}
@@ -47,6 +47,9 @@ protected function setUp() {
 
     // Prepares commonly used URIs.
     $this->baseUri = Url::fromRoute('<front>', [], ['absolute' => TRUE])->toString();
+
+    // Set to test the altered display name.
+    \Drupal::state()->set('user_hooks_test_user_format_name_alter', TRUE);
   }
 
   /**
@@ -87,7 +90,7 @@ public function testUserAttributesInMarkup() {
       // User name.
       $expected_value = [
         'type' => 'literal',
-        'value' => $author->getAccountName(),
+        'value' => $author->getDisplayName(),
       ];
       $this->assertTrue($this->hasRdfProperty($this->getSession()->getPage()->getContent(), $this->baseUri, $account_uri, 'http://xmlns.com/foaf/0.1/name', $expected_value), 'User name found in RDF output (foaf:name).');
 
@@ -108,7 +111,7 @@ public function testUserAttributesInMarkup() {
       // User name.
       $expected_value = [
         'type' => 'literal',
-        'value' => $author->getAccountName(),
+        'value' => $author->getDisplayName(),
       ];
       $this->assertTrue($this->hasRdfProperty($this->getSession()->getPage()->getContent(), $this->baseUri, $account_uri, 'http://xmlns.com/foaf/0.1/name', $expected_value), 'User name found in RDF output (foaf:name).');
     }
diff --git a/web/core/modules/rdf/tests/src/Kernel/RdfCommentStorageLoadTest.php b/web/core/modules/rdf/tests/src/Kernel/RdfCommentStorageLoadTest.php
new file mode 100644
index 0000000000..5ace1bcc64
--- /dev/null
+++ b/web/core/modules/rdf/tests/src/Kernel/RdfCommentStorageLoadTest.php
@@ -0,0 +1,46 @@
+<?php
+
+namespace Drupal\Tests\rdf\Kernel;
+
+use Drupal\Core\Field\FieldItemList;
+use Drupal\Core\Field\Plugin\Field\FieldType\CreatedItem;
+use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
+use Drupal\comment\Entity\Comment;
+
+/**
+ * Tests rdf_comment_storage_load.
+ *
+ * @group rdf
+ */
+class RdfCommentStorageLoadTest extends EntityKernelTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['comment', 'rdf'];
+
+  /**
+   * Tests rdf_comment_storage_load.
+   */
+  public function testRdfCommentStorageLoad() {
+    $field_created_item = $this->prophesize(CreatedItem::class);
+    $field_created_item->setValue([time()]);
+
+    $field_list = $this->prophesize(FieldItemList::class);
+    $field_list->reveal();
+    $field_list->first()->willReturn($field_created_item->reveal());
+
+    $comment = $this->prophesize(Comment::class);
+    $comment->bundle()->willReturn('page');
+    $comment->get('created')->willReturn($field_list);
+    $comment->getFieldDefinitions()->willReturn(NULL);
+    // Set commented entity and parent entity to NULL.
+    $comment->getCommentedEntity()->willReturn(NULL);
+    $comment->getParentComment()->willReturn(NULL);
+
+    /** @var \Drupal\Core\Extension\ModuleHandler $module_handler */
+    $module_handler = \Drupal::service('module_handler');
+    $module_handler->invoke('rdf', 'comment_storage_load', [[$comment->reveal()]]);
+  }
+
+}
diff --git a/web/core/modules/search/tests/src/Functional/SearchNodeUpdateAndDeletionTest.php b/web/core/modules/search/tests/src/Functional/SearchNodeUpdateAndDeletionTest.php
index 4e984037d3..77df01e279 100644
--- a/web/core/modules/search/tests/src/Functional/SearchNodeUpdateAndDeletionTest.php
+++ b/web/core/modules/search/tests/src/Functional/SearchNodeUpdateAndDeletionTest.php
@@ -100,7 +100,11 @@ public function testSearchIndexUpdateOnNodeDeletion() {
 
     // Get the node info from the search index tables.
     $connection = Database::getConnection();
-    $search_index_dataset = $connection->query("SELECT sid FROM {search_index} WHERE type = 'node_search' AND  word = :word", [':word' => 'dragons'])
+    $search_index_dataset = $connection->select('search_index', 'si')
+      ->fields('si', ['sid'])
+      ->condition('type', 'node_search')
+      ->condition('word', 'dragons')
+      ->execute()
       ->fetchField();
     $this->assertNotEqual($search_index_dataset, FALSE, t('Node info found on the search_index'));
 
@@ -108,7 +112,11 @@ public function testSearchIndexUpdateOnNodeDeletion() {
     $node->delete();
 
     // Check if the node info is gone from the search table.
-    $search_index_dataset = $connection->query("SELECT sid FROM {search_index} WHERE type = 'node_search' AND  word = :word", [':word' => 'dragons'])
+    $search_index_dataset = $connection->select('search_index', 'si')
+      ->fields('si', ['sid'])
+      ->condition('type', 'node_search')
+      ->condition('word', 'dragons')
+      ->execute()
       ->fetchField();
     $this->assertFalse($search_index_dataset, t('Node info successfully removed from search_index'));
 
diff --git a/web/core/modules/system/tests/modules/error_test/src/Controller/ErrorTestController.php b/web/core/modules/system/tests/modules/error_test/src/Controller/ErrorTestController.php
index c64da6dc23..2960b2151e 100644
--- a/web/core/modules/system/tests/modules/error_test/src/Controller/ErrorTestController.php
+++ b/web/core/modules/system/tests/modules/error_test/src/Controller/ErrorTestController.php
@@ -76,7 +76,9 @@ public function triggerException() {
    */
   public function triggerPDOException() {
     define('SIMPLETEST_COLLECT_ERRORS', FALSE);
-    $this->database->query('SELECT * FROM bananas_are_awesome');
+    $this->database->select('bananas_are_awesome', 'b')
+      ->fields('b')
+      ->execute();
   }
 
   /**
diff --git a/web/core/modules/system/tests/src/Functional/Database/SelectPagerDefaultTest.php b/web/core/modules/system/tests/src/Functional/Database/SelectPagerDefaultTest.php
index 2ba40a043a..4a37ecd4b6 100644
--- a/web/core/modules/system/tests/src/Functional/Database/SelectPagerDefaultTest.php
+++ b/web/core/modules/system/tests/src/Functional/Database/SelectPagerDefaultTest.php
@@ -30,7 +30,7 @@ public function testEvenPagerQuery() {
     // information forward to the actual query on the other side of the
     // HTTP request.
     $limit = 2;
-    $count = Database::getConnection()->query('SELECT COUNT(*) FROM {test}')->fetchField();
+    $count = Database::getConnection()->select('test')->countQuery()->execute()->fetchField();
 
     $correct_number = $limit;
     $num_pages = floor($count / $limit);
@@ -64,7 +64,7 @@ public function testOddPagerQuery() {
     // information forward to the actual query on the other side of the
     // HTTP request.
     $limit = 2;
-    $count = Database::getConnection()->query('SELECT COUNT(*) FROM {test_task}')->fetchField();
+    $count = Database::getConnection()->select('test_task')->countQuery()->execute()->fetchField();
 
     $correct_number = $limit;
     $num_pages = floor($count / $limit);
diff --git a/web/core/modules/system/tests/src/Functional/Form/StorageTest.php b/web/core/modules/system/tests/src/Functional/Form/StorageTest.php
index d503ba6a38..02ce119834 100644
--- a/web/core/modules/system/tests/src/Functional/Form/StorageTest.php
+++ b/web/core/modules/system/tests/src/Functional/Form/StorageTest.php
@@ -189,7 +189,12 @@ public function testImmutableFormLegacyProtection() {
 
     // Assert that a watchdog message was logged by
     // \Drupal::formBuilder()->setCache().
-    $status = (bool) Database::getConnection()->queryRange('SELECT 1 FROM {watchdog} WHERE message = :message', 0, 1, [':message' => 'Form build-id mismatch detected while attempting to store a form in the cache.']);
+    $status = (bool) Database::getConnection()->select('watchdog')
+      ->condition('message', 'Form build-id mismatch detected while attempting to store a form in the cache.')
+      ->range(0, 1)
+      ->countQuery()
+      ->execute()
+      ->fetchField();
     $this->assertTrue($status, 'A watchdog message was logged by \Drupal::formBuilder()->setCache');
 
     // Ensure that the form state was not poisoned by the preceding call.
diff --git a/web/core/modules/system/tests/src/Functional/Module/InstallTest.php b/web/core/modules/system/tests/src/Functional/Module/InstallTest.php
index 1fb619ff26..0041d3a4f5 100644
--- a/web/core/modules/system/tests/src/Functional/Module/InstallTest.php
+++ b/web/core/modules/system/tests/src/Functional/Module/InstallTest.php
@@ -31,7 +31,7 @@ class InstallTest extends BrowserTestBase {
    */
   public function testGetSchemaAtInstallTime() {
     // @see module_test_install()
-    $value = Database::getConnection()->query("SELECT data FROM {module_test}")->fetchField();
+    $value = Database::getConnection()->select('module_test', 'mt')->fields('mt', ['data'])->execute()->fetchField();
     $this->assertIdentical($value, 'varchar');
   }
 
diff --git a/web/core/modules/system/tests/src/Functional/Session/SessionHttpsTest.php b/web/core/modules/system/tests/src/Functional/Session/SessionHttpsTest.php
index 59dc9205de..49223e61ed 100644
--- a/web/core/modules/system/tests/src/Functional/Session/SessionHttpsTest.php
+++ b/web/core/modules/system/tests/src/Functional/Session/SessionHttpsTest.php
@@ -254,10 +254,7 @@ protected function getPathFromLocationHeader(ResponseInterface $response, $https
    *   has the given insecure and secure session IDs.
    */
   protected function assertSessionIds($sid, $assertion_text) {
-    $args = [
-      ':sid' => Crypt::hashBase64($sid),
-    ];
-    return $this->assertNotEmpty(\Drupal::database()->query('SELECT timestamp FROM {sessions} WHERE sid = :sid', $args)->fetchField(), $assertion_text);
+    return $this->assertNotEmpty(\Drupal::database()->select('sessions', 's')->fields('s', ['timestamp'])->condition('sid', Crypt::hashBase64($sid))->execute()->fetchField(), $assertion_text);
   }
 
   /**
diff --git a/web/core/modules/system/tests/src/Functional/Session/SessionTest.php b/web/core/modules/system/tests/src/Functional/Session/SessionTest.php
index aa34664bd1..ab8948d552 100644
--- a/web/core/modules/system/tests/src/Functional/Session/SessionTest.php
+++ b/web/core/modules/system/tests/src/Functional/Session/SessionTest.php
@@ -233,8 +233,12 @@ public function testSessionWrite() {
     $this->drupalLogin($user);
     $connection = Database::getConnection();
 
-    $sql = 'SELECT u.access, s.timestamp FROM {users_field_data} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE u.uid = :uid';
-    $times1 = $connection->query($sql, [':uid' => $user->id()])->fetchObject();
+    $query = $connection->select('users_field_data', 'u');
+    $query->innerJoin('sessions', 's', 'u.uid = s.uid');
+    $query->fields('u', ['access'])
+      ->fields('s', ['timestamp'])
+      ->condition('u.uid', $user->id());
+    $times1 = $query->execute()->fetchObject();
 
     // Before every request we sleep one second to make sure that if the session
     // is saved, its timestamp will change.
@@ -242,21 +246,21 @@ public function testSessionWrite() {
     // Modify the session.
     sleep(1);
     $this->drupalGet('session-test/set/foo');
-    $times2 = $connection->query($sql, [':uid' => $user->id()])->fetchObject();
+    $times2 = $query->execute()->fetchObject();
     $this->assertEqual($times2->access, $times1->access, 'Users table was not updated.');
     $this->assertNotEqual($times2->timestamp, $times1->timestamp, 'Sessions table was updated.');
 
     // Write the same value again, i.e. do not modify the session.
     sleep(1);
     $this->drupalGet('session-test/set/foo');
-    $times3 = $connection->query($sql, [':uid' => $user->id()])->fetchObject();
+    $times3 = $query->execute()->fetchObject();
     $this->assertEqual($times3->access, $times1->access, 'Users table was not updated.');
     $this->assertEqual($times3->timestamp, $times2->timestamp, 'Sessions table was not updated.');
 
     // Do not change the session.
     sleep(1);
     $this->drupalGet('');
-    $times4 = $connection->query($sql, [':uid' => $user->id()])->fetchObject();
+    $times4 = $query->execute()->fetchObject();
     $this->assertEqual($times4->access, $times3->access, 'Users table was not updated.');
     $this->assertEqual($times4->timestamp, $times3->timestamp, 'Sessions table was not updated.');
 
@@ -267,7 +271,7 @@ public function testSessionWrite() {
     ];
     $this->writeSettings($settings);
     $this->drupalGet('');
-    $times5 = $connection->query($sql, [':uid' => $user->id()])->fetchObject();
+    $times5 = $query->execute()->fetchObject();
     $this->assertNotEqual($times5->access, $times4->access, 'Users table was updated.');
     $this->assertNotEqual($times5->timestamp, $times4->timestamp, 'Sessions table was updated.');
   }
@@ -283,7 +287,12 @@ public function testEmptySessionID() {
 
     // Reset the sid in {sessions} to a blank string. This may exist in the
     // wild in some cases, although we normally prevent it from happening.
-    Database::getConnection()->query("UPDATE {sessions} SET sid = '' WHERE uid = :uid", [':uid' => $user->id()]);
+    Database::getConnection()->update('sessions')
+      ->fields([
+        'sid' => '',
+      ])
+      ->condition('uid', $user->id())
+      ->execute();
     // Send a blank sid in the session cookie, and the session should no longer
     // be valid. Closing the curl handler will stop the previous session ID
     // from persisting.
diff --git a/web/core/modules/system/tests/src/Functional/System/ErrorHandlerTest.php b/web/core/modules/system/tests/src/Functional/System/ErrorHandlerTest.php
index 7e03031c10..a8f52f2750 100644
--- a/web/core/modules/system/tests/src/Functional/System/ErrorHandlerTest.php
+++ b/web/core/modules/system/tests/src/Functional/System/ErrorHandlerTest.php
@@ -105,7 +105,7 @@ public function testExceptionHandler() {
     ];
     $error_pdo_exception = [
       '%type' => 'DatabaseExceptionWrapper',
-      '@message' => 'SELECT * FROM bananas_are_awesome',
+      '@message' => 'SELECT b.* FROM {bananas_are_awesome} b',
       '%function' => 'Drupal\error_test\Controller\ErrorTestController->triggerPDOException()',
       '%line' => 64,
       '%file' => drupal_get_path('module', 'error_test') . '/error_test.module',
@@ -127,7 +127,9 @@ public function testExceptionHandler() {
     // We cannot use assertErrorMessage() since the exact error reported
     // varies from database to database. Check that the SQL string is displayed.
     $this->assertText($error_pdo_exception['%type'], new FormattableMarkup('Found %type in error page.', $error_pdo_exception));
-    $this->assertText($error_pdo_exception['@message'], new FormattableMarkup('Found @message in error page.', $error_pdo_exception));
+    // Assert statement improved since static queries adds table alias in the
+    // error message.
+    $this->assertSession()->pageTextContains($error_pdo_exception['@message']);
     $error_details = new FormattableMarkup('in %function (line ', $error_pdo_exception);
     $this->assertRaw($error_details, new FormattableMarkup("Found '@message' in error page.", ['@message' => $error_details]));
 
diff --git a/web/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTid.php b/web/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTid.php
index 5829681767..24352de93b 100644
--- a/web/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTid.php
+++ b/web/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTid.php
@@ -4,6 +4,7 @@
 
 use Drupal\Core\Entity\Element\EntityAutocomplete;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Session\AccountInterface;
 use Drupal\taxonomy\Entity\Term;
 use Drupal\taxonomy\TermStorageInterface;
 use Drupal\taxonomy\VocabularyStorageInterface;
@@ -38,6 +39,13 @@ class TaxonomyIndexTid extends ManyToOne {
    */
   protected $termStorage;
 
+  /**
+   * The current user.
+   *
+   * @var \Drupal\Core\Session\AccountInterface
+   */
+  protected $currentUser;
+
   /**
    * Constructs a TaxonomyIndexTid object.
    *
@@ -51,11 +59,18 @@ class TaxonomyIndexTid extends ManyToOne {
    *   The vocabulary storage.
    * @param \Drupal\taxonomy\TermStorageInterface $term_storage
    *   The term storage.
+   * @param \Drupal\Core\Session\AccountInterface $current_user
+   *   The current user.
    */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, VocabularyStorageInterface $vocabulary_storage, TermStorageInterface $term_storage) {
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, VocabularyStorageInterface $vocabulary_storage, TermStorageInterface $term_storage, AccountInterface $current_user = NULL) {
     parent::__construct($configuration, $plugin_id, $plugin_definition);
     $this->vocabularyStorage = $vocabulary_storage;
     $this->termStorage = $term_storage;
+    if (!$current_user) {
+      @trigger_error('The current_user service must be passed to ' . __NAMESPACE__ . '\TaxonomyIndexTid::__construct(). It was added in drupal:8.9.0 and will be required before drupal:10.0.0.', E_USER_DEPRECATED);
+      $current_user = \Drupal::service('current_user');
+    }
+    $this->currentUser = $current_user;
   }
 
   /**
@@ -67,7 +82,8 @@ public static function create(ContainerInterface $container, array $configuratio
       $plugin_id,
       $plugin_definition,
       $container->get('entity_type.manager')->getStorage('taxonomy_vocabulary'),
-      $container->get('entity_type.manager')->getStorage('taxonomy_term')
+      $container->get('entity_type.manager')->getStorage('taxonomy_term'),
+      $container->get('current_user')
     );
   }
 
@@ -181,6 +197,9 @@ protected function valueForm(&$form, FormStateInterface $form_state) {
 
         if ($tree) {
           foreach ($tree as $term) {
+            if (!$term->isPublished() && !$this->currentUser->hasPermission('administer taxonomy')) {
+              continue;
+            }
             $choice = new \stdClass();
             $choice->option = [$term->id() => str_repeat('-', $term->depth) . \Drupal::service('entity.repository')->getTranslationFromContext($term)->label()];
             $options[] = $choice;
@@ -195,6 +214,9 @@ protected function valueForm(&$form, FormStateInterface $form_state) {
           ->sort('weight')
           ->sort('name')
           ->addTag('taxonomy_term_access');
+        if (!$this->currentUser->hasPermission('administer taxonomy')) {
+          $query->condition('status', 1);
+        }
         if ($this->options['limit']) {
           $query->condition('vid', $vocabulary->id());
         }
diff --git a/web/core/modules/taxonomy/tests/src/Functional/TermIndexTest.php b/web/core/modules/taxonomy/tests/src/Functional/TermIndexTest.php
index f83313d77f..ccf5466922 100644
--- a/web/core/modules/taxonomy/tests/src/Functional/TermIndexTest.php
+++ b/web/core/modules/taxonomy/tests/src/Functional/TermIndexTest.php
@@ -117,10 +117,12 @@ public function testTaxonomyIndex() {
     // Check that the term is indexed, and only once.
     $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
     $connection = Database::getConnection();
-    $index_count = $connection->query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', [
-      ':nid' => $node->id(),
-      ':tid' => $term_1->id(),
-    ])->fetchField();
+    $index_count = $connection->select('taxonomy_index')
+      ->condition('nid', $node->id())
+      ->condition('tid', $term_1->id())
+      ->countQuery()
+      ->execute()
+      ->fetchField();
     $this->assertEqual(1, $index_count, 'Term 1 is indexed once.');
 
     // Update the article to change one term.
@@ -128,15 +130,19 @@ public function testTaxonomyIndex() {
     $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
 
     // Check that both terms are indexed.
-    $index_count = $connection->query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', [
-      ':nid' => $node->id(),
-      ':tid' => $term_1->id(),
-    ])->fetchField();
+    $index_count = $connection->select('taxonomy_index')
+      ->condition('nid', $node->id())
+      ->condition('tid', $term_1->id())
+      ->countQuery()
+      ->execute()
+      ->fetchField();
     $this->assertEqual(1, $index_count, 'Term 1 is indexed.');
-    $index_count = $connection->query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', [
-      ':nid' => $node->id(),
-      ':tid' => $term_2->id(),
-    ])->fetchField();
+    $index_count = $connection->select('taxonomy_index')
+      ->condition('nid', $node->id())
+      ->condition('tid', $term_2->id())
+      ->countQuery()
+      ->execute()
+      ->fetchField();
     $this->assertEqual(1, $index_count, 'Term 2 is indexed.');
 
     // Update the article to change another term.
@@ -144,15 +150,19 @@ public function testTaxonomyIndex() {
     $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
 
     // Check that only one term is indexed.
-    $index_count = $connection->query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', [
-      ':nid' => $node->id(),
-      ':tid' => $term_1->id(),
-    ])->fetchField();
+    $index_count = $connection->select('taxonomy_index')
+      ->condition('nid', $node->id())
+      ->condition('tid', $term_1->id())
+      ->countQuery()
+      ->execute()
+      ->fetchField();
     $this->assertEqual(0, $index_count, 'Term 1 is not indexed.');
-    $index_count = $connection->query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', [
-      ':nid' => $node->id(),
-      ':tid' => $term_2->id(),
-    ])->fetchField();
+    $index_count = $connection->select('taxonomy_index')
+      ->condition('nid', $node->id())
+      ->condition('tid', $term_2->id())
+      ->countQuery()
+      ->execute()
+      ->fetchField();
     $this->assertEqual(1, $index_count, 'Term 2 is indexed once.');
 
     // Redo the above tests without interface.
@@ -164,15 +174,19 @@ public function testTaxonomyIndex() {
     $node->save();
 
     // Check that the index was not changed.
-    $index_count = $connection->query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', [
-      ':nid' => $node->id(),
-      ':tid' => $term_1->id(),
-    ])->fetchField();
+    $index_count = $connection->select('taxonomy_index')
+      ->condition('nid', $node->id())
+      ->condition('tid', $term_1->id())
+      ->countQuery()
+      ->execute()
+      ->fetchField();
     $this->assertEqual(0, $index_count, 'Term 1 is not indexed.');
-    $index_count = $connection->query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', [
-      ':nid' => $node->id(),
-      ':tid' => $term_2->id(),
-    ])->fetchField();
+    $index_count = $connection->select('taxonomy_index')
+      ->condition('nid', $node->id())
+      ->condition('tid', $term_2->id())
+      ->countQuery()
+      ->execute()
+      ->fetchField();
     $this->assertEqual(1, $index_count, 'Term 2 is indexed once.');
 
     // Update the article to change one term.
@@ -180,15 +194,19 @@ public function testTaxonomyIndex() {
     $node->save();
 
     // Check that both terms are indexed.
-    $index_count = $connection->query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', [
-      ':nid' => $node->id(),
-      ':tid' => $term_1->id(),
-    ])->fetchField();
+    $index_count = $connection->select('taxonomy_index')
+      ->condition('nid', $node->id())
+      ->condition('tid', $term_1->id())
+      ->countQuery()
+      ->execute()
+      ->fetchField();
     $this->assertEqual(1, $index_count, 'Term 1 is indexed.');
-    $index_count = $connection->query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', [
-      ':nid' => $node->id(),
-      ':tid' => $term_2->id(),
-    ])->fetchField();
+    $index_count = $connection->select('taxonomy_index')
+      ->condition('nid', $node->id())
+      ->condition('tid', $term_2->id())
+      ->countQuery()
+      ->execute()
+      ->fetchField();
     $this->assertEqual(1, $index_count, 'Term 2 is indexed.');
 
     // Update the article to change another term.
@@ -196,15 +214,19 @@ public function testTaxonomyIndex() {
     $node->save();
 
     // Check that only one term is indexed.
-    $index_count = $connection->query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', [
-      ':nid' => $node->id(),
-      ':tid' => $term_1->id(),
-    ])->fetchField();
+    $index_count = $connection->select('taxonomy_index')
+      ->condition('nid', $node->id())
+      ->condition('tid', $term_1->id())
+      ->countQuery()
+      ->execute()
+      ->fetchField();
     $this->assertEqual(1, $index_count, 'Term 1 is indexed once.');
-    $index_count = $connection->query('SELECT COUNT(*) FROM {taxonomy_index} WHERE nid = :nid AND tid = :tid', [
-      ':nid' => $node->id(),
-      ':tid' => $term_2->id(),
-    ])->fetchField();
+    $index_count = $connection->select('taxonomy_index')
+      ->condition('nid', $node->id())
+      ->condition('tid', $term_2->id())
+      ->countQuery()
+      ->execute()
+      ->fetchField();
     $this->assertEqual(0, $index_count, 'Term 2 is not indexed.');
   }
 
diff --git a/web/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyIndexTidUiTest.php b/web/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyIndexTidUiTest.php
index eb0774abb3..22845acd79 100644
--- a/web/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyIndexTidUiTest.php
+++ b/web/core/modules/taxonomy/tests/src/Functional/Views/TaxonomyIndexTidUiTest.php
@@ -231,4 +231,41 @@ public function testExposedFilter() {
     $this->assertTrue(empty($preview), 'No results.');
   }
 
+  /**
+   * Tests that an exposed taxonomy filter doesn't show unpublished terms.
+   */
+  public function testExposedUnpublishedFilterOptions() {
+    $this->terms[1][0]->setUnpublished()->save();
+    // Expose the filter.
+    $this->drupalPostForm('admin/structure/views/nojs/handler/test_filter_taxonomy_index_tid/default/filter/tid', [], 'Expose filter');
+    $edit = ['options[expose_button][checkbox][checkbox]' => TRUE];
+    $this->drupalPostForm(NULL, $edit, 'Apply');
+    $this->drupalPostForm(NULL, [], 'Save');
+    // Make sure the unpublished term is shown to the admin user.
+    $this->drupalGet('test-filter-taxonomy-index-tid');
+    $this->assertNotEmpty($this->cssSelect('option[value="' . $this->terms[0][0]->id() . '"]'));
+    $this->assertNotEmpty($this->cssSelect('option[value="' . $this->terms[1][0]->id() . '"]'));
+    $this->drupalLogout();
+    $this->drupalGet('test-filter-taxonomy-index-tid');
+    // Make sure the unpublished term isn't shown to the anonymous user.
+    $this->assertNotEmpty($this->cssSelect('option[value="' . $this->terms[0][0]->id() . '"]'));
+    $this->assertEmpty($this->cssSelect('option[value="' . $this->terms[1][0]->id() . '"]'));
+
+    // Tests that the term also isn't shown when not showing hierarchy.
+    $this->drupalLogin($this->adminUser);
+    $edit = [
+      'options[hierarchy]' => FALSE,
+    ];
+    $this->drupalPostForm('admin/structure/views/nojs/handler-extra/test_filter_taxonomy_index_tid/default/filter/tid', $edit, 'Apply');
+    $this->drupalPostForm(NULL, [], 'Save');
+    $this->drupalGet('test-filter-taxonomy-index-tid');
+    $this->assertNotEmpty($this->cssSelect('option[value="' . $this->terms[0][0]->id() . '"]'));
+    $this->assertNotEmpty($this->cssSelect('option[value="' . $this->terms[1][0]->id() . '"]'));
+    $this->drupalLogout();
+    $this->drupalGet('test-filter-taxonomy-index-tid');
+    // Make sure the unpublished term isn't shown to the anonymous user.
+    $this->assertNotEmpty($this->cssSelect('option[value="' . $this->terms[0][0]->id() . '"]'));
+    $this->assertEmpty($this->cssSelect('option[value="' . $this->terms[1][0]->id() . '"]'));
+  }
+
 }
diff --git a/web/core/modules/user/src/AccountForm.php b/web/core/modules/user/src/AccountForm.php
index 8e32dad8b1..893fdd251b 100644
--- a/web/core/modules/user/src/AccountForm.php
+++ b/web/core/modules/user/src/AccountForm.php
@@ -272,8 +272,11 @@ public function form(array $form, FormStateInterface $form_state) {
     // separately, assume that the user profile data is in the user's preferred
     // language. This entity builder provides that synchronization. For
     // use-cases where this synchronization is not desired, a module can alter
-    // or remove this item.
-    $form['#entity_builders']['sync_user_langcode'] = '::syncUserLangcode';
+    // or remove this item. Sync user langcode only when a user registers and
+    // not when a user is updated or translated.
+    if ($register) {
+      $form['#entity_builders']['sync_user_langcode'] = '::syncUserLangcode';
+    }
 
     $system_date_config = \Drupal::config('system.date');
     $form['timezone'] = [
diff --git a/web/core/modules/user/src/Plugin/Block/UserLoginBlock.php b/web/core/modules/user/src/Plugin/Block/UserLoginBlock.php
index d9971c564d..f55a70d611 100644
--- a/web/core/modules/user/src/Plugin/Block/UserLoginBlock.php
+++ b/web/core/modules/user/src/Plugin/Block/UserLoginBlock.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\user\Plugin\Block;
 
+use Drupal\Component\Utility\UrlHelper;
 use Drupal\Core\Access\AccessResult;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Drupal\Core\Security\TrustedCallbackInterface;
@@ -155,7 +156,7 @@ public function build() {
   public static function renderPlaceholderFormAction() {
     return [
       '#type' => 'markup',
-      '#markup' => Url::fromRoute('<current>', [], ['query' => \Drupal::destination()->getAsArray(), 'external' => FALSE])->toString(),
+      '#markup' => UrlHelper::filterBadProtocol(Url::fromRoute('<current>', [], ['query' => \Drupal::destination()->getAsArray(), 'external' => FALSE])->toString()),
       '#cache' => ['contexts' => ['url.path', 'url.query_args']],
     ];
   }
diff --git a/web/core/modules/user/tests/src/Functional/UserEditTest.php b/web/core/modules/user/tests/src/Functional/UserEditTest.php
index 6a71927a96..d06df78f3a 100644
--- a/web/core/modules/user/tests/src/Functional/UserEditTest.php
+++ b/web/core/modules/user/tests/src/Functional/UserEditTest.php
@@ -174,4 +174,53 @@ public function testUserWellKnownChangePasswordAnon() {
     $this->assertSession()->statusCodeEquals(403);
   }
 
+  /**
+   * Tests that a user is able to change site language.
+   */
+  public function testUserChangeSiteLanguage() {
+    // Install these modules here as these aren't needed for other test methods.
+    \Drupal::service('module_installer')->install([
+      'content_translation',
+      'language',
+    ]);
+    // Create and login as an admin user to add a new language and enable
+    // translation for user accounts.
+    $adminUser = $this->drupalCreateUser([
+      'administer account settings',
+      'administer languages',
+      'administer content translation',
+      'administer users',
+      'translate any entity',
+    ]);
+    $this->drupalLogin($adminUser);
+
+    // Add a new language into the system.
+    $edit = [
+      'predefined_langcode' => 'fr',
+    ];
+    $this->drupalPostForm('admin/config/regional/language/add', $edit, 'Add language');
+    $this->assertSession()->pageTextContains('French');
+
+    // Enable translation for user accounts.
+    $edit = [
+      'language[content_translation]' => 1,
+    ];
+    $this->drupalPostForm('admin/config/people/accounts', $edit, 'Save configuration');
+    $this->assertSession()->pageTextContains('The configuration options have been saved.');
+
+    // Create a regular user for whom translation will be enabled.
+    $webUser = $this->drupalCreateUser();
+
+    // Create a translation for a regular user account.
+    $this->drupalPostForm('user/' . $webUser->id() . '/translations/add/en/fr', [], 'Save');
+    $this->assertSession()->pageTextContains('The changes have been saved.');
+
+    // Update the site language of the user account.
+    $edit = [
+      'preferred_langcode' => 'fr',
+    ];
+    $this->drupalPostForm('user/' . $webUser->id() . '/edit', $edit, 'Save');
+    $this->assertSession()->statusCodeEquals(200);
+  }
+
 }
diff --git a/web/core/modules/views/tests/src/Kernel/Plugin/RelationshipJoinInTest.php b/web/core/modules/views/tests/src/Kernel/Plugin/RelationshipJoinInTest.php
index 4b7a70d5bf..f6e11a0acc 100644
--- a/web/core/modules/views/tests/src/Kernel/Plugin/RelationshipJoinInTest.php
+++ b/web/core/modules/views/tests/src/Kernel/Plugin/RelationshipJoinInTest.php
@@ -40,15 +40,30 @@ public function testRelationshipInQuery() {
     // Update the first two Beatles to be authored by Kristiaan.
     $account_k = $this->createUser([], 'Kristiaan');
     $connection = Database::getConnection();
-    $connection->query("UPDATE {views_test_data} SET uid = :uid WHERE id IN (1,2)", [':uid' => $account_k->id()]);
+    $connection->update('views_test_data')
+      ->fields([
+        'uid' => $account_k->id(),
+      ])
+      ->condition('id', [1, 2], 'IN')
+      ->execute();
 
     // Update the other two Beatles to be authored by Django.
     $account_d = $this->createUser([], 'Django');
-    $connection->query("UPDATE {views_test_data} SET uid = :uid WHERE id IN (3,4)", [':uid' => $account_d->id()]);
+    $connection->update('views_test_data')
+      ->fields([
+        'uid' => $account_d->id(),
+      ])
+      ->condition('id', [3, 4], 'IN')
+      ->execute();
 
     // Update Meredith to be authored by Silvie.
     $account_s = $this->createUser([], 'Silvie');
-    $connection->query("UPDATE {views_test_data} SET uid = :uid WHERE id = 5", [':uid' => $account_s->id()]);
+    $connection->update('views_test_data')
+      ->fields([
+        'uid' => $account_s->id(),
+      ])
+      ->condition('id', 5)
+      ->execute();
 
     $view = Views::getView('test_view');
     $view->setDisplay();
diff --git a/web/core/modules/views/tests/src/Kernel/Plugin/RelationshipTest.php b/web/core/modules/views/tests/src/Kernel/Plugin/RelationshipTest.php
index 421b73643b..86e353bed7 100644
--- a/web/core/modules/views/tests/src/Kernel/Plugin/RelationshipTest.php
+++ b/web/core/modules/views/tests/src/Kernel/Plugin/RelationshipTest.php
@@ -38,8 +38,18 @@ class RelationshipTest extends RelationshipJoinTestBase {
   public function testRelationshipQuery() {
     $connection = Database::getConnection();
     // Set the first entry to have the admin as author.
-    $connection->query("UPDATE {views_test_data} SET uid = 1 WHERE id = 1");
-    $connection->query("UPDATE {views_test_data} SET uid = 2 WHERE id <> 1");
+    $connection->update('views_test_data')
+      ->fields([
+        'uid' => 1,
+      ])
+      ->condition('id', 1)
+      ->execute();
+    $connection->update('views_test_data')
+      ->fields([
+        'uid' => 2,
+      ])
+      ->condition('id', 1, '<>')
+      ->execute();
 
     $view = Views::getView('test_view');
     $view->setDisplay();
@@ -136,11 +146,26 @@ public function testRelationshipQuery() {
   public function testRelationshipRender() {
     $connection = Database::getConnection();
     $author1 = $this->createUser();
-    $connection->query("UPDATE {views_test_data} SET uid = :uid WHERE id = 1", [':uid' => $author1->id()]);
+    $connection->update('views_test_data')
+      ->fields([
+        'uid' => $author1->id(),
+      ])
+      ->condition('id', 1)
+      ->execute();
     $author2 = $this->createUser();
-    $connection->query("UPDATE {views_test_data} SET uid = :uid WHERE id = 2", [':uid' => $author2->id()]);
+    $connection->update('views_test_data')
+      ->fields([
+        'uid' => $author2->id(),
+      ])
+      ->condition('id', 2)
+      ->execute();
     // Set uid to non-existing author uid for row 3.
-    $connection->query("UPDATE {views_test_data} SET uid = :uid WHERE id = 3", [':uid' => $author2->id() + 123]);
+    $connection->update('views_test_data')
+      ->fields([
+        'uid' => $author2->id() + 123,
+      ])
+      ->condition('id', 3)
+      ->execute();
 
     $view = Views::getView('test_view');
     // Add a relationship for authors.
diff --git a/web/core/modules/views_ui/src/Controller/ViewsUIController.php b/web/core/modules/views_ui/src/Controller/ViewsUIController.php
index 92a258558b..c5ccdf23b3 100644
--- a/web/core/modules/views_ui/src/Controller/ViewsUIController.php
+++ b/web/core/modules/views_ui/src/Controller/ViewsUIController.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\views_ui\Controller;
 
+use Drupal\Component\Utility\Tags;
 use Drupal\Core\Controller\ControllerBase;
 use Drupal\Core\Link;
 use Drupal\Core\Url;
@@ -188,13 +189,15 @@ public function autocompleteTag(Request $request) {
     // Keep track of previously processed tags so they can be skipped.
     $tags = [];
     foreach ($views as $view) {
-      $tag = $view->get('tag');
-      if ($tag && !in_array($tag, $tags)) {
-        $tags[] = $tag;
-        if (strpos($tag, $string) === 0) {
-          $matches[] = ['value' => $tag, 'label' => Html::escape($tag)];
-          if (count($matches) >= 10) {
-            break;
+      $view_tag = $view->get('tag');
+      foreach (Tags::explode($view_tag) as $tag) {
+        if ($tag && !in_array($tag, $tags, TRUE)) {
+          $tags[] = $tag;
+          if (mb_stripos($tag, $string) !== FALSE) {
+            $matches[] = ['value' => $tag, 'label' => Html::escape($tag)];
+            if (count($matches) >= 10) {
+              break 2;
+            }
           }
         }
       }
diff --git a/web/core/modules/views_ui/tests/src/Kernel/TagTest.php b/web/core/modules/views_ui/tests/src/Kernel/TagTest.php
index 6376874b4a..9c7dbeb2ea 100644
--- a/web/core/modules/views_ui/tests/src/Kernel/TagTest.php
+++ b/web/core/modules/views_ui/tests/src/Kernel/TagTest.php
@@ -22,7 +22,7 @@ class TagTest extends ViewsKernelTestBase {
   public static $modules = ['views', 'views_ui', 'user'];
 
   /**
-   * Tests the views_ui_autocomplete_tag function.
+   * Tests the ViewsUIController::autocompleteTag() function.
    */
   public function testViewsUiAutocompleteTag() {
     \Drupal::moduleHandler()->loadInclude('views_ui', 'inc', 'admin');
@@ -68,4 +68,41 @@ public function testViewsUiAutocompleteTag() {
     $this->assertCount(0, $matches, "Make sure an invalid tag doesn't return anything.");
   }
 
+  /**
+   * Tests that comma delimited tags are treated as individual tags.
+   *
+   * @dataProvider providerViewsUiAutocompleteIndividualTags
+   */
+  public function testViewsUiAutocompleteIndividualTags($expected_tag, $search_string) {
+    $controller = ViewsUIController::create($this->container);
+    $request = $this->container->get('request_stack')->getCurrentRequest();
+    $tag = 'comma, 你好, Foo bar';
+    View::create(['tag' => $tag, 'id' => $this->randomMachineName()])->save();
+    $request->query->set('q', $search_string);
+    $result = $controller->autocompleteTag($request);
+    $matches = (array) json_decode($result->getContent());
+    $this->assertCount(1, $matches);
+    $this->assertSame($expected_tag, $matches[0]->value);
+  }
+
+  /**
+   * Data provider for testViewsUiAutocompleteIndividualTags().
+   *
+   * @return array[]
+   *   The data set.
+   */
+  public function providerViewsUiAutocompleteIndividualTags() {
+    return [
+      'tag' => ['comma', 'comma'],
+      'case insensitive tag' => ['comma', 'COMMA'],
+      'Hello in Chinese (partial 1)' => ['你好', '你'],
+      'Hello in Chinese (partial 2)' => ['你好', '好'],
+      'Hello in Chinese' => ['你好', '你好'],
+      'Starts with partial and case-sensitive' => ['Foo bar', 'Foo'],
+      'Starts with partial and case-insensitive' => ['Foo bar', 'fOO'],
+      'Ends with partial and case-sensitive' => ['Foo bar', 'bar'],
+      'Ends with partial and case-insensitive' => ['Foo bar', 'BAR'],
+    ];
+  }
+
 }
diff --git a/web/core/modules/workspaces/src/WorkspaceManager.php b/web/core/modules/workspaces/src/WorkspaceManager.php
index 541ca88564..3421d31ec6 100644
--- a/web/core/modules/workspaces/src/WorkspaceManager.php
+++ b/web/core/modules/workspaces/src/WorkspaceManager.php
@@ -186,7 +186,11 @@ public function getActiveWorkspace() {
       foreach ($this->negotiatorIds as $negotiator_id) {
         $negotiator = $this->classResolver->getInstanceFromDefinition($negotiator_id);
         if ($negotiator->applies($request)) {
-          if ($active_workspace = $negotiator->getActiveWorkspace($request)) {
+          // By default, 'view' access is checked when a workspace is activated,
+          // but it should also be checked when retrieving the currently active
+          // workspace.
+          if (($negotiated_workspace = $negotiator->getActiveWorkspace($request)) && $negotiated_workspace->access('view')) {
+            $active_workspace = $negotiated_workspace;
             break;
           }
         }
diff --git a/web/core/modules/workspaces/tests/src/Functional/UpdateSystem/ActiveWorkspaceUpdateTest.php b/web/core/modules/workspaces/tests/src/Functional/UpdateSystem/ActiveWorkspaceUpdateTest.php
index 98cc5a3bfe..1c4f9b90ab 100644
--- a/web/core/modules/workspaces/tests/src/Functional/UpdateSystem/ActiveWorkspaceUpdateTest.php
+++ b/web/core/modules/workspaces/tests/src/Functional/UpdateSystem/ActiveWorkspaceUpdateTest.php
@@ -4,6 +4,7 @@
 
 use Drupal\Tests\BrowserTestBase;
 use Drupal\Tests\UpdatePathTestTrait;
+use Drupal\Tests\user\Traits\UserCreationTrait;
 
 /**
  * Tests that there is no active workspace during database updates.
@@ -12,12 +13,14 @@
  * @group Update
  */
 class ActiveWorkspaceUpdateTest extends BrowserTestBase {
+
   use UpdatePathTestTrait;
+  use UserCreationTrait;
 
   /**
    * {@inheritdoc}
    */
-  protected static $modules = ['workspaces', 'workspace_update_test'];
+  protected static $modules = ['workspaces'];
 
   /**
    * {@inheritdoc}
@@ -29,6 +32,11 @@ class ActiveWorkspaceUpdateTest extends BrowserTestBase {
    */
   protected function setUp() {
     parent::setUp();
+
+    $this->setUpCurrentUser([], ['view any workspace']);
+    $this->container->get('module_installer')->install(['workspace_update_test']);
+    $this->rebuildContainer();
+
     // Ensure the workspace_update_test_post_update_check_active_workspace()
     // update runs.
     $existing_updates = \Drupal::keyValue('post_update')->get('existing_updates', []);
diff --git a/web/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php b/web/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
index 7fc84a4278..52838df335 100644
--- a/web/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
+++ b/web/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
@@ -644,6 +644,24 @@ public function testNonCoreLibrariesNotFound() {
     $this->assertEquals('libraries/third_party_library/css/example.css', $library['css'][0]['data']);
   }
 
+  /**
+   * @covers ::parseLibraryInfo
+   */
+  public function testEmptyLibraryFile() {
+    $this->moduleHandler->expects($this->atLeastOnce())
+      ->method('moduleExists')
+      ->with('empty')
+      ->will($this->returnValue(TRUE));
+
+    $path = __DIR__ . '/library_test_files';
+    $path = substr($path, strlen($this->root) + 1);
+    $this->libraryDiscoveryParser->setPaths('module', 'empty', $path);
+
+    $libraries = $this->libraryDiscoveryParser->buildByExtension('empty');
+
+    $this->assertEquals([], $libraries);
+  }
+
 }
 
 /**
diff --git a/web/core/tests/Drupal/Tests/Core/Asset/library_test_files/empty.libraries.yml b/web/core/tests/Drupal/Tests/Core/Asset/library_test_files/empty.libraries.yml
new file mode 100644
index 0000000000..1388b54b2c
--- /dev/null
+++ b/web/core/tests/Drupal/Tests/Core/Asset/library_test_files/empty.libraries.yml
@@ -0,0 +1 @@
+# This file intentionally left empty
diff --git a/web/core/themes/claro/css/components/form.css b/web/core/themes/claro/css/components/form.css
index 78dc419d1c..ac3f76feab 100644
--- a/web/core/themes/claro/css/components/form.css
+++ b/web/core/themes/claro/css/components/form.css
@@ -137,16 +137,11 @@ tr .form-item,
 .form-item__label.form-required::after,
 .fieldset__label.form-required::after {
   display: inline-block;
-  width: 0.4375rem;
-  height: 0.4375rem;
-  margin-right: 0.3em;
-  margin-left: 0.3em;
-  content: "";
-  vertical-align: super;
-  /* Use a background image to prevent screen readers from announcing the text. */
-  background-image: url(../../images/core/ee0000/required.svg);
-  background-repeat: no-repeat;
-  background-size: 0.4375rem 0.4375rem;
+  margin-right: 0.15em;
+  margin-left: 0.15em;
+  content: "*";
+  color: #d72222;
+  font-size: 0.875rem;
 }
 
 /**
diff --git a/web/core/themes/claro/css/components/form.pcss.css b/web/core/themes/claro/css/components/form.pcss.css
index 554df9c9d1..1cf4cb4478 100644
--- a/web/core/themes/claro/css/components/form.pcss.css
+++ b/web/core/themes/claro/css/components/form.pcss.css
@@ -70,16 +70,11 @@ tr .form-item,
 .form-item__label.form-required::after,
 .fieldset__label.form-required::after {
   display: inline-block;
-  width: var(--input--required-mark-size);
-  height: var(--input--required-mark-size);
-  margin-right: 0.3em;
-  margin-left: 0.3em;
-  content: "";
-  vertical-align: super;
-  /* Use a background image to prevent screen readers from announcing the text. */
-  background-image: url(../../images/core/ee0000/required.svg);
-  background-repeat: no-repeat;
-  background-size: var(--input--required-mark-size) var(--input--required-mark-size);
+  margin-right: 0.15em;
+  margin-left: 0.15em;
+  content: "*";
+  color: var(--color-maximumred);
+  font-size: 0.875rem;
 }
 
 /**
diff --git a/web/sites/default/settings.pantheon.php b/web/sites/default/settings.pantheon.php
index dfcd419a92..ace23ce1ad 100644
--- a/web/sites/default/settings.pantheon.php
+++ b/web/sites/default/settings.pantheon.php
@@ -25,7 +25,7 @@
  * not to any Drupal files.
  */
 if (!defined("PANTHEON_VERSION")) {
-  define("PANTHEON_VERSION", "3");
+  define("PANTHEON_VERSION", "4");
 }
 
 /**
@@ -146,7 +146,7 @@
  *
  */
 if (isset($_ENV['PANTHEON_ENVIRONMENT'])) {
-  $settings["file_temp_path"] = $_SERVER['HOME'] .'/tmp';
+  $settings["file_temp_path"] = sys_get_temp_dir();
 }
 
 /**
-- 
GitLab