From eae7058a05d64a2364c6fb5efef2a3e29051ebc3 Mon Sep 17 00:00:00 2001
From: catch <catch@35733.no-reply.drupal.org>
Date: Tue, 17 Mar 2020 10:28:51 +0000
Subject: [PATCH] =?UTF-8?q?Issue=20#3103529=20by=20alexpott,=20mcdruid,=20?=
 =?UTF-8?q?Chris=20Burge,=20greg.1.anderson,=20rfay,=20anavarre,=20catch,?=
 =?UTF-8?q?=20G=C3=A1bor=20Hojtsy:=20Drupal=208.8.1+=20and=209=20can=20fai?=
 =?UTF-8?q?l=20to=20install=20in=20the=20web=20browser=20due=20to=20cache?=
 =?UTF-8?q?=20pollution?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 core/lib/Drupal/Core/DrupalKernel.php              | 14 ++++++++++++++
 .../Installer/InstallerExistingSettingsTest.php    | 11 +++++++++++
 core/tests/Drupal/KernelTests/KernelTestBase.php   | 11 ++++++-----
 3 files changed, 31 insertions(+), 5 deletions(-)

diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php
index ed776bf5511c..9f1deaa764c8 100644
--- a/core/lib/Drupal/Core/DrupalKernel.php
+++ b/core/lib/Drupal/Core/DrupalKernel.php
@@ -618,6 +618,20 @@ public function discoverServiceProviders() {
     // Retrieve enabled modules and register their namespaces.
     if (!isset($this->moduleList)) {
       $extensions = $this->getConfigStorage()->read('core.extension');
+      // If core.extension configuration does not exist and we're not in the
+      // installer itself, then we need to put the kernel into a pre-installer
+      // mode. The container should not be dumped because Drupal is yet to be
+      // installed. The installer service provider is registered to ensure that
+      // cache and other automatically created tables are not created if
+      // database settings are available. None of this is required when the
+      // installer is running because the installer has its own kernel and
+      // manages the addition of its own service providers.
+      // @see install_begin_request()
+      if ($extensions === FALSE && !InstallerKernel::installationAttempted()) {
+        $this->allowDumping = FALSE;
+        $this->containerNeedsDumping = FALSE;
+        $GLOBALS['conf']['container_service_providers']['InstallerServiceProvider'] = 'Drupal\Core\Installer\InstallerServiceProvider';
+      }
       $this->moduleList = isset($extensions['module']) ? $extensions['module'] : [];
     }
     $module_filenames = $this->getModuleFileNames();
diff --git a/core/tests/Drupal/FunctionalTests/Installer/InstallerExistingSettingsTest.php b/core/tests/Drupal/FunctionalTests/Installer/InstallerExistingSettingsTest.php
index f5fb5dc225e4..141f047a3c1e 100644
--- a/core/tests/Drupal/FunctionalTests/Installer/InstallerExistingSettingsTest.php
+++ b/core/tests/Drupal/FunctionalTests/Installer/InstallerExistingSettingsTest.php
@@ -54,6 +54,17 @@ protected function prepareEnvironment() {
     mkdir($this->settings['settings']['config_sync_directory']->value, 0777, TRUE);
   }
 
+  /**
+   * Visits the interactive installer.
+   */
+  protected function visitInstaller() {
+    // Should redirect to the installer.
+    $this->drupalGet($GLOBALS['base_url']);
+    // Ensure no database tables have been created yet.
+    $this->assertSame([], Database::getConnection()->schema()->findTables('%'));
+    $this->assertSession()->addressEquals($GLOBALS['base_url'] . '/core/install.php');
+  }
+
   /**
    * {@inheritdoc}
    */
diff --git a/core/tests/Drupal/KernelTests/KernelTestBase.php b/core/tests/Drupal/KernelTests/KernelTestBase.php
index 4539ed485028..ebb50d631db8 100644
--- a/core/tests/Drupal/KernelTests/KernelTestBase.php
+++ b/core/tests/Drupal/KernelTests/KernelTestBase.php
@@ -340,11 +340,12 @@ private function bootKernel() {
     // Bootstrap the kernel. Do not use createFromRequest() to retain Settings.
     $kernel = new DrupalKernel('testing', $this->classLoader, FALSE);
     $kernel->setSitePath($this->siteDirectory);
-    // Boot a new one-time container from scratch. Ensure to set the module list
-    // upfront to avoid a subsequent rebuild.
-    if ($modules && $extensions = $this->getExtensionsForModules($modules)) {
-      $kernel->updateModules($extensions, $extensions);
-    }
+    // Boot a new one-time container from scratch. Set the module list upfront
+    // to avoid a subsequent rebuild or setting the kernel into the
+    // pre-installer mode.
+    $extensions = $modules ? $this->getExtensionsForModules($modules) : [];
+    $kernel->updateModules($extensions, $extensions);
+
     // DrupalKernel::boot() is not sufficient as it does not invoke preHandle(),
     // which is required to initialize legacy global variables.
     $request = Request::create('/');
-- 
GitLab