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 8d25e6d4403..00000000000 Binary files a/core/tests/fixtures/files/phar-1.phar and /dev/null differ