summaryrefslogtreecommitdiff
path: root/includes/ZipDirectoryReader.php
diff options
context:
space:
mode:
Diffstat (limited to 'includes/ZipDirectoryReader.php')
-rw-r--r--includes/ZipDirectoryReader.php124
1 files changed, 64 insertions, 60 deletions
diff --git a/includes/ZipDirectoryReader.php b/includes/ZipDirectoryReader.php
index d21cf3b0..37934aea 100644
--- a/includes/ZipDirectoryReader.php
+++ b/includes/ZipDirectoryReader.php
@@ -1,8 +1,8 @@
<?php
/**
- * A class for reading ZIP file directories, for the purposes of upload
- * verification.
+ * A class for reading ZIP file directories, for the purposes of upload
+ * verification.
*
* Only a functional interface is provided: ZipFileReader::read(). No access is
* given to object instances.
@@ -12,7 +12,7 @@ class ZipDirectoryReader {
/**
* Read a ZIP file and call a function for each file discovered in it.
*
- * Because this class is aimed at verification, an error is raised on
+ * Because this class is aimed at verification, an error is raised on
* suspicious or ambiguous input, instead of emulating some standard
* behaviour.
*
@@ -20,7 +20,7 @@ class ZipDirectoryReader {
* @param $callback Array The callback function. It will be called for each file
* with a single associative array each time, with members:
*
- * - name: The file name. Directories conventionally have a trailing
+ * - name: The file name. Directories conventionally have a trailing
* slash.
*
* - mtime: The file modification time, in MediaWiki 14-char format
@@ -30,18 +30,18 @@ class ZipDirectoryReader {
* @param $options Array An associative array of read options, with the option
* name in the key. This may currently contain:
*
- * - zip64: If this is set to true, then we will emulate a
- * library with ZIP64 support, like OpenJDK 7. If it is set to
- * false, then we will emulate a library with no knowledge of
+ * - zip64: If this is set to true, then we will emulate a
+ * library with ZIP64 support, like OpenJDK 7. If it is set to
+ * false, then we will emulate a library with no knowledge of
* ZIP64.
*
- * NOTE: The ZIP64 code is untested and probably doesn't work. It
- * turned out to be easier to just reject ZIP64 archive uploads,
- * since they are likely to be very rare. Confirming safety of a
- * ZIP64 file is fairly complex. What do you do with a file that is
- * ambiguous and broken when read with a non-ZIP64 reader, but valid
- * when read with a ZIP64 reader? This situation is normal for a
- * valid ZIP64 file, and working out what non-ZIP64 readers will make
+ * NOTE: The ZIP64 code is untested and probably doesn't work. It
+ * turned out to be easier to just reject ZIP64 archive uploads,
+ * since they are likely to be very rare. Confirming safety of a
+ * ZIP64 file is fairly complex. What do you do with a file that is
+ * ambiguous and broken when read with a non-ZIP64 reader, but valid
+ * when read with a ZIP64 reader? This situation is normal for a
+ * valid ZIP64 file, and working out what non-ZIP64 readers will make
* of such a file is not trivial.
*
* @return Status object. The following fatal errors are defined:
@@ -50,20 +50,20 @@ class ZipDirectoryReader {
*
* - zip-wrong-format: The file does not appear to be a ZIP file.
*
- * - zip-bad: There was something wrong or ambiguous about the file
+ * - zip-bad: There was something wrong or ambiguous about the file
* data.
*
- * - zip-unsupported: The ZIP file uses features which
+ * - zip-unsupported: The ZIP file uses features which
* ZipDirectoryReader does not support.
*
- * The default messages for those fatal errors are written in a way that
+ * The default messages for those fatal errors are written in a way that
* makes sense for upload verification.
*
- * If a fatal error is returned, more information about the error will be
+ * If a fatal error is returned, more information about the error will be
* available in the debug log.
*
* Note that the callback function may be called any number of times before
- * a fatal error is returned. If this occurs, the data sent to the callback
+ * 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() ) {
@@ -92,6 +92,8 @@ class ZipDirectoryReader {
/** Stored headers */
var $eocdr, $eocdr64, $eocdr64Locator;
+ var $data;
+
/** The "extra field" ID for ZIP64 central directory entries */
const ZIP64_EXTRA_HEADER = 0x0001;
@@ -104,7 +106,6 @@ class ZipDirectoryReader {
/** The index of the "general field" bit for central directory encryption */
const GENERAL_CD_ENCRYPTED = 13;
-
/**
* Private constructor
*/
@@ -165,8 +166,8 @@ class ZipDirectoryReader {
}
/**
- * Read the header which is at the end of the central directory,
- * unimaginatively called the "end of central directory record" by the ZIP
+ * Read the header which is at the end of the central directory,
+ * unimaginatively called the "end of central directory record" by the ZIP
* spec.
*/
function readEndOfCentralDirectoryRecord() {
@@ -189,7 +190,7 @@ class ZipDirectoryReader {
$block = $this->getBlock( $startPos );
$sigPos = strrpos( $block, "PK\x05\x06" );
if ( $sigPos === false ) {
- $this->error( 'zip-wrong-format',
+ $this->error( 'zip-wrong-format',
"zip file lacks EOCDR signature. It probably isn't a zip file." );
}
@@ -212,7 +213,7 @@ class ZipDirectoryReader {
}
/**
- * Read the header called the "ZIP64 end of central directory locator". An
+ * Read the header called the "ZIP64 end of central directory locator". An
* error will be raised if it does not exist.
*/
function readZip64EndOfCentralDirectoryLocator() {
@@ -224,20 +225,20 @@ class ZipDirectoryReader {
);
$structSize = $this->getStructSize( $info );
- $block = $this->getBlock( $this->getFileLength() - $this->eocdr['EOCDR size']
+ $block = $this->getBlock( $this->getFileLength() - $this->eocdr['EOCDR size']
- $structSize, $structSize );
$this->eocdr64Locator = $data = $this->unpack( $block, $info );
if ( $data['signature'] !== "PK\x06\x07" ) {
- // Note: Java will allow this and continue to read the
- // EOCDR64, so we have to reject the upload, we can't
+ // Note: Java will allow this and continue to read the
+ // EOCDR64, so we have to reject the upload, we can't
// just use the EOCDR header instead.
$this->error( 'zip-bad', 'wrong signature on Zip64 end of central directory locator' );
}
}
/**
- * Read the header called the "ZIP64 end of central directory record". It
+ * Read the header called the "ZIP64 end of central directory record". It
* may replace the regular "end of central directory record" in ZIP64 files.
*/
function readZip64EndOfCentralDirectoryRecord() {
@@ -266,14 +267,14 @@ class ZipDirectoryReader {
$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)' );
}
}
/**
- * Find the location of the central directory, as would be seen by a
+ * Find the location of the central directory, as would be seen by a
* non-ZIP64 reader.
*
* @return List containing offset, size and end position.
@@ -286,27 +287,27 @@ class ZipDirectoryReader {
// Some readers use the EOCDR position instead of the offset field
// to find the directory, so to be safe, we check if they both agree.
if ( $offset + $size != $endPos ) {
- $this->error( 'zip-bad', 'the central directory does not immediately precede the end ' .
+ $this->error( 'zip-bad', 'the central directory does not immediately precede the end ' .
'of central directory record' );
}
return array( $offset, $size );
}
/**
- * Find the location of the central directory, as would be seen by a
+ * Find the location of the central directory, as would be seen by a
* ZIP64-compliant reader.
*
* @return List containing offset, size and end position.
*/
function findZip64CentralDirectory() {
- // The spec is ambiguous about the exact rules of precedence between the
- // ZIP64 headers and the original headers. Here we follow zip_util.c
+ // The spec is ambiguous about the exact rules of precedence between the
+ // ZIP64 headers and the original headers. Here we follow zip_util.c
// from OpenJDK 7.
$size = $this->eocdr['CD size'];
$offset = $this->eocdr['CD offset'];
$numEntries = $this->eocdr['CD entries total'];
$endPos = $this->eocdr['position'];
- if ( $size == 0xffffffff
+ if ( $size == 0xffffffff
|| $offset == 0xffffffff
|| $numEntries == 0xffff )
{
@@ -324,7 +325,7 @@ class ZipDirectoryReader {
// Some readers use the EOCDR position instead of the offset field
// to find the directory, so to be safe, we check if they both agree.
if ( $offset + $size != $endPos ) {
- $this->error( 'zip-bad', 'the central directory does not immediately precede the end ' .
+ $this->error( 'zip-bad', 'the central directory does not immediately precede the end ' .
'of central directory record' );
}
return array( $offset, $size );
@@ -390,7 +391,7 @@ class ZipDirectoryReader {
}
// Convert the timestamp into MediaWiki format
- // For the format, please see the MS-DOS 2.0 Programmer's Reference,
+ // For the format, please see the MS-DOS 2.0 Programmer's Reference,
// pages 3-5 and 3-6.
$time = $data['mod time'];
$date = $data['mod date'];
@@ -405,8 +406,8 @@ class ZipDirectoryReader {
$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 ( !function_exists( 'iconv' )
+ || $this->testBit( $data['general bits'], self::GENERAL_UTF8 ) )
{
$name = $data['name'];
} else {
@@ -444,7 +445,7 @@ class ZipDirectoryReader {
while ( $extraPos < strlen( $extraField ) ) {
$extra = $this->unpack( $extraField, $extraHeaderInfo, $extraPos );
$extraPos += $extraHeaderSize;
- $extra += $this->unpack( $extraField,
+ $extra += $this->unpack( $extraField,
array( 'data' => array( 'string', $extra['size'] ) ),
$extraPos );
$extraPos += $extra['size'];
@@ -473,7 +474,7 @@ class ZipDirectoryReader {
* in the file to satisfy the request, an exception will be thrown.
*
* @param $start The byte offset of the start of the block.
- * @param $length The number of bytes to return. If omitted, the remainder
+ * @param $length The number of bytes to return. If omitted, the remainder
* of the file will be returned.
*
* @return string
@@ -500,10 +501,10 @@ class ZipDirectoryReader {
$block .= $this->getSegment( $segIndex );
}
- $block = substr( $block,
+ $block = substr( $block,
$start - $startSeg * self::SEGSIZE,
$length );
-
+
if ( strlen( $block ) < $length ) {
$this->error( 'zip-bad', 'getBlock() returned an unexpectedly small amount of data' );
}
@@ -512,12 +513,12 @@ class ZipDirectoryReader {
}
/**
- * Get a section of the file starting at position $segIndex * self::SEGSIZE,
- * of length self::SEGSIZE. The result is cached. This is a helper function
+ * Get a section of the file starting at position $segIndex * self::SEGSIZE,
+ * of length self::SEGSIZE. The result is cached. This is a helper function
* for getBlock().
*
- * If there are not enough bytes in the file to satsify the request, the
- * return value will be truncated. If a request is made for a segment beyond
+ * If there are not enough bytes in the file to satsify 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.
*/
function getSegment( $segIndex ) {
@@ -556,25 +557,25 @@ class ZipDirectoryReader {
}
/**
- * Unpack a binary structure. This is like the built-in unpack() function
+ * Unpack a binary structure. This is like the built-in unpack() function
* except nicer.
*
* @param $string The binary data input
*
- * @param $struct An associative array giving structure members and their
- * types. In the key is the field name. The value may be either an
- * integer, in which case the field is a little-endian unsigned integer
- * encoded in the given number of bytes, or an array, in which case the
- * first element of the array is the type name, and the subsequent
+ * @param $struct An associative array giving structure members and their
+ * types. In the key is the field name. The value may be either an
+ * integer, in which case the field is a little-endian unsigned integer
+ * encoded in the given number of bytes, or an array, in which case the
+ * first element of the array is the type name, and the subsequent
* elements are type-dependent parameters. Only one such type is defined:
- * - "string": The second array element gives the length of string.
+ * - "string": The second array element gives the length of string.
* Not null terminated.
*
* @param $offset The offset into the string at which to start unpacking.
*
- * @return Unpacked associative array. Note that large integers in the input
- * may be represented as floating point numbers in the return value, so
- * the use of weak comparison is advised.
+ * @return Unpacked associative array. Note that large integers in the input
+ * may be represented as floating point numbers in the return value, so
+ * the use of weak comparison is advised.
*/
function unpack( $string, $struct, $offset = 0 ) {
$size = $this->getStructSize( $struct );
@@ -600,8 +601,8 @@ class ZipDirectoryReader {
$length = intval( $type );
$bytes = substr( $string, $pos, $length );
- // Calculate the value. Use an algorithm which automatically
- // upgrades the value to floating point if necessary.
+ // Calculate the value. Use an algorithm which automatically
+ // upgrades the value to floating point if necessary.
$value = 0;
for ( $i = $length - 1; $i >= 0; $i-- ) {
$value *= 256;
@@ -623,7 +624,7 @@ class ZipDirectoryReader {
}
/**
- * Returns a bit from a given position in an integer value, converted to
+ * Returns a bit from a given position in an integer value, converted to
* boolean.
*
* @param $value integer
@@ -678,6 +679,9 @@ class ZipDirectoryReaderError extends Exception {
parent::__construct( "ZipDirectoryReader error: $code" );
}
+ /**
+ * @return mixed
+ */
function getErrorCode() {
return $this->code;
}