*/
public static function read( $fileName, $callback, $options = array() ) {
$zdr = new self( $fileName, $callback, $options );
+
return $zdr->execute();
}
/** The file name */
- var $fileName;
+ protected $fileName;
/** The opened file resource */
- var $file;
+ protected $file;
/** The cached length of the file, or null if it has not been loaded yet. */
- var $fileLength;
+ protected $fileLength;
/** A segmented cache of the file contents */
- var $buffer;
+ protected $buffer;
/** The file data callback */
- var $callback;
+ protected $callback;
/** The ZIP64 mode */
- var $zip64 = false;
+ protected $zip64 = false;
/** Stored headers */
- var $eocdr, $eocdr64, $eocdr64Locator;
+ protected $eocdr, $eocdr64, $eocdr64Locator;
- var $data;
+ protected $data;
/** The "extra field" ID for ZIP64 central directory entries */
const ZIP64_EXTRA_HEADER = 0x0001;
} else {
if ( $this->eocdr['CD size'] == 0xffffffff
|| $this->eocdr['CD offset'] == 0xffffffff
- || $this->eocdr['CD entries total'] == 0xffff )
- {
+ || $this->eocdr['CD entries total'] == 0xffff
+ ) {
$this->error( 'zip-unsupported', 'Central directory header indicates ZIP64, ' .
'but we are in legacy mode. Rejecting this upload is necessary to avoid ' .
'opening vulnerabilities on clients using OpenJDK 7 or later.' );
}
fclose( $this->file );
+
return $status;
}
$this->error( 'zip-bad', 'trailing bytes after the end of the file comment' );
}
if ( $this->eocdr['disk'] !== 0
- || $this->eocdr['CD start disk'] !== 0 )
- {
+ || $this->eocdr['CD start disk'] !== 0
+ ) {
$this->error( 'zip-unsupported', 'more than one disk (in EOCDR)' );
}
$this->eocdr += $this->unpack(
);
$structSize = $this->getStructSize( $info );
- $block = $this->getBlock( $this->getFileLength() - $this->eocdr['EOCDR size']
- - $structSize, $structSize );
+ $start = $this->getFileLength() - $this->eocdr['EOCDR size'] - $structSize;
+ $block = $this->getBlock( $start, $structSize );
$this->eocdr64Locator = $data = $this->unpack( $block, $info );
if ( $data['signature'] !== "PK\x06\x07" ) {
*/
function readZip64EndOfCentralDirectoryRecord() {
if ( $this->eocdr64Locator['eocdr64 start disk'] != 0
- || $this->eocdr64Locator['number of disks'] != 0 )
- {
+ || $this->eocdr64Locator['number of disks'] != 0
+ ) {
$this->error( 'zip-unsupported', 'more than one disk (in EOCDR64 locator)' );
}
$this->error( 'zip-bad', 'wrong signature on Zip64 end of central directory record' );
}
if ( $data['disk'] !== 0
- || $data['CD start disk'] !== 0 )
- {
+ || $data['CD start disk'] !== 0
+ ) {
$this->error( 'zip-unsupported', 'more than one disk (in EOCDR64)' );
}
}
$this->error( 'zip-bad', 'the central directory does not immediately precede the end ' .
'of central directory record' );
}
+
return array( $offset, $size );
}
$endPos = $this->eocdr['position'];
if ( $size == 0xffffffff
|| $offset == 0xffffffff
- || $numEntries == 0xffff )
- {
+ || $numEntries == 0xffff
+ ) {
$this->readZip64EndOfCentralDirectoryLocator();
if ( isset( $this->eocdr64Locator['eocdr64 offset'] ) ) {
$this->error( 'zip-bad', 'the central directory does not immediately precede the end ' .
'of central directory record' );
}
+
return array( $offset, $size );
}
$pos += $this->getStructSize( $variableInfo );
if ( $this->zip64 && (
- $data['compressed size'] == 0xffffffff
- || $data['uncompressed size'] == 0xffffffff
- || $data['local header offset'] == 0xffffffff ) )
- {
+ $data['compressed size'] == 0xffffffff
+ || $data['uncompressed size'] == 0xffffffff
+ || $data['local header offset'] == 0xffffffff )
+ ) {
$zip64Data = $this->unpackZip64Extra( $data['extra field'] );
if ( $zip64Data ) {
$data = $zip64Data + $data;
$year, $month, $day, $hour, $minute, $second );
// Convert the character set in the file name
- if ( !function_exists( 'iconv' )
- || $this->testBit( $data['general bits'], self::GENERAL_UTF8 ) )
- {
+ if ( $this->testBit( $data['general bits'], self::GENERAL_UTF8 ) ) {
$name = $data['name'];
} else {
$name = iconv( 'CP437', 'UTF-8', $data['name'] );
$stat = fstat( $this->file );
$this->fileLength = $stat['size'];
}
+
return $this->fileLength;
}
* If there are not enough bytes in the file to satisfy the request, the
* return value will be truncated. If a request is made for a segment beyond
* the end of the file, an empty string will be returned.
+ *
+ * @param int $segIndex
+ *
* @return string
*/
function getSegment( $segIndex ) {
$bytePos = $segIndex * self::SEGSIZE;
if ( $bytePos >= $this->getFileLength() ) {
$this->buffer[$segIndex] = '';
+
return '';
}
if ( fseek( $this->file, $bytePos ) ) {
}
$this->buffer[$segIndex] = $seg;
}
+
return $this->buffer[$segIndex];
}
$size += $type;
}
}
+
return $size;
}
if ( is_array( $type ) ) {
list( $typeName, $fieldSize ) = $type;
switch ( $typeName ) {
- case 'string':
- $data[$key] = substr( $string, $pos, $fieldSize );
- $pos += $fieldSize;
- break;
- default:
- throw new MWException( __METHOD__ . ": invalid type \"$typeName\"" );
+ case 'string':
+ $data[$key] = substr( $string, $pos, $fieldSize );
+ $pos += $fieldSize;
+ break;
+ default:
+ throw new MWException( __METHOD__ . ": invalid type \"$typeName\"" );
}
} else {
// Unsigned little-endian integer
* Internal exception class. Will be caught by private code.
*/
class ZipDirectoryReaderError extends Exception {
- var $errorCode;
+ protected $errorCode;
function __construct( $code ) {
$this->errorCode = $code;