コード例 #1
0
 /**
  * Save the phar to disk.
  *
  * @param Pharchive $phar     The phar to write.
  *
  * @param string    $filename The file name to write to.
  *
  * @return void
  *
  * @throws \RuntimeException When the stub is illegal.
  */
 public function save($phar, $filename)
 {
     $this->phar = $phar;
     $this->file = new StreamWriter($filename);
     $this->bins = new StreamWriter('php://temp');
     $stub = $phar->getStub();
     if (false === ($pos = strpos($stub, '__HALT_COMPILER();'))) {
         throw new \RuntimeException('Illegal stub');
     }
     // Mimic plain PHP phar writing, it adds the closing tag.
     $this->file->write(substr($stub, 0, $pos + 18) . " ?>\r\n");
     $this->buildManifest();
     $this->file->writeStream($this->bins->seek(0));
     unset($this->bins);
     // Now sign the phar.
     if ($phar->isSigned()) {
         $this->file->savePosition();
         $this->file->seek(0);
         $hash = $this->file->hashStream($phar->getSignatureAlgorithm(), true);
         $this->file->loadPosition();
         $this->file->write($hash);
         $this->file->writeUint32le($phar->getSignatureFlags());
         $this->file->write('GBMB');
     }
     unset($this->phar);
     unset($this->file);
 }
コード例 #2
0
 /**
  * Read the header from the file.
  *
  * @return void
  *
  * @throws \RuntimeException When the manifest is larger than 100MB (hardcoded limit in PHP).
  *
  * @throws \UnexpectedValueException When the manifest header is truncated.
  *
  * @throws \RuntimeException When the API version is not understood.
  *
  * @throws \UnexpectedValueException When the file length is smaller than the offset of the file contents.
  */
 private function readHead()
 {
     $this->detectStub();
     // Check header.
     $manifestLength = $this->file->readUint32le();
     if ($manifestLength > 1048576 * 100) {
         // Prevent serious memory issues by limiting manifest to at most 100 MB in length.
         // See also: https://github.com/php/php-src/blob/12ff95/ext/phar/phar.c#L719
         throw new \RuntimeException('manifest cannot be larger than 100 MB');
     }
     $this->file->savePosition();
     if ($manifestLength < 10 || $manifestLength != strlen($this->file->read($manifestLength))) {
         throw new \UnexpectedValueException('internal corruption of phar (truncated manifest header)');
     }
     // Back to where we took off.
     $this->file->loadPosition();
     $this->numFiles = $this->file->readUint32le();
     $apiVersion = $this->file->readUint16be();
     if (($apiVersion & 0xfff0) > self::MAX_API_VERSION) {
         throw new \RuntimeException(sprintf('Unable to process phar file, unsupported API version ', $apiVersion >> 12, $apiVersion >> 8 & 0xf, $apiVersion >> 4 & 0xf));
     }
     $this->phar->setApiVersion($apiVersion);
     $this->phar->setFlags($this->file->readUint32le());
     if (0 < ($aliasLength = $this->file->readUint32le())) {
         $this->phar->setAlias($this->file->read($aliasLength));
     }
     if (0 < ($metadataLength = $this->file->readUint32le())) {
         $this->phar->setMetadata(unserialize($this->file->read($metadataLength)));
     }
     $this->binOffset = strlen($this->phar->getStub()) + $manifestLength + 4;
     if ($this->file->getLength() < $this->binOffset) {
         throw new \UnexpectedValueException('internal corruption of phar (truncated manifest header)');
     }
 }