Issue #3210486 by Spokje, longwave, andypost, alexpott: Remove typo3/phar-stream-wrapper and associated code
parent
ca3ce56a2d
commit
9f5c2e9907
|
@ -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": [
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Core\Security;
|
||||
|
||||
use TYPO3\PharStreamWrapper\Assertable;
|
||||
use TYPO3\PharStreamWrapper\Helper;
|
||||
use TYPO3\PharStreamWrapper\Exception;
|
||||
|
||||
/**
|
||||
* An alternate PharExtensionInterceptor to support phar-based CLI tools.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @deprecated in drupal:9.4.0 and is removed from drupal:10.0.0. No replacement
|
||||
* is provided.
|
||||
*
|
||||
* @see https://www.drupal.org/project/drupal/issues/3252439
|
||||
* @see \TYPO3\PharStreamWrapper\Interceptor\PharExtensionInterceptor
|
||||
*/
|
||||
class PharExtensionInterceptor implements Assertable {
|
||||
|
||||
/**
|
||||
* Determines whether phar file is allowed to execute.
|
||||
*
|
||||
* The phar file is allowed to execute if:
|
||||
* - the base file name has a ".phar" suffix.
|
||||
* - it is the CLI tool that has invoked the interceptor.
|
||||
*
|
||||
* @param string $path
|
||||
* The path of the phar file to check.
|
||||
* @param string $command
|
||||
* The command being carried out.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the phar file is allowed to execute.
|
||||
*
|
||||
* @throws \TYPO3\PharStreamWrapper\Exception
|
||||
* Thrown when the file is not allowed to execute.
|
||||
*/
|
||||
public function assert(string $path, string $command): bool {
|
||||
if ($this->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';
|
||||
}
|
||||
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\KernelTests\Core\File;
|
||||
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests that the phar stream wrapper works.
|
||||
*
|
||||
* @group File
|
||||
*/
|
||||
class PharWrapperTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* Tests that only valid phar files can be used.
|
||||
*/
|
||||
public function testPharFile() {
|
||||
$base = $this->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"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue