From f456bba0facf1703cfa765d39c0cb5888810a8ce Mon Sep 17 00:00:00 2001 From: omkar podey <58183-omkar.podey@users.noreply.drupalcode.org> Date: Wed, 11 Jan 2023 14:52:43 +0000 Subject: [PATCH] Issue #3330139 by omkar.podey, Wim Leers: Harden PathExclusionsTrait::excludeInProjectRoot() for paths outside of project root --- .../tests/src/Kernel/ExtensionUpdaterTest.php | 3 --- .../src/PathExcluder/PathExclusionsTrait.php | 6 ++++++ .../src/PathExcluder/SqliteDatabaseExcluder.php | 4 ++++ .../src/Kernel/PackageManagerKernelTestBase.php | 13 +++++++++++++ 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/automatic_updates_extensions/tests/src/Kernel/ExtensionUpdaterTest.php b/automatic_updates_extensions/tests/src/Kernel/ExtensionUpdaterTest.php index 78f55b2742..742dc170fd 100644 --- a/automatic_updates_extensions/tests/src/Kernel/ExtensionUpdaterTest.php +++ b/automatic_updates_extensions/tests/src/Kernel/ExtensionUpdaterTest.php @@ -45,8 +45,6 @@ class ExtensionUpdaterTest extends AutomaticUpdatesExtensionsKernelTestBase { // Create a user who will own the stage even after the container is rebuilt. $user = $this->createUser([], NULL, TRUE, ['uid' => 2]); $this->setCurrentUser($user); - - $this->createVirtualProject(__DIR__ . '/../../fixtures/fake-site'); } /** @@ -162,7 +160,6 @@ class ExtensionUpdaterTest extends AutomaticUpdatesExtensionsKernelTestBase { * @dataProvider providerUpdateException */ public function testUpdateException(string $event_class): void { - $this->createVirtualProject(__DIR__ . '/../../fixtures/fake-site'); $extension_updater = $this->container->get('automatic_updates_extensions.updater'); $results = [ ValidationResult::createError(['An error of some sorts.']), diff --git a/package_manager/src/PathExcluder/PathExclusionsTrait.php b/package_manager/src/PathExcluder/PathExclusionsTrait.php index f81b1541db..bd9fb8928b 100644 --- a/package_manager/src/PathExcluder/PathExclusionsTrait.php +++ b/package_manager/src/PathExcluder/PathExclusionsTrait.php @@ -65,6 +65,12 @@ trait PathExclusionsTrait { $project_root = $this->pathLocator->getProjectRoot(); foreach ($paths as $path) { + if (str_starts_with($path, '/') || str_starts_with($path, 'vfs:')) { + if (!str_starts_with($path, $project_root)) { + throw new \LogicException("$path is not inside the project root: $project_root."); + } + } + // Make absolute paths relative to the project root. $path = str_replace($project_root, '', $path); $path = ltrim($path, '/'); diff --git a/package_manager/src/PathExcluder/SqliteDatabaseExcluder.php b/package_manager/src/PathExcluder/SqliteDatabaseExcluder.php index 43de7961d8..275b6a8efa 100644 --- a/package_manager/src/PathExcluder/SqliteDatabaseExcluder.php +++ b/package_manager/src/PathExcluder/SqliteDatabaseExcluder.php @@ -61,6 +61,10 @@ class SqliteDatabaseExcluder implements EventSubscriberInterface { // and we should ignore it. Always treat it as relative to the project root. if ($this->database->driver() === 'sqlite') { $options = $this->database->getConnectionOptions(); + // Nothing to exclude if the database lives outside the project root. + if (str_starts_with($options['database'], '/') && !str_starts_with($options['database'], $this->pathLocator->getProjectRoot())) { + return; + } $this->excludeInProjectRoot($event, [ $options['database'], $options['database'] . '-shm', diff --git a/package_manager/tests/src/Kernel/PackageManagerKernelTestBase.php b/package_manager/tests/src/Kernel/PackageManagerKernelTestBase.php index 1af46e987a..fdb7db4f7f 100644 --- a/package_manager/tests/src/Kernel/PackageManagerKernelTestBase.php +++ b/package_manager/tests/src/Kernel/PackageManagerKernelTestBase.php @@ -5,6 +5,7 @@ declare(strict_types = 1); namespace Drupal\Tests\package_manager\Kernel; use Drupal\Core\DependencyInjection\ContainerBuilder; +use Drupal\Core\Site\Settings; use Drupal\KernelTests\KernelTestBase; use Drupal\package_manager\Event\PreApplyEvent; use Drupal\package_manager\Event\StageEvent; @@ -236,8 +237,20 @@ abstract class PackageManagerKernelTestBase extends KernelTestBase { $active_dir = vfsStream::newDirectory('active'); $this->vfsRoot->addChild($active_dir); $active_dir = $active_dir->url(); + // Move vfs://root/sites to vfs://root/active/sites. + $sites_in_vfs = vfsStream::url('root/sites'); + rename($sites_in_vfs, $sites_in_vfs . '/active'); static::copyFixtureFilesTo($source_dir, $active_dir); + // Override siteDirectory to point to root/active/... instead of root/... . + $test_site_path = str_replace('vfs://root/', '', $this->siteDirectory); + $this->siteDirectory = vfsStream::url('root/active/' . $test_site_path); + // Override KernelTestBase::setUpFilesystem's Settings object. + $settings = Settings::getInstance() ? Settings::getAll() : []; + $settings['file_public_path'] = $this->siteDirectory . '/files'; + $settings['config_sync_directory'] = $this->siteDirectory . '/files/config/sync'; + new Settings($settings); + // Create a stage root directory alongside the active directory. $stage_dir = vfsStream::newDirectory('stage'); $this->vfsRoot->addChild($stage_dir); -- GitLab