Guest User

go-pear.phar

a guest
Feb 11th, 2013
320
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <?php
  2. error_reporting(1803);
  3. if (function_exists('mb_internal_encoding')) {
  4.     mb_internal_encoding('ASCII');
  5. }
  6. if (!class_exists('PHP_Archive')) {/**
  7.  * PHP_Archive Class (implements .phar)
  8.  *
  9.  * @package PHP_Archive
  10.  * @category PHP
  11.  */
  12. /**
  13.  * PHP_Archive Class (implements .phar)
  14.  *
  15.  * PHAR files a singular archive from which an entire application can run.
  16.  * To use it, simply package it using {@see PHP_Archive_Creator} and use phar://
  17.  * URIs to your includes. i.e. require_once 'phar://config.php' will include config.php
  18.  * from the root of the PHAR file.
  19.  *
  20.  * Gz code borrowed from the excellent File_Archive package by Vincent Lascaux.
  21.  *
  22.  * @copyright Copyright David Shafik and Synaptic Media 2004. All rights reserved.
  23.  * @author Davey Shafik <davey@synapticmedia.net>
  24.  * @author Greg Beaver <cellog@php.net>
  25.  * @link http://www.synapticmedia.net Synaptic Media
  26.  * @version Id: Archive.php,v 1.52 2007/09/01 20:28:14 cellog Exp $
  27.  * @package PHP_Archive
  28.  * @category PHP
  29.  */
  30.  
  31. class PHP_Archive
  32. {
  33.     const GZ = 0x00001000;
  34.     const BZ2 = 0x00002000;
  35.     const SIG = 0x00010000;
  36.     const SHA1 = 0x0002;
  37.     const MD5 = 0x0001;
  38.     /**
  39.      * Whether this archive is compressed with zlib
  40.      *
  41.      * @var bool
  42.      */
  43.     private $_compressed;
  44.     /**
  45.      * @var string Real path to the .phar archive
  46.      */
  47.     private $_archiveName = null;
  48.     /**
  49.      * Current file name in the phar
  50.      * @var string
  51.      */
  52.     protected $currentFilename = null;
  53.     /**
  54.      * Length of current file in the phar
  55.      * @var string
  56.      */
  57.     protected $internalFileLength = null;
  58.     /**
  59.      * Current file statistics (size, creation date, etc.)
  60.      * @var string
  61.      */
  62.     protected $currentStat = null;
  63.     /**
  64.      * @var resource|null Pointer to open .phar
  65.      */
  66.     protected $fp = null;
  67.     /**
  68.      * @var int Current Position of the pointer
  69.      */
  70.     protected $position = 0;
  71.  
  72.     /**
  73.      * Map actual realpath of phars to meta-data about the phar
  74.      *
  75.      * Data is indexed by the alias that is used by internal files.  In other
  76.      * words, if a file is included via:
  77.      * <code>
  78.      * require_once 'phar://PEAR.phar/PEAR/Installer.php';
  79.      * </code>
  80.      * then the alias is "PEAR.phar"
  81.      *
  82.      * Information stored is a boolean indicating whether this .phar is compressed
  83.      * with zlib, another for bzip2, phar-specific meta-data, and
  84.      * the precise offset of internal files
  85.      * within the .phar, used with the {@link $_manifest} to load actual file contents
  86.      * @var array
  87.      */
  88.     private static $_pharMapping = array();
  89.     /**
  90.      * Map real file paths to alias used
  91.      *
  92.      * @var array
  93.      */
  94.     private static $_pharFiles = array();
  95.     /**
  96.      * File listing for the .phar
  97.      *
  98.      * The manifest is indexed per phar.
  99.      *
  100.      * Files within the .phar are indexed by their relative path within the
  101.      * .phar.  Each file has this information in its internal array
  102.      *
  103.      * - 0 = uncompressed file size
  104.      * - 1 = timestamp of when file was added to phar
  105.      * - 2 = offset of file within phar relative to internal file's start
  106.      * - 3 = compressed file size (actual size in the phar)
  107.      * @var array
  108.      */
  109.     private static $_manifest = array();
  110.     /**
  111.      * Absolute offset of internal files within the .phar, indexed by absolute
  112.      * path to the .phar
  113.      *
  114.      * @var array
  115.      */
  116.     private static $_fileStart = array();
  117.     /**
  118.      * file name of the phar
  119.      *
  120.      * @var string
  121.      */
  122.     private $_basename;
  123.  
  124.  
  125.     /**
  126.      * Default MIME types used for the web front controller
  127.      *
  128.      * @var array
  129.      */
  130.     public static $defaultmimes = array(
  131.             'aif' => 'audio/x-aiff',
  132.             'aiff' => 'audio/x-aiff',
  133.             'arc' => 'application/octet-stream',
  134.             'arj' => 'application/octet-stream',
  135.             'art' => 'image/x-jg',
  136.             'asf' => 'video/x-ms-asf',
  137.             'asx' => 'video/x-ms-asf',
  138.             'avi' => 'video/avi',
  139.             'bin' => 'application/octet-stream',
  140.             'bm' => 'image/bmp',
  141.             'bmp' => 'image/bmp',
  142.             'bz2' => 'application/x-bzip2',
  143.             'css' => 'text/css',
  144.             'doc' => 'application/msword',
  145.             'dot' => 'application/msword',
  146.             'dv' => 'video/x-dv',
  147.             'dvi' => 'application/x-dvi',
  148.             'eps' => 'application/postscript',
  149.             'exe' => 'application/octet-stream',
  150.             'gif' => 'image/gif',
  151.             'gz' => 'application/x-gzip',
  152.             'gzip' => 'application/x-gzip',
  153.             'htm' => 'text/html',
  154.             'html' => 'text/html',
  155.             'ico' => 'image/x-icon',
  156.             'jpe' => 'image/jpeg',
  157.             'jpg' => 'image/jpeg',
  158.             'jpeg' => 'image/jpeg',
  159.             'js' => 'application/x-javascript',
  160.             'log' => 'text/plain',
  161.             'mid' => 'audio/x-midi',
  162.             'mov' => 'video/quicktime',
  163.             'mp2' => 'audio/mpeg',
  164.             'mp3' => 'audio/mpeg3',
  165.             'mpg' => 'audio/mpeg',
  166.             'pdf' => 'aplication/pdf',
  167.             'png' => 'image/png',
  168.             'rtf' => 'application/rtf',
  169.             'tif' => 'image/tiff',
  170.             'tiff' => 'image/tiff',
  171.             'txt' => 'text/plain',
  172.             'xml' => 'text/xml',
  173.         );
  174.  
  175.     public static $defaultphp = array(
  176.         'php' => true
  177.         );
  178.  
  179.     public static $defaultphps = array(
  180.         'phps' => true
  181.         );
  182.  
  183.     public static $deny = array('/.+\.inc$/');
  184.  
  185.     public static function viewSource($archive, $file)
  186.     {
  187.         // security, idea borrowed from PHK
  188.         if (!file_exists($archive . '.introspect')) {
  189.             header("HTTP/1.0 404 Not Found");
  190.             return false;
  191.         }
  192.         if (self::_fileExists($archive, $_GET['viewsource'])) {
  193.             $source = highlight_file('phar://go-pear.phar/' .
  194.                 $_GET['viewsource'], true);
  195.             header('Content-Type: text/html');
  196.             header('Content-Length: ' . strlen($source));
  197.             echo '<html><head><title>Source of ',
  198.                 htmlspecialchars($_GET['viewsource']), '</title></head>';
  199.             echo '<body><h1>Source of ',
  200.                 htmlspecialchars($_GET['viewsource']), '</h1>';
  201.             if (isset($_GET['introspect'])) {
  202.                 echo '<a href="', htmlspecialchars($_SERVER['PHP_SELF']),
  203.                     '?introspect=', urlencode(htmlspecialchars($_GET['introspect'])),
  204.                     '">Return to ', htmlspecialchars($_GET['introspect']), '</a><br />';
  205.             }
  206.             echo $source;
  207.             return false;
  208.         } else {
  209.             header("HTTP/1.0 404 Not Found");
  210.             return false;
  211.         }
  212.        
  213.     }
  214.  
  215.     public static function introspect($archive, $dir)
  216.     {
  217.         // security, idea borrowed from PHK
  218.         if (!file_exists($archive . '.introspect')) {
  219.             header("HTTP/1.0 404 Not Found");
  220.             return false;
  221.         }
  222.         if (!$dir) {
  223.             $dir = '/';
  224.         }
  225.         $dir = self::processFile($dir);
  226.         if ($dir[0] != '/') {
  227.             $dir = '/' . $dir;
  228.         }
  229.         try {
  230.             $self = htmlspecialchars($_SERVER['PHP_SELF']);
  231.             $iterate = new DirectoryIterator('phar://go-pear.phar' . $dir);
  232.             echo '<html><head><title>Introspect ', htmlspecialchars($dir),
  233.                 '</title></head><body><h1>Introspect ', htmlspecialchars($dir),
  234.                 '</h1><ul>';
  235.             if ($dir != '/') {
  236.                 echo '<li><a href="', $self, '?introspect=',
  237.                     htmlspecialchars(dirname($dir)), '">..</a></li>';
  238.             }
  239.             foreach ($iterate as $entry) {
  240.                 if ($entry->isDot()) continue;
  241.                 $name = self::processFile($entry->getPathname());
  242.                 $name = str_replace('phar://go-pear.phar/', '', $name);
  243.                 if ($entry->isDir()) {
  244.                     echo '<li><a href="', $self, '?introspect=',
  245.                         urlencode(htmlspecialchars($name)),
  246.                         '">',
  247.                         htmlspecialchars($entry->getFilename()), '/</a> [directory]</li>';
  248.                 } else {
  249.                     echo '<li><a href="', $self, '?introspect=',
  250.                         urlencode(htmlspecialchars($dir)), '&viewsource=',
  251.                         urlencode(htmlspecialchars($name)),
  252.                         '">',
  253.                         htmlspecialchars($entry->getFilename()), '</a></li>';
  254.                 }
  255.             }
  256.             return false;
  257.         } catch (Exception $e) {
  258.             echo '<html><head><title>Directory not found: ',
  259.                 htmlspecialchars($dir), '</title></head>',
  260.                 '<body><h1>Directory not found: ', htmlspecialchars($dir), '</h1>',
  261.                 '<p>Try <a href="', htmlspecialchars($_SERVER['PHP_SELF']), '?introspect=/">',
  262.                 'This link</a></p></body></html>';
  263.             return false;
  264.         }
  265.     }
  266.  
  267.     public static function webFrontController($initfile)
  268.     {
  269.         if (isset($_SERVER) && isset($_SERVER['REQUEST_URI'])) {
  270.             $uri = parse_url($_SERVER['REQUEST_URI']);
  271.             $archive = realpath($_SERVER['SCRIPT_FILENAME']);
  272.             $subpath = str_replace('/' . basename($archive), '', $uri['path']);
  273.             if (!$subpath || $subpath == '/') {
  274.                 if (isset($_GET['viewsource'])) {
  275.                     return self::viewSource($archive, $_GET['viewsource']);
  276.                 }
  277.                 if (isset($_GET['introspect'])) {
  278.                     return self::introspect($archive, $_GET['introspect']);
  279.                 }
  280.                 $subpath = '/' . $initfile;
  281.             }
  282.             if (!self::_fileExists($archive, substr($subpath, 1))) {
  283.                 header("HTTP/1.0 404 Not Found");
  284.                 return false;
  285.             }
  286.             foreach (self::$deny as $pattern) {
  287.                 if (preg_match($pattern, $subpath)) {
  288.                     header("HTTP/1.0 404 Not Found");
  289.                     return false;
  290.                 }
  291.             }
  292.             $inf = pathinfo(basename($subpath));
  293.             if (!isset($inf['extension'])) {
  294.                 header('Content-Type: text/plain');
  295.                 header('Content-Length: ' .
  296.                     self::_filesize($archive, substr($subpath, 1)));
  297.                 readfile('phar://go-pear.phar' . $subpath);
  298.                 return false;
  299.             }
  300.             if (isset(self::$defaultphp[$inf['extension']])) {
  301.                 include 'phar://go-pear.phar' . $subpath;
  302.                 return false;
  303.             }
  304.             if (isset(self::$defaultmimes[$inf['extension']])) {
  305.                 header('Content-Type: ' . self::$defaultmimes[$inf['extension']]);
  306.                 header('Content-Length: ' .
  307.                     self::_filesize($archive, substr($subpath, 1)));
  308.                 readfile('phar://go-pear.phar' . $subpath);
  309.                 return false;
  310.             }
  311.             if (isset(self::$defaultphps[$inf['extension']])) {
  312.                 header('Content-Type: text/html');
  313.                 $c = highlight_file('phar://go-pear.phar' . $subpath, true);
  314.                 header('Content-Length: ' . strlen($c));
  315.                 echo $c;
  316.                 return false;
  317.             }
  318.             header('Content-Type: text/plain');
  319.             header('Content-Length: ' .
  320.                     self::_filesize($archive, substr($subpath, 1)));
  321.             readfile('phar://go-pear.phar' . $subpath);
  322.         }
  323.     }
  324.  
  325.     /**
  326.      * Detect end of stub
  327.      *
  328.      * @param string $buffer stub past '__HALT_'.'COMPILER();'
  329.      * @return end of stub, prior to length of manifest.
  330.      */
  331.     private static final function _endOfStubLength($buffer)
  332.     {
  333.         $pos = 0;
  334.         if (!strlen($buffer)) {
  335.             return $pos;
  336.         }
  337.         if (($buffer[0] == ' ' || $buffer[0] == "\n") && @substr($buffer, 1, 2) == '')
  338.         {
  339.             $pos += 3;
  340.             if ($buffer[$pos] == "\r" && $buffer[$pos+1] == "\n") {
  341.                 $pos += 2;
  342.             }
  343.             else if ($buffer[$pos] == "\n") {
  344.                 $pos += 1;
  345.             }
  346.         }
  347.         return $pos;
  348.     }
  349.  
  350.     /**
  351.      * Allows loading an external Phar archive without include()ing it
  352.      *
  353.      * @param string $file  phar package to load
  354.      * @param string $alias alias to use
  355.      * @throws Exception
  356.      */
  357.     public static final function loadPhar($file, $alias = NULL)
  358.     {
  359.         $file = realpath($file);
  360.         if ($file) {
  361.             $fp = fopen($file, 'rb');
  362.             $buffer = '';
  363.             while (!feof($fp)) {
  364.                 $buffer .= fread($fp, 8192);
  365.                 // don't break phars
  366.                 if ($pos = strpos($buffer, '__HALT_COMPI' . 'LER();')) {
  367.                     $buffer .= fread($fp, 5);
  368.                     fclose($fp);
  369.                     $pos += 18;
  370.                     $pos += self::_endOfStubLength(substr($buffer, $pos));
  371.                     return self::_mapPhar($file, $pos, $alias);
  372.                 }
  373.             }
  374.             fclose($fp);
  375.         }
  376.     }
  377.  
  378.     /**
  379.      * Map a full real file path to an alias used to refer to the .phar
  380.      *
  381.      * This function can only be called from the initialization of the .phar itself.
  382.      * Any attempt to call from outside the .phar or to re-alias the .phar will fail
  383.      * as a security measure.
  384.      * @param string $alias
  385.      * @param int $dataoffset the value of 42313                  
  386.      */
  387.     public static final function mapPhar($alias = NULL, $dataoffset = NULL)
  388.     {
  389.         try {
  390.             $trace = debug_backtrace();
  391.             $file = $trace[0]['file'];
  392.             // this ensures that this is safe
  393.             if (!in_array($file, get_included_files())) {
  394.                 die('SECURITY ERROR: PHP_Archive::mapPhar can only be called from within ' .
  395.                     'the phar that initiates it');
  396.             }
  397.             $file = realpath($file);
  398.             if (!isset($dataoffset)) {
  399.                 $dataoffset = constant('__COMPILER_HALT_OFFSET'.'__');
  400.                 $fp = fopen($file, 'rb');
  401.                 fseek($fp, $dataoffset, SEEK_SET);
  402.                 $dataoffset = $dataoffset + self::_endOfStubLength(fread($fp, 5));
  403.                 fclose($fp);
  404.             }
  405.  
  406.             self::_mapPhar($file, $dataoffset);
  407.         } catch (Exception $e) {
  408.             die($e->getMessage());
  409.         }
  410.     }
  411.  
  412.     /**
  413.      * Sub-function, allows recovery from errors
  414.      *
  415.      * @param unknown_type $file
  416.      * @param unknown_type $dataoffset
  417.      */
  418.     private static function _mapPhar($file, $dataoffset, $alias = NULL)
  419.     {
  420.         $file = realpath($file);
  421.         if (isset(self::$_manifest[$file])) {
  422.             return;
  423.         }
  424.         if (!is_array(self::$_pharMapping)) {
  425.             self::$_pharMapping = array();
  426.         }
  427.         $fp = fopen($file, 'rb');
  428.         // seek to __HALT_COMPILER_OFFSET__
  429.         fseek($fp, $dataoffset);
  430.         $manifest_length = unpack('Vlen', fread($fp, 4));
  431.         $manifest = '';
  432.         $last = '1';
  433.         while (strlen($last) && strlen($manifest) < $manifest_length['len']) {
  434.             $read = 8192;
  435.             if ($manifest_length['len'] - strlen($manifest) < 8192) {
  436.                 $read = $manifest_length['len'] - strlen($manifest);
  437.             }
  438.             $last = fread($fp, $read);
  439.             $manifest .= $last;
  440.         }
  441.         if (strlen($manifest) < $manifest_length['len']) {
  442.             throw new Exception('ERROR: manifest length read was "' .
  443.                 strlen($manifest) .'" should be "' .
  444.                 $manifest_length['len'] . '"');
  445.         }
  446.         $info = self::_unserializeManifest($manifest);
  447.         if ($info['alias']) {
  448.             $alias = $info['alias'];
  449.             $explicit = true;
  450.         } else {
  451.             if (!isset($alias)) {
  452.                 $alias = $file;
  453.             }
  454.             $explicit = false;
  455.         }
  456.         self::$_manifest[$file] = $info['manifest'];
  457.         $compressed = $info['compressed'];
  458.         self::$_fileStart[$file] = ftell($fp);
  459.         fclose($fp);
  460.         if ($compressed & 0x00001000) {
  461.             if (!function_exists('gzinflate')) {
  462.                 throw new Exception('Error: zlib extension is not enabled - gzinflate() function needed' .
  463.                     ' for compressed .phars');
  464.             }
  465.         }
  466.         if ($compressed & 0x00002000) {
  467.             if (!function_exists('bzdecompress')) {
  468.                 throw new Exception('Error: bzip2 extension is not enabled - bzdecompress() function needed' .
  469.                     ' for compressed .phars');
  470.             }
  471.         }
  472.         if (isset(self::$_pharMapping[$alias])) {
  473.             throw new Exception('ERROR: PHP_Archive::mapPhar has already been called for alias "' .
  474.                 $alias . '" cannot re-alias to "' . $file . '"');
  475.         }
  476.         self::$_pharMapping[$alias] = array($file, $compressed, $dataoffset, $explicit,
  477.             $info['metadata']);
  478.         self::$_pharFiles[$file] = $alias;
  479.     }
  480.  
  481.     /**
  482.      * extract the manifest into an internal array
  483.      *
  484.      * @param string $manifest
  485.      * @return false|array
  486.      */
  487.     private static function _unserializeManifest($manifest)
  488.     {
  489.         // retrieve the number of files in the manifest
  490.         $info = unpack('V', substr($manifest, 0, 4));
  491.         $apiver = substr($manifest, 4, 2);
  492.         $apiver = bin2hex($apiver);
  493.         $apiver_dots = hexdec($apiver[0]) . '.' . hexdec($apiver[1]) . '.' . hexdec($apiver[2]);
  494.         $majorcompat = hexdec($apiver[0]);
  495.         $calcapi = explode('.', self::APIVersion());
  496.         if ($calcapi[0] != $majorcompat) {
  497.             throw new Exception('Phar is incompatible API version ' . $apiver_dots . ', but ' .
  498.                 'PHP_Archive is API version '.self::APIVersion());
  499.         }
  500.         if ($calcapi[0] === '0') {
  501.             if (self::APIVersion() != $apiver_dots) {
  502.                 throw new Exception('Phar is API version ' . $apiver_dots .
  503.                     ', but PHP_Archive is API version '.self::APIVersion(), E_USER_ERROR);
  504.             }
  505.         }
  506.         $flags = unpack('V', substr($manifest, 6, 4));
  507.         $ret = array('compressed' => $flags & 0x00003000);
  508.         // signature is not verified by default in PHP_Archive, phar is better
  509.         $ret['hassignature'] = $flags & 0x00010000;
  510.         $aliaslen = unpack('V', substr($manifest, 10, 4));
  511.         if ($aliaslen) {
  512.             $ret['alias'] = substr($manifest, 14, $aliaslen[1]);
  513.         } else {
  514.             $ret['alias'] = false;
  515.         }
  516.         $manifest = substr($manifest, 14 + $aliaslen[1]);
  517.         $metadatalen = unpack('V', substr($manifest, 0, 4));
  518.         if ($metadatalen[1]) {
  519.             $ret['metadata'] = unserialize(substr($manifest, 4, $metadatalen[1]));
  520.             $manifest = substr($manifest, 4 + $metadatalen[1]);
  521.         } else {
  522.             $ret['metadata'] = null;
  523.             $manifest = substr($manifest, 4);
  524.         }
  525.         $offset = 0;
  526.         $start = 0;
  527.         for ($i = 0; $i < $info[1]; $i++) {
  528.             // length of the file name
  529.             $len = unpack('V', substr($manifest, $start, 4));
  530.             $start += 4;
  531.             // file name
  532.             $savepath = substr($manifest, $start, $len[1]);
  533.             $start += $len[1];
  534.             // retrieve manifest data:
  535.             // 0 = uncompressed file size
  536.             // 1 = timestamp of when file was added to phar
  537.             // 2 = compressed filesize
  538.             // 3 = crc32
  539.             // 4 = flags
  540.             // 5 = metadata length
  541.             $ret['manifest'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', substr($manifest, $start, 24)));
  542.             $ret['manifest'][$savepath][3] = sprintf('%u', $ret['manifest'][$savepath][3]
  543.                 & 0xffffffff);
  544.             if ($ret['manifest'][$savepath][5]) {
  545.                 $ret['manifest'][$savepath][6] = unserialize(substr($manifest, $start + 24,
  546.                     $ret['manifest'][$savepath][5]));
  547.             } else {
  548.                 $ret['manifest'][$savepath][6] = null;
  549.             }
  550.             $ret['manifest'][$savepath][7] = $offset;
  551.             $offset += $ret['manifest'][$savepath][2];
  552.             $start += 24 + $ret['manifest'][$savepath][5];
  553.         }
  554.         return $ret;
  555.     }
  556.  
  557.     /**
  558.      * @param string
  559.      */
  560.     private static function processFile($path)
  561.     {
  562.         if ($path == '.') {
  563.             return '';
  564.         }
  565.         $std = str_replace("\\", "/", $path);
  566.         while ($std != ($std = ereg_replace("[^\/:?]+/\.\./", "", $std))) ;
  567.         $std = str_replace("/./", "", $std);
  568.         if (strlen($std) > 1 && $std[0] == '/') {
  569.             $std = substr($std, 1);
  570.         }
  571.         if (strncmp($std, "./", 2) == 0) {
  572.             return substr($std, 2);
  573.         } else {
  574.             return $std;
  575.         }
  576.     }
  577.  
  578.     /**
  579.      * Seek in the master archive to a matching file or directory
  580.      * @param string
  581.      */
  582.     protected function selectFile($path, $allowdirs = true)
  583.     {
  584.         $std = self::processFile($path);
  585.         if (isset(self::$_manifest[$this->_archiveName][$path])) {
  586.             $this->_setCurrentFile($path);
  587.             return true;
  588.         }
  589.         if (!$allowdirs) {
  590.             return 'Error: "' . $path . '" is not a file in phar "' . $this->_basename . '"';
  591.         }
  592.         foreach (self::$_manifest[$this->_archiveName] as $file => $info) {
  593.             if (empty($std) ||
  594.                   //$std is a directory
  595.                   strncmp($std.'/', $path, strlen($std)+1) == 0) {
  596.                 $this->currentFilename = $this->internalFileLength = $this->currentStat = null;
  597.                 return true;
  598.             }
  599.         }
  600.         return 'Error: "' . $path . '" not found in phar "' . $this->_basename . '"';
  601.     }
  602.  
  603.     private function _setCurrentFile($path)
  604.     {
  605.         $this->currentStat = array(
  606.             2 => 0100444, // file mode, readable by all, writeable by none
  607.             4 => 0, // uid
  608.             5 => 0, // gid
  609.             7 => self::$_manifest[$this->_archiveName][$path][0], // size
  610.             9 => self::$_manifest[$this->_archiveName][$path][1], // creation time
  611.             );
  612.         $this->currentFilename = $path;
  613.         $this->internalFileLength = self::$_manifest[$this->_archiveName][$path][2];
  614.         // seek to offset of file header within the .phar
  615.         if (is_resource(@$this->fp)) {
  616.             fseek($this->fp, self::$_fileStart[$this->_archiveName] + self::$_manifest[$this->_archiveName][$path][7]);
  617.         }
  618.     }
  619.  
  620.     private static function _fileExists($archive, $path)
  621.     {
  622.         return isset(self::$_manifest[$archive]) &&
  623.             isset(self::$_manifest[$archive][$path]);
  624.     }
  625.  
  626.     private static function _filesize($archive, $path)
  627.     {
  628.         return self::$_manifest[$archive][$path][0];
  629.     }
  630.  
  631.     /**
  632.      * Seek to a file within the master archive, and extract its contents
  633.      * @param string
  634.      * @return array|string an array containing an error message string is returned
  635.      *                      upon error, otherwise the file contents are returned
  636.      */
  637.     public function extractFile($path)
  638.     {
  639.         $this->fp = @fopen($this->_archiveName, "rb");
  640.         if (!$this->fp) {
  641.             return array('Error: cannot open phar "' . $this->_archiveName . '"');
  642.         }
  643.         if (($e = $this->selectFile($path, false)) === true) {
  644.             $data = '';
  645.             $count = $this->internalFileLength;
  646.             while ($count) {
  647.                 if ($count < 8192) {
  648.                     $data .= @fread($this->fp, $count);
  649.                     $count = 0;
  650.                 } else {
  651.                     $count -= 8192;
  652.                     $data .= @fread($this->fp, 8192);
  653.                 }
  654.             }
  655.             @fclose($this->fp);
  656.             if (self::$_manifest[$this->_archiveName][$path][4] & self::GZ) {
  657.                 $data = gzinflate($data);
  658.             } elseif (self::$_manifest[$this->_archiveName][$path][4] & self::BZ2) {
  659.                 $data = bzdecompress($data);
  660.             }
  661.             if (!isset(self::$_manifest[$this->_archiveName][$path]['ok'])) {
  662.                 if (strlen($data) != $this->currentStat[7]) {
  663.                     return array("Not valid internal .phar file (size error {$size} != " .
  664.                         $this->currentStat[7] . ")");
  665.                 }
  666.                 if (self::$_manifest[$this->_archiveName][$path][3] != sprintf("%u", crc32($data) & 0xffffffff)) {
  667.                     return array("Not valid internal .phar file (checksum error)");
  668.                 }
  669.                 self::$_manifest[$this->_archiveName][$path]['ok'] = true;
  670.             }
  671.             return $data;
  672.         } else {
  673.             @fclose($this->fp);
  674.             return array($e);
  675.         }
  676.     }
  677.  
  678.     /**
  679.      * Parse urls like phar:///fullpath/to/my.phar/file.txt
  680.      *
  681.      * @param string $file
  682.      * @return false|array
  683.      */
  684.     static protected function parseUrl($file)
  685.     {
  686.         if (substr($file, 0, 7) != 'phar://') {
  687.             return false;
  688.         }
  689.         $file = substr($file, 7);
  690.    
  691.         $ret = array('scheme' => 'phar');
  692.         $pos_p = strpos($file, '.phar.php');
  693.         $pos_z = strpos($file, '.phar.gz');
  694.         $pos_b = strpos($file, '.phar.bz2');
  695.         if ($pos_p) {
  696.             if ($pos_z) {
  697.                 return false;
  698.             }
  699.             $ret['host'] = substr($file, 0, $pos_p + strlen('.phar.php'));
  700.             $ret['path'] = substr($file, strlen($ret['host']));
  701.         } elseif ($pos_z) {
  702.             $ret['host'] = substr($file, 0, $pos_z + strlen('.phar.gz'));
  703.             $ret['path'] = substr($file, strlen($ret['host']));
  704.         } elseif ($pos_b) {
  705.             $ret['host'] = substr($file, 0, $pos_z + strlen('.phar.bz2'));
  706.             $ret['path'] = substr($file, strlen($ret['host']));
  707.         } elseif (($pos_p = strpos($file, ".phar")) !== false) {
  708.             $ret['host'] = substr($file, 0, $pos_p + strlen('.phar'));
  709.             $ret['path'] = substr($file, strlen($ret['host']));
  710.         } else {
  711.             return false;
  712.         }
  713.         if (!$ret['path']) {
  714.             $ret['path'] = '/';
  715.         }
  716.         return $ret;
  717.     }
  718.    
  719.     /**
  720.      * Locate the .phar archive in the include_path and detect the file to open within
  721.      * the archive.
  722.      *
  723.      * Possible parameters are phar://pharname.phar/filename_within_phar.ext
  724.      * @param string a file within the archive
  725.      * @return string the filename within the .phar to retrieve
  726.      */
  727.     public function initializeStream($file)
  728.     {
  729.         $file = self::processFile($file);
  730.         $info = @parse_url($file);
  731.         if (!$info) {
  732.             $info = self::parseUrl($file);
  733.         }
  734.         if (!$info) {
  735.             return false;
  736.         }
  737.         if (!isset($info['host'])) {
  738.             // malformed internal file
  739.             return false;
  740.         }
  741.         if (!isset(self::$_pharFiles[$info['host']]) &&
  742.               !isset(self::$_pharMapping[$info['host']])) {
  743.             try {
  744.                 self::loadPhar($info['host']);
  745.                 // use alias from here out
  746.                 $info['host'] = self::$_pharFiles[$info['host']];
  747.             } catch (Exception $e) {
  748.                 return false;
  749.             }
  750.         }
  751.         if (!isset($info['path'])) {
  752.             return false;
  753.         } elseif (strlen($info['path']) > 1) {
  754.             $info['path'] = substr($info['path'], 1);
  755.         }
  756.         if (isset(self::$_pharMapping[$info['host']])) {
  757.             $this->_basename = $info['host'];
  758.             $this->_archiveName = self::$_pharMapping[$info['host']][0];
  759.             $this->_compressed = self::$_pharMapping[$info['host']][1];
  760.         } elseif (isset(self::$_pharFiles[$info['host']])) {
  761.             $this->_archiveName = $info['host'];
  762.             $this->_basename = self::$_pharFiles[$info['host']];
  763.             $this->_compressed = self::$_pharMapping[$this->_basename][1];
  764.         }
  765.         $file = $info['path'];
  766.         return $file;
  767.     }
  768.  
  769.     /**
  770.      * Open the requested file - PHP streams API
  771.      *
  772.      * @param string $file String provided by the Stream wrapper
  773.      * @access private
  774.      */
  775.     public function stream_open($file)
  776.     {
  777.         return $this->_streamOpen($file);
  778.     }
  779.  
  780.     /**
  781.      * @param string filename to opne, or directory name
  782.      * @param bool if true, a directory will be matched, otherwise only files
  783.      *             will be matched
  784.      * @uses trigger_error()
  785.      * @return bool success of opening
  786.      * @access private
  787.      */
  788.     private function _streamOpen($file, $searchForDir = false)
  789.     {
  790.         $path = $this->initializeStream($file);
  791.         if (!$path) {
  792.             trigger_error('Error: Unknown phar in "' . $file . '"', E_USER_ERROR);
  793.         }
  794.         if (is_array($this->file = $this->extractFile($path))) {
  795.             trigger_error($this->file[0], E_USER_ERROR);
  796.             return false;
  797.         }
  798.         if ($path != $this->currentFilename) {
  799.             if (!$searchForDir) {
  800.                 trigger_error("Cannot open '$file', is a directory", E_USER_ERROR);
  801.                 return false;
  802.             } else {
  803.                 $this->file = '';
  804.                 return true;
  805.             }
  806.         }
  807.  
  808.         if (!is_null($this->file) && $this->file !== false) {
  809.             return true;
  810.         } else {
  811.             return false;
  812.         }
  813.     }
  814.    
  815.     /**
  816.      * Read the data - PHP streams API
  817.      *
  818.      * @param int
  819.      * @access private
  820.      */
  821.     public function stream_read($count)
  822.     {
  823.         $ret = substr($this->file, $this->position, $count);
  824.         $this->position += strlen($ret);
  825.         return $ret;
  826.     }
  827.    
  828.     /**
  829.      * Whether we've hit the end of the file - PHP streams API
  830.      * @access private
  831.      */
  832.     function stream_eof()
  833.     {
  834.         return $this->position >= $this->currentStat[7];
  835.     }
  836.    
  837.     /**
  838.      * For seeking the stream - PHP streams API
  839.      * @param int
  840.      * @param SEEK_SET|SEEK_CUR|SEEK_END
  841.      * @access private
  842.      */
  843.     public function stream_seek($pos, $whence)
  844.     {
  845.         switch ($whence) {
  846.             case SEEK_SET:
  847.                 if ($pos < 0) {
  848.                     return false;
  849.                 }
  850.                 $this->position = $pos;
  851.                 break;
  852.             case SEEK_CUR:
  853.                 if ($pos + $this->currentStat[7] < 0) {
  854.                     return false;
  855.                 }
  856.                 $this->position += $pos;
  857.                 break;
  858.             case SEEK_END:
  859.                 if ($pos + $this->currentStat[7] < 0) {
  860.                     return false;
  861.                 }
  862.                 $this->position = $pos + $this->currentStat[7];
  863.                 break;
  864.             default:
  865.                 return false;
  866.         }
  867.         return true;
  868.     }
  869.    
  870.     /**
  871.      * The current position in the stream - PHP streams API
  872.      * @access private
  873.      */
  874.     public function stream_tell()
  875.     {
  876.         return $this->position;
  877.     }
  878.  
  879.     /**
  880.      * The result of an fstat call, returns mod time from creation, and file size -
  881.      * PHP streams API
  882.      * @uses _stream_stat()
  883.      * @access private
  884.      */
  885.     public function stream_stat()
  886.     {
  887.         return $this->_stream_stat();
  888.     }
  889.  
  890.     /**
  891.      * Retrieve statistics on a file or directory within the .phar
  892.      * @param string file/directory to stat
  893.      * @access private
  894.      */
  895.     public function _stream_stat($file = null)
  896.     {
  897.         $std = $file ? self::processFile($file) : $this->currentFilename;
  898.         if ($file) {
  899.             if (isset(self::$_manifest[$this->_archiveName][$file])) {
  900.                 $this->_setCurrentFile($file);
  901.                 $isdir = false;
  902.             } else {
  903.                 do {
  904.                     $isdir = false;
  905.                     if ($file == '/') {
  906.                         break;
  907.                     }
  908.                     foreach (self::$_manifest[$this->_archiveName] as $path => $info) {
  909.                         if (strpos($path, $file) === 0) {
  910.                             if (strlen($path) > strlen($file) &&
  911.                                   $path[strlen($file)] == '/') {
  912.                                 break 2;
  913.                             }
  914.                         }
  915.                     }
  916.                     // no files exist and no directories match this string
  917.                     return false;
  918.                 } while (false);
  919.                 $isdir = true;
  920.             }
  921.         } else {
  922.             $isdir = false; // open streams must be files
  923.         }
  924.         $mode = $isdir ? 0040444 : 0100444;
  925.         // 040000 = dir, 010000 = file
  926.         // everything is readable, nothing is writeable
  927.         return array(
  928.            0, 0, $mode, 0, 0, 0, 0, 0, 0, 0, 0, 0, // non-associative indices
  929.            'dev' => 0, 'ino' => 0,
  930.            'mode' => $mode,
  931.            'nlink' => 0, 'uid' => 0, 'gid' => 0, 'rdev' => 0, 'blksize' => 0, 'blocks' => 0,
  932.            'size' => $this->currentStat[7],
  933.            'atime' => $this->currentStat[9],
  934.            'mtime' => $this->currentStat[9],
  935.            'ctime' => $this->currentStat[9],
  936.            );
  937.     }
  938.  
  939.     /**
  940.      * Stat a closed file or directory - PHP streams API
  941.      * @param string
  942.      * @param int
  943.      * @access private
  944.      */
  945.     public function url_stat($url, $flags)
  946.     {
  947.         $path = $this->initializeStream($url);
  948.         return $this->_stream_stat($path);
  949.     }
  950.  
  951.     /**
  952.      * Open a directory in the .phar for reading - PHP streams API
  953.      * @param string directory name
  954.      * @access private
  955.      */
  956.     public function dir_opendir($path)
  957.     {
  958.         $info = @parse_url($path);
  959.         if (!$info) {
  960.             $info = self::parseUrl($path);
  961.             if (!$info) {
  962.                 trigger_error('Error: "' . $path . '" is a file, and cannot be opened with opendir',
  963.                     E_USER_ERROR);
  964.                 return false;
  965.             }
  966.         }
  967.         $path = !empty($info['path']) ?
  968.             $info['host'] . $info['path'] : $info['host'] . '/';
  969.         $path = $this->initializeStream('phar://' . $path);
  970.         if (isset(self::$_manifest[$this->_archiveName][$path])) {
  971.             trigger_error('Error: "' . $path . '" is a file, and cannot be opened with opendir',
  972.                 E_USER_ERROR);
  973.             return false;
  974.         }
  975.         if ($path == false) {
  976.             trigger_error('Error: Unknown phar in "' . $file . '"', E_USER_ERROR);
  977.             return false;
  978.         }
  979.         $this->fp = @fopen($this->_archiveName, "rb");
  980.         if (!$this->fp) {
  981.             trigger_error('Error: cannot open phar "' . $this->_archiveName . '"');
  982.             return false;
  983.         }
  984.         $this->_dirFiles = array();
  985.         foreach (self::$_manifest[$this->_archiveName] as $file => $info) {
  986.             if ($path == '/') {
  987.                 if (strpos($file, '/')) {
  988.                     $a = explode('/', $file);
  989.                     $this->_dirFiles[array_shift($a)] = true;
  990.                 } else {
  991.                     $this->_dirFiles[$file] = true;
  992.                 }
  993.             } elseif (strpos($file, $path) === 0) {
  994.                 $fname = substr($file, strlen($path) + 1);
  995.                 if (strpos($fname, '/')) {
  996.                     // this is a directory
  997.                     $a = explode('/', $fname);
  998.                     $this->_dirFiles[array_shift($a)] = true;
  999.                 } elseif ($file[strlen($path)] == '/') {
  1000.                     // this is a file
  1001.                     $this->_dirFiles[$fname] = true;
  1002.                 }
  1003.             }
  1004.         }
  1005.         @fclose($this->fp);
  1006.         if (!count($this->_dirFiles)) {
  1007.             return false;
  1008.         }
  1009.         @uksort($this->_dirFiles, 'strnatcmp');
  1010.         return true;
  1011.     }
  1012.  
  1013.     /**
  1014.      * Read the next directory entry - PHP streams API
  1015.      * @access private
  1016.      */
  1017.     public function dir_readdir()
  1018.     {
  1019.         $ret = key($this->_dirFiles);
  1020.         @next($this->_dirFiles);
  1021.         if (!$ret) {
  1022.             return false;
  1023.         }
  1024.         return $ret;
  1025.     }
  1026.  
  1027.     /**
  1028.      * Close a directory handle opened with opendir() - PHP streams API
  1029.      * @access private
  1030.      */
  1031.     public function dir_closedir()
  1032.     {
  1033.         $this->_dirFiles = array();
  1034.         return true;
  1035.     }
  1036.  
  1037.     /**
  1038.      * Rewind to the first directory entry - PHP streams API
  1039.      * @access private
  1040.      */
  1041.     public function dir_rewinddir()
  1042.     {
  1043.         @reset($this->_dirFiles);
  1044.         return true;
  1045.     }
  1046.  
  1047.     /**
  1048.      * API version of this class
  1049.      * @return string
  1050.      */
  1051.     public static final function APIVersion()
  1052.     {
  1053.         return '1.0.0';
  1054.     }
  1055.  
  1056.     /**
  1057.      * Retrieve Phar-specific metadata for a Phar archive
  1058.      *
  1059.      * @param string $phar full path to Phar archive, or alias
  1060.      * @return null|mixed The value that was serialized for the Phar
  1061.      *                    archive's metadata
  1062.      * @throws Exception
  1063.      */
  1064.     public static function getPharMetadata($phar)
  1065.     {
  1066.         if (isset(self::$_pharFiles[$phar])) {
  1067.             $phar = self::$_pharFiles[$phar];
  1068.         }
  1069.         if (!isset(self::$_pharMapping[$phar])) {
  1070.             throw new Exception('Unknown Phar archive: "' . $phar . '"');
  1071.         }
  1072.         return self::$_pharMapping[$phar][4];
  1073.     }
  1074.  
  1075.     /**
  1076.      * Retrieve File-specific metadata for a Phar archive file
  1077.      *
  1078.      * @param string $phar full path to Phar archive, or alias
  1079.      * @param string $file relative path to file within Phar archive
  1080.      * @return null|mixed The value that was serialized for the Phar
  1081.      *                    archive's metadata
  1082.      * @throws Exception
  1083.      */
  1084.     public static function getFileMetadata($phar, $file)
  1085.     {
  1086.         if (!isset(self::$_pharFiles[$phar])) {
  1087.             if (!isset(self::$_pharMapping[$phar])) {
  1088.                 throw new Exception('Unknown Phar archive: "' . $phar . '"');
  1089.             }
  1090.             $phar = self::$_pharMapping[$phar][0];
  1091.         }
  1092.         if (!isset(self::$_manifest[$phar])) {
  1093.             throw new Exception('Unknown Phar: "' . $phar . '"');
  1094.         }
  1095.         $file = self::processFile($file);
  1096.         if (!isset(self::$_manifest[$phar][$file])) {
  1097.             throw new Exception('Unknown file "' . $file . '" within Phar "'. $phar . '"');
  1098.         }
  1099.         return self::$_manifest[$phar][$file][6];
  1100.     }
  1101.  
  1102.     /**
  1103.      * @return list of supported signature algorithmns.
  1104.      */
  1105.     public static function getsupportedsignatures()
  1106.     {
  1107.         $ret = array('MD5', 'SHA-1');
  1108.         if (extension_loaded('hash')) {
  1109.             $ret[] = 'SHA-256';
  1110.             $ret[] = 'SHA-512';
  1111.         }
  1112.         return $ret;
  1113.     }
  1114. }}
  1115. if (!class_exists('Phar')) {
  1116.     PHP_Archive::mapPhar(null, 42313                   );
  1117. } else {
  1118.     try {
  1119.         Phar::mapPhar();
  1120.     } catch (Exception $e) {
  1121.         echo $e->getMessage();
  1122.     }
  1123. }
  1124. if (class_exists('PHP_Archive') && !in_array('phar', stream_get_wrappers())) {
  1125.     stream_wrapper_register('phar', 'PHP_Archive');
  1126. }
  1127.  
  1128. @ini_set('memory_limit', -1);
  1129. if (extension_loaded('phar')) {if (isset($_SERVER) && isset($_SERVER['REQUEST_URI'])) {
  1130.     $uri = parse_url($_SERVER['REQUEST_URI']);
  1131.     $archive = realpath($_SERVER['SCRIPT_FILENAME']);
  1132.     $subpath = str_replace('/' . basename($archive), '', $uri['path']);
  1133.     $mimetypes = array (
  1134.   'aif' => 'audio/x-aiff',
  1135.   'aiff' => 'audio/x-aiff',
  1136.   'arc' => 'application/octet-stream',
  1137.   'arj' => 'application/octet-stream',
  1138.   'art' => 'image/x-jg',
  1139.   'asf' => 'video/x-ms-asf',
  1140.   'asx' => 'video/x-ms-asf',
  1141.   'avi' => 'video/avi',
  1142.   'bin' => 'application/octet-stream',
  1143.   'bm' => 'image/bmp',
  1144.   'bmp' => 'image/bmp',
  1145.   'bz2' => 'application/x-bzip2',
  1146.   'css' => 'text/css',
  1147.   'doc' => 'application/msword',
  1148.   'dot' => 'application/msword',
  1149.   'dv' => 'video/x-dv',
  1150.   'dvi' => 'application/x-dvi',
  1151.   'eps' => 'application/postscript',
  1152.   'exe' => 'application/octet-stream',
  1153.   'gif' => 'image/gif',
  1154.   'gz' => 'application/x-gzip',
  1155.   'gzip' => 'application/x-gzip',
  1156.   'htm' => 'text/html',
  1157.   'html' => 'text/html',
  1158.   'ico' => 'image/x-icon',
  1159.   'jpe' => 'image/jpeg',
  1160.   'jpg' => 'image/jpeg',
  1161.   'jpeg' => 'image/jpeg',
  1162.   'js' => 'application/x-javascript',
  1163.   'log' => 'text/plain',
  1164.   'mid' => 'audio/x-midi',
  1165.   'mov' => 'video/quicktime',
  1166.   'mp2' => 'audio/mpeg',
  1167.   'mp3' => 'audio/mpeg3',
  1168.   'mpg' => 'audio/mpeg',
  1169.   'pdf' => 'aplication/pdf',
  1170.   'png' => 'image/png',
  1171.   'rtf' => 'application/rtf',
  1172.   'tif' => 'image/tiff',
  1173.   'tiff' => 'image/tiff',
  1174.   'txt' => 'text/plain',
  1175.   'xml' => 'text/xml',
  1176. );
  1177.     $phpfiles = array (
  1178.   'php' => true,
  1179. );
  1180.     $phpsfiles = array (
  1181.   'phps' => true,
  1182. );
  1183.     $deny = array (
  1184.   0 => '/.+\\.inc$/',
  1185. );
  1186.     $subpath = str_replace('/' . basename($archive), '', $uri['path']);
  1187.     if (!$subpath || $subpath == '/') {
  1188.         $subpath = '/PEAR.php';
  1189.     }
  1190.     if ($subpath[0] != '/') {
  1191.         $subpath = '/' . $subpath;
  1192.     }
  1193.     if (!@file_exists('phar://' . $archive . $subpath)) {
  1194.         header("HTTP/1.0 404 Not Found");
  1195.         exit;
  1196.     }
  1197.  
  1198.     foreach ($deny as $pattern) {
  1199.         if (preg_match($pattern, $subpath)) {
  1200.             header("HTTP/1.0 404 Not Found");
  1201.             exit;
  1202.         }
  1203.     }
  1204.     $inf = pathinfo(basename($subpath));
  1205.     if (!isset($inf['extension'])) {
  1206.         header('Content-Type: text/plain');
  1207.         header('Content-Length: ' . filesize('phar://' . $archive . $subpath));
  1208.         readfile('phar://' . $archive . $subpath);
  1209.         exit;
  1210.     }
  1211.     if (isset($phpfiles[$inf['extension']])) {
  1212.         include 'phar://' . $archive . '/' . $subpath;
  1213.         exit;
  1214.     }
  1215.     if (isset($mimetypes[$inf['extension']])) {
  1216.         header('Content-Type: ' . $mimetypes[$inf['extension']]);
  1217.         header('Content-Length: ' . filesize('phar://' . $archive . $subpath));
  1218.         readfile('phar://' . $archive . $subpath);
  1219.         exit;
  1220.     }
  1221.     if (isset($phpsfiles[$inf['extension']])) {
  1222.         header('Content-Type: text/html');
  1223.         $c = highlight_file('phar://' . $archive . $subpath, true);
  1224.         header('Content-Length: ' . strlen($c));
  1225.         echo $c;
  1226.         exit;
  1227.     }
  1228.     header('Content-Type: text/plain');
  1229.     header('Content-Length: ' . filesize('phar://' . $archive . '/' . $subpath));
  1230.     readfile('phar://' . $archive . '/' . $subpath);
  1231.     exit;
  1232. }} else {if (!empty($_SERVER['REQUEST_URI'])) {PHP_Archive::webFrontController('PEAR.php');exit;}}
  1233.  
  1234.  
  1235.  
  1236. require_once 'phar://go-pear.phar/index.php';
  1237. __HALT_COMPILER();
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×