Merge "Add support for PHP7 random_bytes in favor of mcrypt_create_iv"
[lhc/web/wiklou.git] / includes / utils / ZipDirectoryReader.php
index 0f56e33..212f325 100644 (file)
@@ -26,7 +26,6 @@
  *
  * Only a functional interface is provided: ZipFileReader::read(). No access is
  * given to object instances.
- *
  */
 class ZipDirectoryReader {
        /**
@@ -86,7 +85,7 @@ class ZipDirectoryReader {
         * a fatal error is returned. If this occurs, the data sent to the callback
         * function should be discarded.
         */
-       public static function read( $fileName, $callback, $options = array() ) {
+       public static function read( $fileName, $callback, $options = [] ) {
                $zdr = new self( $fileName, $callback, $options );
 
                return $zdr->execute();
@@ -129,6 +128,9 @@ class ZipDirectoryReader {
 
        /**
         * Private constructor
+        * @param string $fileName
+        * @param callable $callback
+        * @param array $options
         */
        protected function __construct( $fileName, $callback, $options ) {
                $this->fileName = $fileName;
@@ -146,7 +148,7 @@ class ZipDirectoryReader {
         */
        function execute() {
                $this->file = fopen( $this->fileName, 'r' );
-               $this->data = array();
+               $this->data = [];
                if ( !$this->file ) {
                        return Status::newFatal( 'zip-file-open-error' );
                }
@@ -183,6 +185,7 @@ class ZipDirectoryReader {
         * Throw an error, and log a debug message
         * @param mixed $code
         * @param string $debugMessage
+        * @throws ZipDirectoryReaderError
         */
        function error( $code, $debugMessage ) {
                wfDebug( __CLASS__ . ": Fatal error: $debugMessage\n" );
@@ -195,7 +198,7 @@ class ZipDirectoryReader {
         * spec.
         */
        function readEndOfCentralDirectoryRecord() {
-               $info = array(
+               $info = [
                        'signature' => 4,
                        'disk' => 2,
                        'CD start disk' => 2,
@@ -204,13 +207,17 @@ class ZipDirectoryReader {
                        'CD size' => 4,
                        'CD offset' => 4,
                        'file comment length' => 2,
-               );
+               ];
                $structSize = $this->getStructSize( $info );
                $startPos = $this->getFileLength() - 65536 - $structSize;
                if ( $startPos < 0 ) {
                        $startPos = 0;
                }
 
+               if ( $this->getFileLength() === 0 ) {
+                       $this->error( 'zip-wrong-format', "The file is empty." );
+               }
+
                $block = $this->getBlock( $startPos );
                $sigPos = strrpos( $block, "PK\x05\x06" );
                if ( $sigPos === false ) {
@@ -231,7 +238,7 @@ class ZipDirectoryReader {
                }
                $this->eocdr += $this->unpack(
                        $block,
-                       array( 'file comment' => array( 'string', $this->eocdr['file comment length'] ) ),
+                       [ 'file comment' => [ 'string', $this->eocdr['file comment length'] ] ],
                        $sigPos + $structSize );
                $this->eocdr['position'] = $startPos + $sigPos;
        }
@@ -241,12 +248,12 @@ class ZipDirectoryReader {
         * error will be raised if it does not exist.
         */
        function readZip64EndOfCentralDirectoryLocator() {
-               $info = array(
-                       'signature' => array( 'string', 4 ),
+               $info = [
+                       'signature' => [ 'string', 4 ],
                        'eocdr64 start disk' => 4,
                        'eocdr64 offset' => 8,
                        'number of disks' => 4,
-               );
+               ];
                $structSize = $this->getStructSize( $info );
 
                $start = $this->getFileLength() - $this->eocdr['EOCDR size'] - $structSize;
@@ -272,8 +279,8 @@ class ZipDirectoryReader {
                        $this->error( 'zip-unsupported', 'more than one disk (in EOCDR64 locator)' );
                }
 
-               $info = array(
-                       'signature' => array( 'string', 4 ),
+               $info = [
+                       'signature' => [ 'string', 4 ],
                        'EOCDR64 size' => 8,
                        'version made by' => 2,
                        'version needed' => 2,
@@ -283,7 +290,7 @@ class ZipDirectoryReader {
                        'CD entries total' => 8,
                        'CD size' => 8,
                        'CD offset' => 8
-               );
+               ];
                $structSize = $this->getStructSize( $info );
                $block = $this->getBlock( $this->eocdr64Locator['eocdr64 offset'], $structSize );
                $this->eocdr64 = $data = $this->unpack( $block, $info );
@@ -315,7 +322,7 @@ class ZipDirectoryReader {
                                'of central directory record' );
                }
 
-               return array( $offset, $size );
+               return [ $offset, $size ];
        }
 
        /**
@@ -354,17 +361,19 @@ class ZipDirectoryReader {
                                'of central directory record' );
                }
 
-               return array( $offset, $size );
+               return [ $offset, $size ];
        }
 
        /**
         * Read the central directory at the given location
+        * @param int $offset
+        * @param int $size
         */
        function readCentralDirectory( $offset, $size ) {
                $block = $this->getBlock( $offset, $size );
 
-               $fixedInfo = array(
-                       'signature' => array( 'string', 4 ),
+               $fixedInfo = [
+                       'signature' => [ 'string', 4 ],
                        'version made by' => 2,
                        'version needed' => 2,
                        'general bits' => 2,
@@ -381,7 +390,7 @@ class ZipDirectoryReader {
                        'internal attrs' => 2,
                        'external attrs' => 4,
                        'local header offset' => 4,
-               );
+               ];
                $fixedSize = $this->getStructSize( $fixedInfo );
 
                $pos = 0;
@@ -393,11 +402,11 @@ class ZipDirectoryReader {
                                $this->error( 'zip-bad', 'Invalid signature found in directory entry' );
                        }
 
-                       $variableInfo = array(
-                               'name' => array( 'string', $data['name length'] ),
-                               'extra field' => array( 'string', $data['extra field length'] ),
-                               'comment' => array( 'string', $data['comment length'] ),
-                       );
+                       $variableInfo = [
+                               'name' => [ 'string', $data['name length'] ],
+                               'extra field' => [ 'string', $data['extra field length'] ],
+                               'comment' => [ 'string', $data['comment length'] ],
+                       ];
                        $data += $this->unpack( $block, $variableInfo, $pos );
                        $pos += $this->getStructSize( $variableInfo );
 
@@ -439,39 +448,40 @@ class ZipDirectoryReader {
                        }
 
                        // Compile a data array for the user, with a sensible format
-                       $userData = array(
+                       $userData = [
                                'name' => $name,
                                'mtime' => $timestamp,
                                'size' => $data['uncompressed size'],
-                       );
+                       ];
                        call_user_func( $this->callback, $userData );
                }
        }
 
        /**
         * Interpret ZIP64 "extra field" data and return an associative array.
+        * @param string $extraField
         * @return array|bool
         */
        function unpackZip64Extra( $extraField ) {
-               $extraHeaderInfo = array(
+               $extraHeaderInfo = [
                        'id' => 2,
                        'size' => 2,
-               );
+               ];
                $extraHeaderSize = $this->getStructSize( $extraHeaderInfo );
 
-               $zip64ExtraInfo = array(
+               $zip64ExtraInfo = [
                        'uncompressed size' => 8,
                        'compressed size' => 8,
                        'local header offset' => 8,
                        'disk number start' => 4,
-               );
+               ];
 
                $extraPos = 0;
                while ( $extraPos < strlen( $extraField ) ) {
                        $extra = $this->unpack( $extraField, $extraHeaderInfo, $extraPos );
                        $extraPos += $extraHeaderSize;
                        $extra += $this->unpack( $extraField,
-                               array( 'data' => array( 'string', $extra['size'] ) ),
+                               [ 'data' => [ 'string', $extra['size'] ] ],
                                $extraPos );
                        $extraPos += $extra['size'];
 
@@ -575,6 +585,7 @@ class ZipDirectoryReader {
 
        /**
         * Get the size of a structure in bytes. See unpack() for the format of $struct.
+        * @param array $struct
         * @return int
         */
        function getStructSize( $struct ) {
@@ -619,7 +630,7 @@ class ZipDirectoryReader {
                        $this->error( 'zip-bad', 'unpack() would run past the end of the supplied string' );
                }
 
-               $data = array();
+               $data = [];
                $pos = $offset;
                foreach ( $struct as $key => $type ) {
                        if ( is_array( $type ) ) {