diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php
index 7c9fb6c8ef..b9784250c6 100644
--- a/core/lib/Drupal/Core/DrupalKernel.php
+++ b/core/lib/Drupal/Core/DrupalKernel.php
@@ -491,8 +491,8 @@ public function boot() {
         // example, this occurs during a module install.
         // @see \Drupal\Core\Extension\ModuleInstaller::install()
       };
-      stream_wrapper_unregister('phar');
-      stream_wrapper_register('phar', PharStreamWrapper::class);
+//      stream_wrapper_unregister('phar');
+//      stream_wrapper_register('phar', PharStreamWrapper::class);
     }
 
     $this->booted = TRUE;
diff --git a/core/tests/Drupal/KernelTests/Core/File/PharWrapperTest.php b/core/tests/Drupal/KernelTests/Core/File/PharWrapperTest.php
index 2cd2ab1ea9..466e8056f8 100644
--- a/core/tests/Drupal/KernelTests/Core/File/PharWrapperTest.php
+++ b/core/tests/Drupal/KernelTests/Core/File/PharWrapperTest.php
@@ -3,6 +3,8 @@
 namespace Drupal\KernelTests\Core\File;
 
 use Drupal\KernelTests\KernelTestBase;
+use Symfony\Component\Process\PhpExecutableFinder;
+use Symfony\Component\Process\Process;
 
 /**
  * Tests that the phar stream wrapper works.
@@ -30,4 +32,25 @@ public function testPharFile() {
     file_exists("phar://$base/image-2.jpg/index.php");
   }
 
+  /**
+   * Tests phar files not ending in .phar can be executed using the CLI.
+   */
+  public function testCliPharFile() {
+    $php = (new PhpExecutableFinder())->find();
+    $process = new Process("$php cli_phar", __DIR__ . '/fixtures');
+    $process->run();
+
+    $expected_output = <<<EOF
+Can access phar files without .phar extension if they are the CLI command.
+Can access phar files with .phar extension.
+Cannot access other phar files without .phar extension.
+Shutdown functions work in phar files without a .phar extension.
+Shutdown functions cannot access other phar files without .phar extension.
+
+EOF;
+
+    $this->assertSame($expected_output, $process->getOutput());
+    $this->assertSame(0, $process->getExitCode());
+  }
+
 }
