80 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			80 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?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.
 | 
						|
 *
 | 
						|
 * @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 Exception
 | 
						|
   *   Thrown when the file is not allowed to execute.
 | 
						|
   */
 | 
						|
  public function assert($path, $command) {
 | 
						|
    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 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';
 | 
						|
  }
 | 
						|
 | 
						|
}
 |