From 9f5c2e9907604efcf378d4690d22915f21d3d867 Mon Sep 17 00:00:00 2001 From: catch Date: Wed, 26 Jan 2022 08:51:43 +0000 Subject: [PATCH] Issue #3210486 by Spokje, longwave, andypost, alexpott: Remove typo3/phar-stream-wrapper and associated code --- composer.lock | 60 +------------ .../Metapackage/CoreRecommended/composer.json | 3 +- core/composer.json | 1 - core/lib/Drupal/Core/DrupalKernel.php | 25 ------ .../Security/PharExtensionInterceptor.php | 85 ------------------ .../KernelTests/Core/File/PharWrapperTest.php | 40 --------- .../Core/File/StreamWrapperTest.php | 27 ------ core/tests/fixtures/files/phar-1.phar | Bin 6909 -> 0 bytes 8 files changed, 3 insertions(+), 238 deletions(-) delete mode 100644 core/lib/Drupal/Core/Security/PharExtensionInterceptor.php delete mode 100644 core/tests/Drupal/KernelTests/Core/File/PharWrapperTest.php delete mode 100644 core/tests/fixtures/files/phar-1.phar diff --git a/composer.lock b/composer.lock index 9ecaabd188f..a33732c64f2 100644 --- a/composer.lock +++ b/composer.lock @@ -448,7 +448,7 @@ "dist": { "type": "path", "url": "core", - "reference": "eefc18dedeaf145e81deed18c914b87cc2c62bd8" + "reference": "f6e86b91c8d470e57aa22b05e003a389d43a0813" }, "require": { "asm89/stack-cors": "^2.0.2", @@ -489,8 +489,7 @@ "symfony/serializer": "^5.4", "symfony/validator": "^5.4", "symfony/yaml": "^5.4", - "twig/twig": "^3.0", - "typo3/phar-stream-wrapper": "^3.1.3" + "twig/twig": "^3.0" }, "conflict": { "drush/drush": "<8.1.10" @@ -4468,61 +4467,6 @@ } ], "time": "2022-01-03T21:15:37+00:00" - }, - { - "name": "typo3/phar-stream-wrapper", - "version": "v3.1.7", - "source": { - "type": "git", - "url": "https://github.com/TYPO3/phar-stream-wrapper.git", - "reference": "5cc2f04a4e2f5c7e9cc02a3bdf80fae0f3e11a8c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/TYPO3/phar-stream-wrapper/zipball/5cc2f04a4e2f5c7e9cc02a3bdf80fae0f3e11a8c", - "reference": "5cc2f04a4e2f5c7e9cc02a3bdf80fae0f3e11a8c", - "shasum": "" - }, - "require": { - "ext-json": "*", - "php": "^7.0 || ^8.0" - }, - "require-dev": { - "ext-xdebug": "*", - "phpspec/prophecy": "^1.10", - "symfony/phpunit-bridge": "^5.1" - }, - "suggest": { - "ext-fileinfo": "For PHP builtin file type guessing, otherwise uses internal processing" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "v3.x-dev" - } - }, - "autoload": { - "psr-4": { - "TYPO3\\PharStreamWrapper\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Interceptors for PHP's native phar:// stream handling", - "homepage": "https://typo3.org/", - "keywords": [ - "phar", - "php", - "security", - "stream-wrapper" - ], - "support": { - "issues": "https://github.com/TYPO3/phar-stream-wrapper/issues", - "source": "https://github.com/TYPO3/phar-stream-wrapper/tree/v3.1.7" - }, - "time": "2021-09-20T19:19:13+00:00" } ], "packages-dev": [ diff --git a/composer/Metapackage/CoreRecommended/composer.json b/composer/Metapackage/CoreRecommended/composer.json index 6d202741ca8..78cbf42176e 100644 --- a/composer/Metapackage/CoreRecommended/composer.json +++ b/composer/Metapackage/CoreRecommended/composer.json @@ -60,7 +60,6 @@ "symfony/validator": "v5.4.2", "symfony/var-dumper": "v5.4.2", "symfony/yaml": "v5.4.2", - "twig/twig": "v3.3.7", - "typo3/phar-stream-wrapper": "v3.1.7" + "twig/twig": "v3.3.7" } } diff --git a/core/composer.json b/core/composer.json index aef3c04fc57..f2f4f174978 100644 --- a/core/composer.json +++ b/core/composer.json @@ -31,7 +31,6 @@ "symfony/polyfill-iconv": "^1.0", "symfony/polyfill-php80": "^1.16", "symfony/yaml": "^5.4", - "typo3/phar-stream-wrapper": "^3.1.3", "twig/twig": "^3.0", "doctrine/annotations": "^1.12", "guzzlehttp/guzzle": "^7.3.0", diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php index 40e49dcef9a..485c3ce9e4a 100644 --- a/core/lib/Drupal/Core/DrupalKernel.php +++ b/core/lib/Drupal/Core/DrupalKernel.php @@ -21,7 +21,6 @@ use Drupal\Core\Http\TrustedHostsRequestFactory; use Drupal\Core\Installer\InstallerKernel; use Drupal\Core\Installer\InstallerRedirectTrait; use Drupal\Core\Language\Language; -use Drupal\Core\Security\PharExtensionInterceptor; use Drupal\Core\Security\RequestSanitizer; use Drupal\Core\Site\Settings; use Drupal\Core\Test\TestDatabase; @@ -33,9 +32,6 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; use Symfony\Component\HttpKernel\TerminableInterface; -use TYPO3\PharStreamWrapper\Manager as PharStreamWrapperManager; -use TYPO3\PharStreamWrapper\Behavior as PharStreamWrapperBehavior; -use TYPO3\PharStreamWrapper\PharStreamWrapper; /** * The DrupalKernel class is the core of Drupal itself. @@ -479,27 +475,6 @@ class DrupalKernel implements DrupalKernelInterface, TerminableInterface { $this->classLoader->setApcuPrefix($prefix); } - // @todo clean-up for PHP 8.0+ https://www.drupal.org/node/3210486 - if (PHP_VERSION_ID < 80000 && in_array('phar', stream_get_wrappers(), TRUE)) { - // Set up a stream wrapper to handle insecurities due to PHP's builtin - // phar stream wrapper. This is not registered as a regular stream wrapper - // to prevent \Drupal\Core\File\FileSystem::validScheme() treating "phar" - // as a valid scheme. - try { - $behavior = new PharStreamWrapperBehavior(); - PharStreamWrapperManager::initialize( - $behavior->withAssertion(new PharExtensionInterceptor()) - ); - } - catch (\LogicException $e) { - // Continue if the PharStreamWrapperManager is already initialized. For - // example, this occurs during a module install. - // @see \Drupal\Core\Extension\ModuleInstaller::install() - } - stream_wrapper_unregister('phar'); - stream_wrapper_register('phar', PharStreamWrapper::class); - } - $this->booted = TRUE; return $this; diff --git a/core/lib/Drupal/Core/Security/PharExtensionInterceptor.php b/core/lib/Drupal/Core/Security/PharExtensionInterceptor.php deleted file mode 100644 index 8622dbb77a3..00000000000 --- a/core/lib/Drupal/Core/Security/PharExtensionInterceptor.php +++ /dev/null @@ -1,85 +0,0 @@ -baseFileContainsPharExtension($path)) { - return TRUE; - } - throw new Exception( - sprintf( - 'Unexpected file extension in "%s"', - $path - ), - 1535198703 - ); - } - - /** - * Determines if a path has a .phar extension or invoked execution. - * - * @param string $path - * The path of the phar file to check. - * - * @return bool - * TRUE if the file has a .phar extension or if the execution has been - * invoked by the phar file. - */ - private function baseFileContainsPharExtension($path) { - $baseFile = Helper::determineBaseFile($path); - if ($baseFile === NULL) { - return FALSE; - } - // If the stream wrapper is registered by invoking a phar file that does - // not have .phar extension then this should be allowed. For example, some - // CLI tools recommend removing the extension. - $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); - // Find the last entry in the backtrace containing a 'file' key as - // sometimes the last caller is executed outside the scope of a file. For - // example, this occurs with shutdown functions. - do { - $caller = array_pop($backtrace); - } while (empty($caller['file']) && !empty($backtrace)); - if (isset($caller['file']) && $baseFile === Helper::determineBaseFile($caller['file'])) { - return TRUE; - } - $fileExtension = pathinfo($baseFile, PATHINFO_EXTENSION); - return strtolower($fileExtension) === 'phar'; - } - -} diff --git a/core/tests/Drupal/KernelTests/Core/File/PharWrapperTest.php b/core/tests/Drupal/KernelTests/Core/File/PharWrapperTest.php deleted file mode 100644 index e528636ff53..00000000000 --- a/core/tests/Drupal/KernelTests/Core/File/PharWrapperTest.php +++ /dev/null @@ -1,40 +0,0 @@ -getDrupalRoot() . '/core/tests/fixtures/files'; - // Ensure that file operations via the phar:// stream wrapper work for phar - // files with the .phar extension. - $this->assertFileDoesNotExist("phar://$base/phar-1.phar/no-such-file.php"); - $this->assertFileExists("phar://$base/phar-1.phar/index.php"); - $file_contents = file_get_contents("phar://$base/phar-1.phar/index.php"); - $expected_hash = 'c7e7904ea573c5ebea3ef00bb08c1f86af1a45961fbfbeb1892ff4a98fd73ad5'; - $this->assertSame($expected_hash, hash('sha256', $file_contents)); - - // @todo clean-up for PHP 8.0+ https://www.drupal.org/node/3210486 - if (PHP_VERSION_ID < 80000) { - // Ensure that file operations via the phar:// stream wrapper throw an - // exception for files without the .phar extension. - $this->expectException('TYPO3\PharStreamWrapper\Exception'); - file_exists("phar://$base/image-2.jpg/index.php"); - } - else { - // PHP 8 fixed via https://wiki.php.net/rfc/phar_stop_autoloading_metadata - $this->assertFalse(file_exists("phar://$base/image-2.jpg/index.php")); - } - } - -} diff --git a/core/tests/Drupal/KernelTests/Core/File/StreamWrapperTest.php b/core/tests/Drupal/KernelTests/Core/File/StreamWrapperTest.php index 43b999e93fe..3e0404183a7 100644 --- a/core/tests/Drupal/KernelTests/Core/File/StreamWrapperTest.php +++ b/core/tests/Drupal/KernelTests/Core/File/StreamWrapperTest.php @@ -152,31 +152,4 @@ class StreamWrapperTest extends FileTestBase { $this->assertFalse($stream_wrapper_manager->isValidScheme($stream_wrapper_manager::getScheme('foo://asdf')), 'Did not get a valid stream scheme from foo://asdf'); } - /** - * Tests that phar stream wrapper is registered as expected. - * - * @see \Drupal\Core\StreamWrapper\StreamWrapperManager::register() - */ - public function testPharStreamWrapperRegistration() { - if (!in_array('phar', stream_get_wrappers(), TRUE)) { - $this->markTestSkipped('There is no phar stream wrapper registered. PHP is probably compiled without phar support.'); - } - // Ensure that phar is not treated as a valid scheme. - $stream_wrapper_manager = $this->container->get('stream_wrapper_manager'); - $this->assertFalse($stream_wrapper_manager->getViaScheme('phar')); - - // Ensure that calling register again and unregister do not create errors - // due to the PharStreamWrapperManager singleton. - $stream_wrapper_manager->register(); - $this->assertContains('public', stream_get_wrappers()); - $this->assertContains('phar', stream_get_wrappers()); - $stream_wrapper_manager->unregister(); - $this->assertNotContains('public', stream_get_wrappers()); - // This will have reverted to the builtin phar stream wrapper. - $this->assertContains('phar', stream_get_wrappers()); - $stream_wrapper_manager->register(); - $this->assertContains('public', stream_get_wrappers()); - $this->assertContains('phar', stream_get_wrappers()); - } - } diff --git a/core/tests/fixtures/files/phar-1.phar b/core/tests/fixtures/files/phar-1.phar deleted file mode 100644 index 8d25e6d4403979bf0fb37b7d10ff721bc804130d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6909 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