diff --git a/core/tests/Drupal/KernelTests/Core/File/fixtures/build_phar.php b/core/tests/Drupal/KernelTests/Core/File/fixtures/build_phar.php
new file mode 100644
index 0000000000..f452344981
--- /dev/null
+++ b/core/tests/Drupal/KernelTests/Core/File/fixtures/build_phar.php
@@ -0,0 +1,20 @@
+<?php
+
+/**
+ * @file
+ * Builds a test phar file.
+ */
+
+if (PHP_SAPI !== 'cli') {
+  return;
+}
+// Create a phar to run from CLI.
+$phar = new \Phar(__DIR__ . '/cli.phar');
+$phar->buildFromDirectory(__DIR__ . '/cli_phar_builder');
+
+// pointing main file which requires all classes
+$phar->setDefaultStub('index.php', '/index.php');
+
+// Make a version without a phar extension.
+copy(__DIR__ . '/cli.phar', __DIR__ . '/cli_phar');
+copy(__DIR__ . '/cli.phar', __DIR__ . '/cli_phar.png');
diff --git a/core/tests/Drupal/KernelTests/Core/File/fixtures/cli.phar b/core/tests/Drupal/KernelTests/Core/File/fixtures/cli.phar
new file mode 100644
index 0000000000..275ccc13e7
--- /dev/null
+++ b/core/tests/Drupal/KernelTests/Core/File/fixtures/cli.phar
@@ -0,0 +1,348 @@
+<?php
+
+$web = '/index.php';
+
+if (in_array('phar', stream_get_wrappers()) && class_exists('Phar', 0)) {
+Phar::interceptFileFuncs();
+set_include_path('phar://' . __FILE__ . PATH_SEPARATOR . get_include_path());
+Phar::webPhar(null, $web);
+include 'phar://' . __FILE__ . '/' . Extract_Phar::START;
+return;
+}
+
+if (@(isset($_SERVER['REQUEST_URI']) && isset($_SERVER['REQUEST_METHOD']) && ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'POST'))) {
+Extract_Phar::go(true);
+$mimes = array(
+'phps' => 2,
+'c' => 'text/plain',
+'cc' => 'text/plain',
+'cpp' => 'text/plain',
+'c++' => 'text/plain',
+'dtd' => 'text/plain',
+'h' => 'text/plain',
+'log' => 'text/plain',
+'rng' => 'text/plain',
+'txt' => 'text/plain',
+'xsd' => 'text/plain',
+'php' => 1,
+'inc' => 1,
+'avi' => 'video/avi',
+'bmp' => 'image/bmp',
+'css' => 'text/css',
+'gif' => 'image/gif',
+'htm' => 'text/html',
+'html' => 'text/html',
+'htmls' => 'text/html',
+'ico' => 'image/x-ico',
+'jpe' => 'image/jpeg',
+'jpg' => 'image/jpeg',
+'jpeg' => 'image/jpeg',
+'js' => 'application/x-javascript',
+'midi' => 'audio/midi',
+'mid' => 'audio/midi',
+'mod' => 'audio/mod',
+'mov' => 'movie/quicktime',
+'mp3' => 'audio/mp3',
+'mpg' => 'video/mpeg',
+'mpeg' => 'video/mpeg',
+'pdf' => 'application/pdf',
+'png' => 'image/png',
+'swf' => 'application/shockwave-flash',
+'tif' => 'image/tiff',
+'tiff' => 'image/tiff',
+'wav' => 'audio/wav',
+'xbm' => 'image/xbm',
+'xml' => 'text/xml',
+);
+
+header("Cache-Control: no-cache, must-revalidate");
+header("Pragma: no-cache");
+
+$basename = basename(__FILE__);
+if (!strpos($_SERVER['REQUEST_URI'], $basename)) {
+chdir(Extract_Phar::$temp);
+include $web;
+return;
+}
+$pt = substr($_SERVER['REQUEST_URI'], strpos($_SERVER['REQUEST_URI'], $basename) + strlen($basename));
+if (!$pt || $pt == '/') {
+$pt = $web;
+header('HTTP/1.1 301 Moved Permanently');
+header('Location: ' . $_SERVER['REQUEST_URI'] . '/' . $pt);
+exit;
+}
+$a = realpath(Extract_Phar::$temp . DIRECTORY_SEPARATOR . $pt);
+if (!$a || strlen(dirname($a)) < strlen(Extract_Phar::$temp)) {
+header('HTTP/1.0 404 Not Found');
+echo "<html>\n <head>\n  <title>File Not Found<title>\n </head>\n <body>\n  <h1>404 - File Not Found</h1>\n </body>\n</html>";
+exit;
+}
+$b = pathinfo($a);
+if (!isset($b['extension'])) {
+header('Content-Type: text/plain');
+header('Content-Length: ' . filesize($a));
+readfile($a);
+exit;
+}
+if (isset($mimes[$b['extension']])) {
+if ($mimes[$b['extension']] === 1) {
+include $a;
+exit;
+}
+if ($mimes[$b['extension']] === 2) {
+highlight_file($a);
+exit;
+}
+header('Content-Type: ' .$mimes[$b['extension']]);
+header('Content-Length: ' . filesize($a));
+readfile($a);
+exit;
+}
+}
+
+class Extract_Phar
+{
+static $temp;
+static $origdir;
+const GZ = 0x1000;
+const BZ2 = 0x2000;
+const MASK = 0x3000;
+const START = 'index.php';
+const LEN = 6644;
+
+static function go($return = false)
+{
+$fp = fopen(__FILE__, 'rb');
+fseek($fp, self::LEN);
+$L = unpack('V', $a = fread($fp, 4));
+$m = '';
+
+do {
+$read = 8192;
+if ($L[1] - strlen($m) < 8192) {
+$read = $L[1] - strlen($m);
+}
+$last = fread($fp, $read);
+$m .= $last;
+} while (strlen($last) && strlen($m) < $L[1]);
+
+if (strlen($m) < $L[1]) {
+die('ERROR: manifest length read was "' .
+strlen($m) .'" should be "' .
+$L[1] . '"');
+}
+
+$info = self::_unpack($m);
+$f = $info['c'];
+
+if ($f & self::GZ) {
+if (!function_exists('gzinflate')) {
+die('Error: zlib extension is not enabled -' .
+' gzinflate() function needed for zlib-compressed .phars');
+}
+}
+
+if ($f & self::BZ2) {
+if (!function_exists('bzdecompress')) {
+die('Error: bzip2 extension is not enabled -' .
+' bzdecompress() function needed for bz2-compressed .phars');
+}
+}
+
+$temp = self::tmpdir();
+
+if (!$temp || !is_writable($temp)) {
+$sessionpath = session_save_path();
+if (strpos ($sessionpath, ";") !== false)
+$sessionpath = substr ($sessionpath, strpos ($sessionpath, ";")+1);
+if (!file_exists($sessionpath) || !is_dir($sessionpath)) {
+die('Could not locate temporary directory to extract phar');
+}
+$temp = $sessionpath;
+}
+
+$temp .= '/pharextract/'.basename(__FILE__, '.phar');
+self::$temp = $temp;
+self::$origdir = getcwd();
+@mkdir($temp, 0777, true);
+$temp = realpath($temp);
+
+if (!file_exists($temp . DIRECTORY_SEPARATOR . md5_file(__FILE__))) {
+self::_removeTmpFiles($temp, getcwd());
+@mkdir($temp, 0777, true);
+@file_put_contents($temp . '/' . md5_file(__FILE__), '');
+
+foreach ($info['m'] as $path => $file) {
+$a = !file_exists(dirname($temp . '/' . $path));
+@mkdir(dirname($temp . '/' . $path), 0777, true);
+clearstatcache();
+
+if ($path[strlen($path) - 1] == '/') {
+@mkdir($temp . '/' . $path, 0777);
+} else {
+file_put_contents($temp . '/' . $path, self::extractFile($path, $file, $fp));
+@chmod($temp . '/' . $path, 0666);
+}
+}
+}
+
+chdir($temp);
+
+if (!$return) {
+include self::START;
+}
+}
+
+static function tmpdir()
+{
+if (strpos(PHP_OS, 'WIN') !== false) {
+if ($var = getenv('TMP') ? getenv('TMP') : getenv('TEMP')) {
+return $var;
+}
+if (is_dir('/temp') || mkdir('/temp')) {
+return realpath('/temp');
+}
+return false;
+}
+if ($var = getenv('TMPDIR')) {
+return $var;
+}
+return realpath('/tmp');
+}
+
+static function _unpack($m)
+{
+$info = unpack('V', substr($m, 0, 4));
+ $l = unpack('V', substr($m, 10, 4));
+$m = substr($m, 14 + $l[1]);
+$s = unpack('V', substr($m, 0, 4));
+$o = 0;
+$start = 4 + $s[1];
+$ret['c'] = 0;
+
+for ($i = 0; $i < $info[1]; $i++) {
+ $len = unpack('V', substr($m, $start, 4));
+$start += 4;
+ $savepath = substr($m, $start, $len[1]);
+$start += $len[1];
+   $ret['m'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', substr($m, $start, 24)));
+$ret['m'][$savepath][3] = sprintf('%u', $ret['m'][$savepath][3]
+& 0xffffffff);
+$ret['m'][$savepath][7] = $o;
+$o += $ret['m'][$savepath][2];
+$start += 24 + $ret['m'][$savepath][5];
+$ret['c'] |= $ret['m'][$savepath][4] & self::MASK;
+}
+return $ret;
+}
+
+static function extractFile($path, $entry, $fp)
+{
+$data = '';
+$c = $entry[2];
+
+while ($c) {
+if ($c < 8192) {
+$data .= @fread($fp, $c);
+$c = 0;
+} else {
+$c -= 8192;
+$data .= @fread($fp, 8192);
+}
+}
+
+if ($entry[4] & self::GZ) {
+$data = gzinflate($data);
+} elseif ($entry[4] & self::BZ2) {
+$data = bzdecompress($data);
+}
+
+if (strlen($data) != $entry[0]) {
+die("Invalid internal .phar file (size error " . strlen($data) . " != " .
+$stat[7] . ")");
+}
+
+if ($entry[3] != sprintf("%u", crc32($data) & 0xffffffff)) {
+die("Invalid internal .phar file (checksum error)");
+}
+
+return $data;
+}
+
+static function _removeTmpFiles($temp, $origdir)
+{
+chdir($temp);
+
+foreach (glob('*') as $f) {
+if (file_exists($f)) {
+is_dir($f) ? @rmdir($f) : @unlink($f);
+if (file_exists($f) && is_dir($f)) {
+self::_removeTmpFiles($f, getcwd());
+}
+}
+}
+
+@rmdir($temp);
+clearstatcache();
+chdir($origdir);
+}
+}
+
+Extract_Phar::go();
+__HALT_COMPILER(); ?>
+7                  	   index.php  sÁ?\  Öå\¶      <?php
+
+/**
+ * @file
+ * Tests phar protection.
+ */
+
+use Drupal\Core\Security\PharExtensionInterceptor;
+use TYPO3\PharStreamWrapper\Behavior;
+use TYPO3\PharStreamWrapper\Exception as PharStreamWrapperException;
+use TYPO3\PharStreamWrapper\Manager;
+use TYPO3\PharStreamWrapper\PharStreamWrapper;
+
+// Use the current working directory so we don't have to include all the code in
+// the phar file.
+require_once getcwd() . '/../../../../../../../autoload.php';
+stream_wrapper_unregister('phar');
+stream_wrapper_register('phar', PharStreamWrapper::class);
+
+Manager::initialize(
+  (new Behavior())
+    ->withAssertion(new PharExtensionInterceptor())
+);
+
+if (file_exists(__DIR__ . '/index.php')) {
+  echo "Can access phar files without .phar extension if they are the CLI command.\n";
+}
+
+if (file_exists('phar://cli.phar')) {
+  echo "Can access phar files with .phar extension.\n";
+}
+
+// Try an insecure phar without an extension.
+try {
+  file_exists('phar://cli_phar.png');
+}
+catch (PharStreamWrapperException $e) {
+  echo "Cannot access other phar files without .phar extension.\n";
+}
+
+// Try accessing phar from a shutdown function.
+register_shutdown_function('phar_shutdown');
+
+function phar_shutdown() {
+  if (file_exists(__DIR__ . '/index.php')) {
+    echo "Shutdown functions work in phar files without a .phar extension.\n";
+  }
+  // Try an insecure phar without an extension.
+  try {
+    file_exists('phar://cli_phar.png');
+  }
+  catch (PharStreamWrapperException $e) {
+    echo "Shutdown functions cannot access other phar files without .phar extension.\n";
+  }
+}
+m*ˆ4ä¦åÊŽˆŽ8º» vÚ#^   GBMB
\ No newline at end of file
diff --git a/core/tests/Drupal/KernelTests/Core/File/fixtures/cli_phar b/core/tests/Drupal/KernelTests/Core/File/fixtures/cli_phar
new file mode 100644
index 0000000000000000000000000000000000000000..275ccc13e772be600dd0b038fbec62d9290c7330
GIT binary patch
literal 8296
zcmb_hOLN@D5ms_YRZx{fQn{vTw1EXsTrNn8mYgL;iK12#E2PPgYr1SwL1BT}U6^<U
z!15tWcc1(-@)L4MPPyg><dAdxKl1fFK<qA7l3k(1BGA+C?&<CsY(2@wnPHe$e83(v
z%L$W!Uv~hrHVq>jGCNFMFVDRj+sejXZnara=G=?j5ii}V+{-ea7xvN;yLXTIkyjKh
zzYdGCu&pDBzKXSP4SMNz!=&W7&$IGH81WaA#0TZ3QGipJ_|YWbZswI^DXHr?7V9wA
zeX+OSb6q?h?et%{C%vPc<DLHDF#x2(6yXxMNl7q=9_(ZiMQujbVM*aKVaYsyO9<>;
zm$~PcuH<vl-#PAY8aXc~d9rD|lRkNBhXu5@O{jBx+B-h8j(dOlqIc4Fzc}8rUJGX|
z!Z_&lUmZSINDUnHI(v+8yzKQY_Vz8C7c_--ba>LYmV~3H)gPsHnNK)uH{&qo1wt%?
zX}||rVX?>CY`tw*zId`qeqB0Q<b{bvz-DNcH6kxBH-UpPXabL$fKfVX0_RC1xV$c#
zu&;|oft1i>>>BJs8dT5TWhl8^h5=6<dIiQHRyKyQH{uSxl0ORRFzF_G18@`$B?E~{
zuYiurSVDzI@fIm)v;bV^tkFY1t+T#fApn?vlkqwnuOkUoev+Epg0W1dTQhJa5<55w
zeXk7D#JOJi#=G<iKM%8#SjJ(X+~ZAxFm=ScgiDq);8giuf$>Vn>7_)*L&%-KOhW&n
zL^6uC?7<Wxyb?vGG?qb$m4V`~uw)vZ1u6t}QwRuFnNA*QJiP*1Ts2S><J7;n@-F$x
z5Or)!c;$3(@hX^#zcrU?IEd@k&?}f+4^%El73h_qND0A0WC*>r4Qx|m%)Nl;c5B!3
z$9!csP0Botx-3aoe1f!DJSobRoL_oT7<eUbfk@LF<=!avZjoutFb7`26EEi2`})z=
zRTT(S<L{!TXKB$;jYK^|0o9bE#`xnP%<bt)W0pM5h@C9tqU6@=rkRycpqLCGYO$P;
z*MlunBZ_!p*K||XkSr>iB$9fXMIA^gK%Jm+nDwgPKXTSOYwW@58aqfYdBBc%9(xH-
z%IL<rb*;6Z$}Q4m)RgASvG5aCWDkKX(4rBR)G|yDmZN7zqPaD=4Rp`<j(fZ4YF|w?
zILSvu2uxs-G8yith}x!ycx-8C17{H~l^)vKRkpFZ!9Gt*_9C4m0a?lYamrd-RCu<}
z6ShSZ^uV^tu#EUNwd-371tdgAV{Q%7;6{>+*S1N(3Y(#Fupnp@Du_v5tL7*gLC8sA
zGEB)h6;IVl2WJ-g6Hf}1D)dhZsy2=G31YU=zsY!))!JAsgc@g`C!=yK1383YMfgT~
zlG4=+2qb0e_=zb<_IuGp&&+8}q$-3Zo9x^=vhXomBYmsg;oVyOA;NWGXgC^2_$}Re
z{hFPCJYAs9|HCI3gv7MR>PcsOYZN6qiO)nez+|W1(mWg?XEzN$O^TAe{2Fmyy<S^g
zUDcpxU#|<;dJT54bMi+4d{6_5fecV|@!LUFvfb}}j)jL0H#SiAl;|ObOloZmlaMK=
zIN%JusNhRb*BoZ_nr5gYx+b=nl@DlF3=7ULY@lG~<<YR)g#dufeUMC&%=0g7>l6dA
z*xy6S9f`a_W2hMe%c3DVND+9*_5wgYTl>Sh%xZK0Z0$96iLPQX?POXO#Y&;iBZ-27
z{zTQZCR6a2VmptSNeIAXS7X|_ww6I)F`R0E5GsU#R<weK6{sJC+_rkh$A`yVhVmE=
zITS$g#YUpa7O*R?U@fE^{4R?!ICrcTLsOkZ0UL0+D(yj;Y>|VJL?&%@m?9nQDz}<3
znKA@ite;^%eXaBZ^q#_g`L)<m)W39?tHa0W4H!r0j~I(9{qsD{yX;LA4p>!4SXiLB
zmJBU&5TX9BkP#NE=<Ow@nX`oR04T#W7fe?CG|qC4$`CM|n7q7@MyW$WO;cp|VpRuk
z0<JmDYdd%oX6qkRx6WgM#)CKO?@?H6*eVWXoKc6@IdNC6qW|0t3mp2wl6+;$mM_w^
zfETdKsCEk`;>|5EOvw`+I8m8Ha$w9rovh)vS!=Vk#O|U*s%=?cC2nG7m?c`wYI#jb
zyGx}~XGERp617q?g^Zk9sB&djq%9>zM4g|br^H#Bd-)9m5%<d!Pi0Dhq0=Ix@XP3H
zPuBU$R3{b;yVG(ATTwbzN6%LE3MBH07|M-NF(n=qP?c5q2q$6xDxiQpjW2{%gxF@Q
zj~+d0GkpXU3e-js89=qMroAO~T`-o!!Kbnf>5?gro@x*09D_dZ$Jq;Nt};v7m4@$E
z@u>(|HYr_{bn57ezM8D&MWbAkpA76ujtLogLM7$QimlfSMah&oxy?*sEs~YSu_<fe
zFgZ>stMw3vY^GAKT>3t&8BhBWM>Rn66El0YkAyB~x<Zm-OK1S-0=H9YJ$#kXf=-Hn
zI`0@q_d-$okgpV(42w!Piixcjgh$Z6hMBO^AIB*=*t`!Q`QgKdBw743<oG|GJgT>f
zDyL2WQm(o{A=0^?tji1<@ojamk6s<QhbIW@mwTUMa=$GMFj>q>mtHPYo+p>K)jv1_
z))Pvw+I#o*y+;V7m}>tf=*br1rD}lXkkw#=x*+$DhScbgUUGuhYs5tH6qQReB>~e4
zV!CfsK~dK^lN!Wm&RMnINP~;&oAo(FAFg5qtj)v}f=K|HEI?Y*SYlSGQLk;_bY(`E
zPoRoPmqrUXR1BzvW0o_K^Epi>f<XZWfWb)7z$FUpQ`)2A4ecF6kKC}p#nbXKc^txd
z0*nP>r5I(RlDQ0_n;@i~quY==Y{DO!g7|8)gsLD@Fc32)l||_|s~BN-$~!X`NA3v<
zTBVfdoDQ5*-#HDOQ|_GNYM?sb)<mu&5adSThH1`c4~Th@<+v9e+SVr%8YY|ZjC&ZE
zhw5h$yGO*%Od%{~WLOicbqa|L6HwMgpqlVLoeJIC1>81XSJN0x>$M$0!W;9rsSu&i
z=QpwvQEua2gK9KQ&!$f%iS;v5-B1&)>5EcBXD+`!Hw#kq*r)Z`*e8b(Bcy0mJpowJ
z^SG2aLndZ%GC|LCQj40&asbup-j0j{0+~{ls9AHgY9!ReQv+N@KRuF@ZB!4nKUQ(k
zEJyR!ULx*;n7Ck1yhzTYj5-9SE*x+fr{R~i&{K5(k?cBvfh871T9ju<BEXjD?r7R@
zBr6bgwzfW*wA#$i{Riu|)EAjhOVN*04L4f;MKOt`dRiz_2e<7^uoYU&9_HNU8N*Zq
z5uNO2np8C%jG}a4TlZ1xX*d|_EE2s`eYpTsfYp2moG0vQ9*eOGFJ1O@l0;!bM?*M?
z!aGAv-$L|sDS0gzjfPWmk!r766tyJqpPwa^Y1&woqP?l_7C7#L)^%U)?DyT>!-FGy
zL^%eCJ=y-1@#xN-J3qtkuhn1t!Ot)8TOF!@_lrAsihn*ir@#OH%@5~)BYga9$<Ia3
z{rd*Hk6nfYqlZ4ugM}D^S(c|I=3|@&I#_WGV}fDjc|OU!=zJG5+W86hCpbdfoYNN;
zXe}>v_VlNr6wR4P`d=L#J`gx3;)Bzd@>|pSGd{*G{fDr6*Yuf*4*m!;37TS3t-fE>
zftTR={{#BWF-MVd9QFlFD94<^)*PFkU8VU&n2c(thazQHoCUbcDj7@ydW!ukK7%nY
ziX?R!Z~%!RF{5*X*wh^i9=J%)xtk_FuZC+eF?Kr6{C{s!rcvqz>dPK#0DZ$#-|sM5
z<a~s$cDQ(!U-^(bGbl3%?RlqmyW&O&q=s@Feees*5I5DhVMBYh6Mn^X{P4|?Ixbt;
zz6#6n4o=ZI#Y^BU$_%0*{<C||bunRyZ-n&^m|_<*CNDR4J*0x~<D7cy#e$LObW*Bv
ziPj{OkwF0beS^j?qqw`j$8bi+)kn}dPg+%JtZ#h%Rnd<^b$X*J@?rV2!Ycs?dLO4u
zC>|ySZ5ovTT4^j)8g~qIP$6!CN-pJ2hrWNnf$t2QY3Zyqm%P=^K$DqKpAN&ygDISo
ze}o_BOc4Q~Z6Gr_Ph;lcj%ZQ_=~Yr)v`}`-baeHat1n?>f>v;O^wXDo#I;(&JqWq~
zN9Br+*2%0&NEK{g1ft1muQ`N_y@UK87e$7{x{M<e8(m*t)RJo|l2XRUNAo=f`d;#r
qLriMCGvfQ-ZT$DIKm6<a@4o-+@Bd(z|M~rI|NL__jhD|3p8XGQBo^fW

literal 0
HcmV?d00001

diff --git a/core/tests/Drupal/KernelTests/Core/File/fixtures/cli_phar.png b/core/tests/Drupal/KernelTests/Core/File/fixtures/cli_phar.png
new file mode 100644
index 0000000000..275ccc13e7
--- /dev/null
+++ b/core/tests/Drupal/KernelTests/Core/File/fixtures/cli_phar.png
@@ -0,0 +1,348 @@
+<?php
+
+$web = '/index.php';
+
+if (in_array('phar', stream_get_wrappers()) && class_exists('Phar', 0)) {
+Phar::interceptFileFuncs();
+set_include_path('phar://' . __FILE__ . PATH_SEPARATOR . get_include_path());
+Phar::webPhar(null, $web);
+include 'phar://' . __FILE__ . '/' . Extract_Phar::START;
+return;
+}
+
+if (@(isset($_SERVER['REQUEST_URI']) && isset($_SERVER['REQUEST_METHOD']) && ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'POST'))) {
+Extract_Phar::go(true);
+$mimes = array(
+'phps' => 2,
+'c' => 'text/plain',
+'cc' => 'text/plain',
+'cpp' => 'text/plain',
+'c++' => 'text/plain',
+'dtd' => 'text/plain',
+'h' => 'text/plain',
+'log' => 'text/plain',
+'rng' => 'text/plain',
+'txt' => 'text/plain',
+'xsd' => 'text/plain',
+'php' => 1,
+'inc' => 1,
+'avi' => 'video/avi',
+'bmp' => 'image/bmp',
+'css' => 'text/css',
+'gif' => 'image/gif',
+'htm' => 'text/html',
+'html' => 'text/html',
+'htmls' => 'text/html',
+'ico' => 'image/x-ico',
+'jpe' => 'image/jpeg',
+'jpg' => 'image/jpeg',
+'jpeg' => 'image/jpeg',
+'js' => 'application/x-javascript',
+'midi' => 'audio/midi',
+'mid' => 'audio/midi',
+'mod' => 'audio/mod',
+'mov' => 'movie/quicktime',
+'mp3' => 'audio/mp3',
+'mpg' => 'video/mpeg',
+'mpeg' => 'video/mpeg',
+'pdf' => 'application/pdf',
+'png' => 'image/png',
+'swf' => 'application/shockwave-flash',
+'tif' => 'image/tiff',
+'tiff' => 'image/tiff',
+'wav' => 'audio/wav',
+'xbm' => 'image/xbm',
+'xml' => 'text/xml',
+);
+
+header("Cache-Control: no-cache, must-revalidate");
+header("Pragma: no-cache");
+
+$basename = basename(__FILE__);
+if (!strpos($_SERVER['REQUEST_URI'], $basename)) {
+chdir(Extract_Phar::$temp);
+include $web;
+return;
+}
+$pt = substr($_SERVER['REQUEST_URI'], strpos($_SERVER['REQUEST_URI'], $basename) + strlen($basename));
+if (!$pt || $pt == '/') {
+$pt = $web;
+header('HTTP/1.1 301 Moved Permanently');
+header('Location: ' . $_SERVER['REQUEST_URI'] . '/' . $pt);
+exit;
+}
+$a = realpath(Extract_Phar::$temp . DIRECTORY_SEPARATOR . $pt);
+if (!$a || strlen(dirname($a)) < strlen(Extract_Phar::$temp)) {
+header('HTTP/1.0 404 Not Found');
+echo "<html>\n <head>\n  <title>File Not Found<title>\n </head>\n <body>\n  <h1>404 - File Not Found</h1>\n </body>\n</html>";
+exit;
+}
+$b = pathinfo($a);
+if (!isset($b['extension'])) {
+header('Content-Type: text/plain');
+header('Content-Length: ' . filesize($a));
+readfile($a);
+exit;
+}
+if (isset($mimes[$b['extension']])) {
+if ($mimes[$b['extension']] === 1) {
+include $a;
+exit;
+}
+if ($mimes[$b['extension']] === 2) {
+highlight_file($a);
+exit;
+}
+header('Content-Type: ' .$mimes[$b['extension']]);
+header('Content-Length: ' . filesize($a));
+readfile($a);
+exit;
+}
+}
+
+class Extract_Phar
+{
+static $temp;
+static $origdir;
+const GZ = 0x1000;
+const BZ2 = 0x2000;
+const MASK = 0x3000;
+const START = 'index.php';
+const LEN = 6644;
+
+static function go($return = false)
+{
+$fp = fopen(__FILE__, 'rb');
+fseek($fp, self::LEN);
+$L = unpack('V', $a = fread($fp, 4));
+$m = '';
+
+do {
+$read = 8192;
+if ($L[1] - strlen($m) < 8192) {
+$read = $L[1] - strlen($m);
+}
+$last = fread($fp, $read);
+$m .= $last;
+} while (strlen($last) && strlen($m) < $L[1]);
+
+if (strlen($m) < $L[1]) {
+die('ERROR: manifest length read was "' .
+strlen($m) .'" should be "' .
+$L[1] . '"');
+}
+
+$info = self::_unpack($m);
+$f = $info['c'];
+
+if ($f & self::GZ) {
+if (!function_exists('gzinflate')) {
+die('Error: zlib extension is not enabled -' .
+' gzinflate() function needed for zlib-compressed .phars');
+}
+}
+
+if ($f & self::BZ2) {
+if (!function_exists('bzdecompress')) {
+die('Error: bzip2 extension is not enabled -' .
+' bzdecompress() function needed for bz2-compressed .phars');
+}
+}
+
+$temp = self::tmpdir();
+
+if (!$temp || !is_writable($temp)) {
+$sessionpath = session_save_path();
+if (strpos ($sessionpath, ";") !== false)
+$sessionpath = substr ($sessionpath, strpos ($sessionpath, ";")+1);
+if (!file_exists($sessionpath) || !is_dir($sessionpath)) {
+die('Could not locate temporary directory to extract phar');
+}
+$temp = $sessionpath;
+}
+
+$temp .= '/pharextract/'.basename(__FILE__, '.phar');
+self::$temp = $temp;
+self::$origdir = getcwd();
+@mkdir($temp, 0777, true);
+$temp = realpath($temp);
+
+if (!file_exists($temp . DIRECTORY_SEPARATOR . md5_file(__FILE__))) {
+self::_removeTmpFiles($temp, getcwd());
+@mkdir($temp, 0777, true);
+@file_put_contents($temp . '/' . md5_file(__FILE__), '');
+
+foreach ($info['m'] as $path => $file) {
+$a = !file_exists(dirname($temp . '/' . $path));
+@mkdir(dirname($temp . '/' . $path), 0777, true);
+clearstatcache();
+
+if ($path[strlen($path) - 1] == '/') {
+@mkdir($temp . '/' . $path, 0777);
+} else {
+file_put_contents($temp . '/' . $path, self::extractFile($path, $file, $fp));
+@chmod($temp . '/' . $path, 0666);
+}
+}
+}
+
+chdir($temp);
+
+if (!$return) {
+include self::START;
+}
+}
+
+static function tmpdir()
+{
+if (strpos(PHP_OS, 'WIN') !== false) {
+if ($var = getenv('TMP') ? getenv('TMP') : getenv('TEMP')) {
+return $var;
+}
+if (is_dir('/temp') || mkdir('/temp')) {
+return realpath('/temp');
+}
+return false;
+}
+if ($var = getenv('TMPDIR')) {
+return $var;
+}
+return realpath('/tmp');
+}
+
+static function _unpack($m)
+{
+$info = unpack('V', substr($m, 0, 4));
+ $l = unpack('V', substr($m, 10, 4));
+$m = substr($m, 14 + $l[1]);
+$s = unpack('V', substr($m, 0, 4));
+$o = 0;
+$start = 4 + $s[1];
+$ret['c'] = 0;
+
+for ($i = 0; $i < $info[1]; $i++) {
+ $len = unpack('V', substr($m, $start, 4));
+$start += 4;
+ $savepath = substr($m, $start, $len[1]);
+$start += $len[1];
+   $ret['m'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', substr($m, $start, 24)));
+$ret['m'][$savepath][3] = sprintf('%u', $ret['m'][$savepath][3]
+& 0xffffffff);
+$ret['m'][$savepath][7] = $o;
+$o += $ret['m'][$savepath][2];
+$start += 24 + $ret['m'][$savepath][5];
+$ret['c'] |= $ret['m'][$savepath][4] & self::MASK;
+}
+return $ret;
+}
+
+static function extractFile($path, $entry, $fp)
+{
+$data = '';
+$c = $entry[2];
+
+while ($c) {
+if ($c < 8192) {
+$data .= @fread($fp, $c);
+$c = 0;
+} else {
+$c -= 8192;
+$data .= @fread($fp, 8192);
+}
+}
+
+if ($entry[4] & self::GZ) {
+$data = gzinflate($data);
+} elseif ($entry[4] & self::BZ2) {
+$data = bzdecompress($data);
+}
+
+if (strlen($data) != $entry[0]) {
+die("Invalid internal .phar file (size error " . strlen($data) . " != " .
+$stat[7] . ")");
+}
+
+if ($entry[3] != sprintf("%u", crc32($data) & 0xffffffff)) {
+die("Invalid internal .phar file (checksum error)");
+}
+
+return $data;
+}
+
+static function _removeTmpFiles($temp, $origdir)
+{
+chdir($temp);
+
+foreach (glob('*') as $f) {
+if (file_exists($f)) {
+is_dir($f) ? @rmdir($f) : @unlink($f);
+if (file_exists($f) && is_dir($f)) {
+self::_removeTmpFiles($f, getcwd());
+}
+}
+}
+
+@rmdir($temp);
+clearstatcache();
+chdir($origdir);
+}
+}
+
+Extract_Phar::go();
+__HALT_COMPILER(); ?>
+7                  	   index.php  sÁ?\  Öå\¶      <?php
+
+/**
+ * @file
+ * Tests phar protection.
+ */
+
+use Drupal\Core\Security\PharExtensionInterceptor;
+use TYPO3\PharStreamWrapper\Behavior;
+use TYPO3\PharStreamWrapper\Exception as PharStreamWrapperException;
+use TYPO3\PharStreamWrapper\Manager;
+use TYPO3\PharStreamWrapper\PharStreamWrapper;
+
+// Use the current working directory so we don't have to include all the code in
+// the phar file.
+require_once getcwd() . '/../../../../../../../autoload.php';
+stream_wrapper_unregister('phar');
+stream_wrapper_register('phar', PharStreamWrapper::class);
+
+Manager::initialize(
+  (new Behavior())
+    ->withAssertion(new PharExtensionInterceptor())
+);
+
+if (file_exists(__DIR__ . '/index.php')) {
+  echo "Can access phar files without .phar extension if they are the CLI command.\n";
+}
+
+if (file_exists('phar://cli.phar')) {
+  echo "Can access phar files with .phar extension.\n";
+}
+
+// Try an insecure phar without an extension.
+try {
+  file_exists('phar://cli_phar.png');
+}
+catch (PharStreamWrapperException $e) {
+  echo "Cannot access other phar files without .phar extension.\n";
+}
+
+// Try accessing phar from a shutdown function.
+register_shutdown_function('phar_shutdown');
+
+function phar_shutdown() {
+  if (file_exists(__DIR__ . '/index.php')) {
+    echo "Shutdown functions work in phar files without a .phar extension.\n";
+  }
+  // Try an insecure phar without an extension.
+  try {
+    file_exists('phar://cli_phar.png');
+  }
+  catch (PharStreamWrapperException $e) {
+    echo "Shutdown functions cannot access other phar files without .phar extension.\n";
+  }
+}
+m*ˆ4ä¦åÊŽˆŽ8º» vÚ#^   GBMB
\ No newline at end of file
diff --git a/core/tests/Drupal/KernelTests/Core/File/fixtures/cli_phar_builder/index.php b/core/tests/Drupal/KernelTests/Core/File/fixtures/cli_phar_builder/index.php
new file mode 100644
index 0000000000..a8d7d6707d
--- /dev/null
+++ b/core/tests/Drupal/KernelTests/Core/File/fixtures/cli_phar_builder/index.php
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * @file
+ * Tests phar protection.
+ */
+
+use Drupal\Core\Security\PharExtensionInterceptor;
+use TYPO3\PharStreamWrapper\Behavior;
+use TYPO3\PharStreamWrapper\Exception as PharStreamWrapperException;
+use TYPO3\PharStreamWrapper\Manager;
+use TYPO3\PharStreamWrapper\PharStreamWrapper;
+
+// Use the current working directory so we don't have to include all the code in
+// the phar file.
+require_once getcwd() . '/../../../../../../../autoload.php';
+stream_wrapper_unregister('phar');
+stream_wrapper_register('phar', PharStreamWrapper::class);
+
+Manager::initialize(
+  (new Behavior())
+    ->withAssertion(new PharExtensionInterceptor())
+);
+
+if (file_exists(__DIR__ . '/index.php')) {
+  echo "Can access phar files without .phar extension if they are the CLI command.\n";
+}
+
+if (file_exists('phar://cli.phar')) {
+  echo "Can access phar files with .phar extension.\n";
+}
+
+// Try an insecure phar without an extension.
+try {
+  file_exists('phar://cli_phar.png');
+}
+catch (PharStreamWrapperException $e) {
+  echo "Cannot access other phar files without .phar extension.\n";
+}
+
+// Try accessing phar from a shutdown function.
+register_shutdown_function('phar_shutdown');
+
+function phar_shutdown() {
+  if (file_exists(__DIR__ . '/index.php')) {
+    echo "Shutdown functions work in phar files without a .phar extension.\n";
+  }
+  // Try an insecure phar without an extension.
+  try {
+    file_exists('phar://cli_phar.png');
+  }
+  catch (PharStreamWrapperException $e) {
+    echo "Shutdown functions cannot access other phar files without .phar extension.\n";
+  }
+}
