MediaWiki  1.23.8
ZipDirectoryReader.php
Go to the documentation of this file.
1 <?php
89  public static function read( $fileName, $callback, $options = array() ) {
90  $zdr = new self( $fileName, $callback, $options );
91 
92  return $zdr->execute();
93  }
94 
96  protected $fileName;
97 
99  protected $file;
100 
102  protected $fileLength;
103 
105  protected $buffer;
106 
108  protected $callback;
109 
111  protected $zip64 = false;
112 
115 
116  protected $data;
117 
119  const ZIP64_EXTRA_HEADER = 0x0001;
120 
122  const SEGSIZE = 16384;
123 
125  const GENERAL_UTF8 = 11;
126 
129 
133  protected function __construct( $fileName, $callback, $options ) {
134  $this->fileName = $fileName;
135  $this->callback = $callback;
136 
137  if ( isset( $options['zip64'] ) ) {
138  $this->zip64 = $options['zip64'];
139  }
140  }
141 
147  function execute() {
148  $this->file = fopen( $this->fileName, 'r' );
149  $this->data = array();
150  if ( !$this->file ) {
151  return Status::newFatal( 'zip-file-open-error' );
152  }
153 
154  $status = Status::newGood();
155  try {
157  if ( $this->zip64 ) {
158  list( $offset, $size ) = $this->findZip64CentralDirectory();
159  $this->readCentralDirectory( $offset, $size );
160  } else {
161  if ( $this->eocdr['CD size'] == 0xffffffff
162  || $this->eocdr['CD offset'] == 0xffffffff
163  || $this->eocdr['CD entries total'] == 0xffff
164  ) {
165  $this->error( 'zip-unsupported', 'Central directory header indicates ZIP64, ' .
166  'but we are in legacy mode. Rejecting this upload is necessary to avoid ' .
167  'opening vulnerabilities on clients using OpenJDK 7 or later.' );
168  }
169 
170  list( $offset, $size ) = $this->findOldCentralDirectory();
171  $this->readCentralDirectory( $offset, $size );
172  }
173  } catch ( ZipDirectoryReaderError $e ) {
174  $status->fatal( $e->getErrorCode() );
175  }
176 
177  fclose( $this->file );
178 
179  return $status;
180  }
181 
185  function error( $code, $debugMessage ) {
186  wfDebug( __CLASS__ . ": Fatal error: $debugMessage\n" );
187  throw new ZipDirectoryReaderError( $code );
188  }
189 
196  $info = array(
197  'signature' => 4,
198  'disk' => 2,
199  'CD start disk' => 2,
200  'CD entries this disk' => 2,
201  'CD entries total' => 2,
202  'CD size' => 4,
203  'CD offset' => 4,
204  'file comment length' => 2,
205  );
206  $structSize = $this->getStructSize( $info );
207  $startPos = $this->getFileLength() - 65536 - $structSize;
208  if ( $startPos < 0 ) {
209  $startPos = 0;
210  }
211 
212  $block = $this->getBlock( $startPos );
213  $sigPos = strrpos( $block, "PK\x05\x06" );
214  if ( $sigPos === false ) {
215  $this->error( 'zip-wrong-format',
216  "zip file lacks EOCDR signature. It probably isn't a zip file." );
217  }
218 
219  $this->eocdr = $this->unpack( substr( $block, $sigPos ), $info );
220  $this->eocdr['EOCDR size'] = $structSize + $this->eocdr['file comment length'];
221 
222  if ( $structSize + $this->eocdr['file comment length'] != strlen( $block ) - $sigPos ) {
223  $this->error( 'zip-bad', 'trailing bytes after the end of the file comment' );
224  }
225  if ( $this->eocdr['disk'] !== 0
226  || $this->eocdr['CD start disk'] !== 0
227  ) {
228  $this->error( 'zip-unsupported', 'more than one disk (in EOCDR)' );
229  }
230  $this->eocdr += $this->unpack(
231  $block,
232  array( 'file comment' => array( 'string', $this->eocdr['file comment length'] ) ),
233  $sigPos + $structSize );
234  $this->eocdr['position'] = $startPos + $sigPos;
235  }
236 
242  $info = array(
243  'signature' => array( 'string', 4 ),
244  'eocdr64 start disk' => 4,
245  'eocdr64 offset' => 8,
246  'number of disks' => 4,
247  );
248  $structSize = $this->getStructSize( $info );
249 
250  $start = $this->getFileLength() - $this->eocdr['EOCDR size'] - $structSize;
251  $block = $this->getBlock( $start, $structSize );
252  $this->eocdr64Locator = $data = $this->unpack( $block, $info );
253 
254  if ( $data['signature'] !== "PK\x06\x07" ) {
255  // Note: Java will allow this and continue to read the
256  // EOCDR64, so we have to reject the upload, we can't
257  // just use the EOCDR header instead.
258  $this->error( 'zip-bad', 'wrong signature on Zip64 end of central directory locator' );
259  }
260  }
261 
267  if ( $this->eocdr64Locator['eocdr64 start disk'] != 0
268  || $this->eocdr64Locator['number of disks'] != 0
269  ) {
270  $this->error( 'zip-unsupported', 'more than one disk (in EOCDR64 locator)' );
271  }
272 
273  $info = array(
274  'signature' => array( 'string', 4 ),
275  'EOCDR64 size' => 8,
276  'version made by' => 2,
277  'version needed' => 2,
278  'disk' => 4,
279  'CD start disk' => 4,
280  'CD entries this disk' => 8,
281  'CD entries total' => 8,
282  'CD size' => 8,
283  'CD offset' => 8
284  );
285  $structSize = $this->getStructSize( $info );
286  $block = $this->getBlock( $this->eocdr64Locator['eocdr64 offset'], $structSize );
287  $this->eocdr64 = $data = $this->unpack( $block, $info );
288  if ( $data['signature'] !== "PK\x06\x06" ) {
289  $this->error( 'zip-bad', 'wrong signature on Zip64 end of central directory record' );
290  }
291  if ( $data['disk'] !== 0
292  || $data['CD start disk'] !== 0
293  ) {
294  $this->error( 'zip-unsupported', 'more than one disk (in EOCDR64)' );
295  }
296  }
297 
305  $size = $this->eocdr['CD size'];
306  $offset = $this->eocdr['CD offset'];
307  $endPos = $this->eocdr['position'];
308 
309  // Some readers use the EOCDR position instead of the offset field
310  // to find the directory, so to be safe, we check if they both agree.
311  if ( $offset + $size != $endPos ) {
312  $this->error( 'zip-bad', 'the central directory does not immediately precede the end ' .
313  'of central directory record' );
314  }
315 
316  return array( $offset, $size );
317  }
318 
326  // The spec is ambiguous about the exact rules of precedence between the
327  // ZIP64 headers and the original headers. Here we follow zip_util.c
328  // from OpenJDK 7.
329  $size = $this->eocdr['CD size'];
330  $offset = $this->eocdr['CD offset'];
331  $numEntries = $this->eocdr['CD entries total'];
332  $endPos = $this->eocdr['position'];
333  if ( $size == 0xffffffff
334  || $offset == 0xffffffff
335  || $numEntries == 0xffff
336  ) {
338 
339  if ( isset( $this->eocdr64Locator['eocdr64 offset'] ) ) {
341  if ( isset( $this->eocdr64['CD offset'] ) ) {
342  $size = $this->eocdr64['CD size'];
343  $offset = $this->eocdr64['CD offset'];
344  $endPos = $this->eocdr64Locator['eocdr64 offset'];
345  }
346  }
347  }
348  // Some readers use the EOCDR position instead of the offset field
349  // to find the directory, so to be safe, we check if they both agree.
350  if ( $offset + $size != $endPos ) {
351  $this->error( 'zip-bad', 'the central directory does not immediately precede the end ' .
352  'of central directory record' );
353  }
354 
355  return array( $offset, $size );
356  }
357 
361  function readCentralDirectory( $offset, $size ) {
362  $block = $this->getBlock( $offset, $size );
363 
364  $fixedInfo = array(
365  'signature' => array( 'string', 4 ),
366  'version made by' => 2,
367  'version needed' => 2,
368  'general bits' => 2,
369  'compression method' => 2,
370  'mod time' => 2,
371  'mod date' => 2,
372  'crc-32' => 4,
373  'compressed size' => 4,
374  'uncompressed size' => 4,
375  'name length' => 2,
376  'extra field length' => 2,
377  'comment length' => 2,
378  'disk number start' => 2,
379  'internal attrs' => 2,
380  'external attrs' => 4,
381  'local header offset' => 4,
382  );
383  $fixedSize = $this->getStructSize( $fixedInfo );
384 
385  $pos = 0;
386  while ( $pos < $size ) {
387  $data = $this->unpack( $block, $fixedInfo, $pos );
388  $pos += $fixedSize;
389 
390  if ( $data['signature'] !== "PK\x01\x02" ) {
391  $this->error( 'zip-bad', 'Invalid signature found in directory entry' );
392  }
393 
394  $variableInfo = array(
395  'name' => array( 'string', $data['name length'] ),
396  'extra field' => array( 'string', $data['extra field length'] ),
397  'comment' => array( 'string', $data['comment length'] ),
398  );
399  $data += $this->unpack( $block, $variableInfo, $pos );
400  $pos += $this->getStructSize( $variableInfo );
401 
402  if ( $this->zip64 && (
403  $data['compressed size'] == 0xffffffff
404  || $data['uncompressed size'] == 0xffffffff
405  || $data['local header offset'] == 0xffffffff )
406  ) {
407  $zip64Data = $this->unpackZip64Extra( $data['extra field'] );
408  if ( $zip64Data ) {
409  $data = $zip64Data + $data;
410  }
411  }
412 
413  if ( $this->testBit( $data['general bits'], self::GENERAL_CD_ENCRYPTED ) ) {
414  $this->error( 'zip-unsupported', 'central directory encryption is not supported' );
415  }
416 
417  // Convert the timestamp into MediaWiki format
418  // For the format, please see the MS-DOS 2.0 Programmer's Reference,
419  // pages 3-5 and 3-6.
420  $time = $data['mod time'];
421  $date = $data['mod date'];
422 
423  $year = 1980 + ( $date >> 9 );
424  $month = ( $date >> 5 ) & 15;
425  $day = $date & 31;
426  $hour = ( $time >> 11 ) & 31;
427  $minute = ( $time >> 5 ) & 63;
428  $second = ( $time & 31 ) * 2;
429  $timestamp = sprintf( "%04d%02d%02d%02d%02d%02d",
430  $year, $month, $day, $hour, $minute, $second );
431 
432  // Convert the character set in the file name
433  if ( !function_exists( 'iconv' )
434  || $this->testBit( $data['general bits'], self::GENERAL_UTF8 )
435  ) {
436  $name = $data['name'];
437  } else {
438  $name = iconv( 'CP437', 'UTF-8', $data['name'] );
439  }
440 
441  // Compile a data array for the user, with a sensible format
442  $userData = array(
443  'name' => $name,
444  'mtime' => $timestamp,
445  'size' => $data['uncompressed size'],
446  );
447  call_user_func( $this->callback, $userData );
448  }
449  }
450 
455  function unpackZip64Extra( $extraField ) {
456  $extraHeaderInfo = array(
457  'id' => 2,
458  'size' => 2,
459  );
460  $extraHeaderSize = $this->getStructSize( $extraHeaderInfo );
461 
462  $zip64ExtraInfo = array(
463  'uncompressed size' => 8,
464  'compressed size' => 8,
465  'local header offset' => 8,
466  'disk number start' => 4,
467  );
468 
469  $extraPos = 0;
470  while ( $extraPos < strlen( $extraField ) ) {
471  $extra = $this->unpack( $extraField, $extraHeaderInfo, $extraPos );
472  $extraPos += $extraHeaderSize;
473  $extra += $this->unpack( $extraField,
474  array( 'data' => array( 'string', $extra['size'] ) ),
475  $extraPos );
476  $extraPos += $extra['size'];
477 
478  if ( $extra['id'] == self::ZIP64_EXTRA_HEADER ) {
479  return $this->unpack( $extra['data'], $zip64ExtraInfo );
480  }
481  }
482 
483  return false;
484  }
485 
489  function getFileLength() {
490  if ( $this->fileLength === null ) {
491  $stat = fstat( $this->file );
492  $this->fileLength = $stat['size'];
493  }
494 
495  return $this->fileLength;
496  }
497 
508  function getBlock( $start, $length = null ) {
509  $fileLength = $this->getFileLength();
510  if ( $start >= $fileLength ) {
511  $this->error( 'zip-bad', "getBlock() requested position $start, " .
512  "file length is $fileLength" );
513  }
514  if ( $length === null ) {
515  $length = $fileLength - $start;
516  }
517  $end = $start + $length;
518  if ( $end > $fileLength ) {
519  $this->error( 'zip-bad', "getBlock() requested end position $end, " .
520  "file length is $fileLength" );
521  }
522  $startSeg = floor( $start / self::SEGSIZE );
523  $endSeg = ceil( $end / self::SEGSIZE );
524 
525  $block = '';
526  for ( $segIndex = $startSeg; $segIndex <= $endSeg; $segIndex++ ) {
527  $block .= $this->getSegment( $segIndex );
528  }
529 
530  $block = substr( $block,
531  $start - $startSeg * self::SEGSIZE,
532  $length );
533 
534  if ( strlen( $block ) < $length ) {
535  $this->error( 'zip-bad', 'getBlock() returned an unexpectedly small amount of data' );
536  }
537 
538  return $block;
539  }
540 
551  function getSegment( $segIndex ) {
552  if ( !isset( $this->buffer[$segIndex] ) ) {
553  $bytePos = $segIndex * self::SEGSIZE;
554  if ( $bytePos >= $this->getFileLength() ) {
555  $this->buffer[$segIndex] = '';
556 
557  return '';
558  }
559  if ( fseek( $this->file, $bytePos ) ) {
560  $this->error( 'zip-bad', "seek to $bytePos failed" );
561  }
562  $seg = fread( $this->file, self::SEGSIZE );
563  if ( $seg === false ) {
564  $this->error( 'zip-bad', "read from $bytePos failed" );
565  }
566  $this->buffer[$segIndex] = $seg;
567  }
568 
569  return $this->buffer[$segIndex];
570  }
571 
576  function getStructSize( $struct ) {
577  $size = 0;
578  foreach ( $struct as $type ) {
579  if ( is_array( $type ) ) {
580  list( , $fieldSize ) = $type;
581  $size += $fieldSize;
582  } else {
583  $size += $type;
584  }
585  }
586 
587  return $size;
588  }
589 
612  function unpack( $string, $struct, $offset = 0 ) {
613  $size = $this->getStructSize( $struct );
614  if ( $offset + $size > strlen( $string ) ) {
615  $this->error( 'zip-bad', 'unpack() would run past the end of the supplied string' );
616  }
617 
618  $data = array();
619  $pos = $offset;
620  foreach ( $struct as $key => $type ) {
621  if ( is_array( $type ) ) {
622  list( $typeName, $fieldSize ) = $type;
623  switch ( $typeName ) {
624  case 'string':
625  $data[$key] = substr( $string, $pos, $fieldSize );
626  $pos += $fieldSize;
627  break;
628  default:
629  throw new MWException( __METHOD__ . ": invalid type \"$typeName\"" );
630  }
631  } else {
632  // Unsigned little-endian integer
633  $length = intval( $type );
634 
635  // Calculate the value. Use an algorithm which automatically
636  // upgrades the value to floating point if necessary.
637  $value = 0;
638  for ( $i = $length - 1; $i >= 0; $i-- ) {
639  $value *= 256;
640  $value += ord( $string[$pos + $i] );
641  }
642 
643  // Throw an exception if there was loss of precision
644  if ( $value > pow( 2, 52 ) ) {
645  $this->error( 'zip-unsupported', 'number too large to be stored in a double. ' .
646  'This could happen if we tried to unpack a 64-bit structure ' .
647  'at an invalid location.' );
648  }
649  $data[$key] = $value;
650  $pos += $length;
651  }
652  }
653 
654  return $data;
655  }
656 
665  function testBit( $value, $bitIndex ) {
666  return (bool)( ( $value >> $bitIndex ) & 1 );
667  }
668 
672  function hexDump( $s ) {
673  $n = strlen( $s );
674  for ( $i = 0; $i < $n; $i += 16 ) {
675  printf( "%08X ", $i );
676  for ( $j = 0; $j < 16; $j++ ) {
677  print " ";
678  if ( $j == 8 ) {
679  print " ";
680  }
681  if ( $i + $j >= $n ) {
682  print " ";
683  } else {
684  printf( "%02X", ord( $s[$i + $j] ) );
685  }
686  }
687 
688  print " |";
689  for ( $j = 0; $j < 16; $j++ ) {
690  if ( $i + $j >= $n ) {
691  print " ";
692  } elseif ( ctype_print( $s[$i + $j] ) ) {
693  print $s[$i + $j];
694  } else {
695  print '.';
696  }
697  }
698  print "|\n";
699  }
700  }
701 }
702 
706 class ZipDirectoryReaderError extends Exception {
707  protected $errorCode;
708 
709  function __construct( $code ) {
710  $this->errorCode = $code;
711  parent::__construct( "ZipDirectoryReader error: $code" );
712  }
713 
717  function getErrorCode() {
718  return $this->errorCode;
719  }
720 }
ZipDirectoryReader\getBlock
getBlock( $start, $length=null)
Get the file contents from a given offset.
Definition: ZipDirectoryReader.php:508
$time
see documentation in includes Linker php for Linker::makeImageLink & $time
Definition: hooks.txt:1358
ZipDirectoryReader\readZip64EndOfCentralDirectoryLocator
readZip64EndOfCentralDirectoryLocator()
Read the header called the "ZIP64 end of central directory locator".
Definition: ZipDirectoryReader.php:241
ZipDirectoryReader\getFileLength
getFileLength()
Get the length of the file.
Definition: ZipDirectoryReader.php:489
data
and how to run hooks for an and one after Each event has a preferably in CamelCase For ArticleDelete hook A clump of code and data that should be run when an event happens This can be either a function and a chunk of data
Definition: hooks.txt:6
php
skin txt MediaWiki includes four core it has been set as the default in MediaWiki since the replacing Monobook it had been been the default skin since before being replaced by Vector largely rewritten in while keeping its appearance Several legacy skins were removed in the as the burden of supporting them became too heavy to bear Those in etc for skin dependent CSS etc for skin dependent JavaScript These can also be customised on a per user by etc This feature has led to a wide variety of user styles becoming that gallery is a good place to ending in php
Definition: skin.txt:62
$timestamp
if( $limit) $timestamp
Definition: importImages.php:104
$n
$n
Definition: RandomTest.php:76
Status\newGood
static newGood( $value=null)
Factory function for good results.
Definition: Status.php:77
ZipDirectoryReader\findZip64CentralDirectory
findZip64CentralDirectory()
Find the location of the central directory, as would be seen by a ZIP64-compliant reader.
Definition: ZipDirectoryReader.php:325
$s
$s
Definition: mergeMessageFileList.php:156
ZipDirectoryReader\unpack
unpack( $string, $struct, $offset=0)
Unpack a binary structure.
Definition: ZipDirectoryReader.php:612
ZipDirectoryReader\findOldCentralDirectory
findOldCentralDirectory()
Find the location of the central directory, as would be seen by a non-ZIP64 reader.
Definition: ZipDirectoryReader.php:304
ZipDirectoryReader\ZIP64_EXTRA_HEADER
const ZIP64_EXTRA_HEADER
The "extra field" ID for ZIP64 central directory entries.
Definition: ZipDirectoryReader.php:119
ZipDirectoryReader\unpackZip64Extra
unpackZip64Extra( $extraField)
Interpret ZIP64 "extra field" data and return an associative array.
Definition: ZipDirectoryReader.php:455
ZipDirectoryReader\$buffer
$buffer
A segmented cache of the file contents.
Definition: ZipDirectoryReader.php:105
ZipDirectoryReader\testBit
testBit( $value, $bitIndex)
Returns a bit from a given position in an integer value, converted to boolean.
Definition: ZipDirectoryReader.php:665
ZipDirectoryReader
A class for reading ZIP file directories, for the purposes of upload verification.
Definition: ZipDirectoryReader.php:31
file
We ve cleaned up the code here by removing clumps of infrequently used code and moving them off somewhere else It s much easier for someone working with this code to see what s _really_ going and make changes or fix bugs In we can take all the code that deals with the little used title reversing we can concentrate it all in an extension file
Definition: hooks.txt:93
ZipDirectoryReader\$file
$file
The opened file resource.
Definition: ZipDirectoryReader.php:99
MWException
MediaWiki exception.
Definition: MWException.php:26
ZipDirectoryReader\hexDump
hexDump( $s)
Debugging helper function which dumps a string in hexdump -C format.
Definition: ZipDirectoryReader.php:672
ZipDirectoryReader\$data
$data
Definition: ZipDirectoryReader.php:116
ZipDirectoryReader\execute
execute()
Read the directory according to settings in $this.
Definition: ZipDirectoryReader.php:147
ZipDirectoryReader\__construct
__construct( $fileName, $callback, $options)
Private constructor.
Definition: ZipDirectoryReader.php:133
ZipDirectoryReader\$fileName
$fileName
The file name.
Definition: ZipDirectoryReader.php:96
array
the array() calling protocol came about after MediaWiki 1.4rc1.
List of Api Query prop modules.
ZipDirectoryReader\getStructSize
getStructSize( $struct)
Get the size of a structure in bytes.
Definition: ZipDirectoryReader.php:576
ZipDirectoryReader\readZip64EndOfCentralDirectoryRecord
readZip64EndOfCentralDirectoryRecord()
Read the header called the "ZIP64 end of central directory record".
Definition: ZipDirectoryReader.php:266
ZipDirectoryReader\error
error( $code, $debugMessage)
Throw an error, and log a debug message.
Definition: ZipDirectoryReader.php:185
ZipDirectoryReader\$callback
$callback
The file data callback.
Definition: ZipDirectoryReader.php:108
list
deferred txt A few of the database updates required by various functions here can be deferred until after the result page is displayed to the user For updating the view updating the linked to tables after a etc PHP does not yet have any way to tell the server to actually return and disconnect while still running these but it might have such a feature in the future We handle these by creating a deferred update object and putting those objects on a global list
Definition: deferred.txt:11
$options
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped & $options
Definition: hooks.txt:1530
wfDebug
wfDebug( $text, $dest='all')
Sends a line to the debug log if enabled or, optionally, to a comment in output.
Definition: GlobalFunctions.php:933
ZipDirectoryReader\$eocdr64
$eocdr64
Definition: ZipDirectoryReader.php:114
$name
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:336
ZipDirectoryReader\$eocdr64Locator
$eocdr64Locator
Definition: ZipDirectoryReader.php:114
$size
$size
Definition: RandomTest.php:75
$value
$value
Definition: styleTest.css.php:45
ZipDirectoryReader\GENERAL_UTF8
const GENERAL_UTF8
The index of the "general field" bit for UTF-8 file names.
Definition: ZipDirectoryReader.php:125
ZipDirectoryReaderError\$errorCode
$errorCode
Definition: ZipDirectoryReader.php:707
ZipDirectoryReader\getSegment
getSegment( $segIndex)
Get a section of the file starting at position $segIndex * self::SEGSIZE, of length self::SEGSIZE.
Definition: ZipDirectoryReader.php:551
ZipDirectoryReaderError\__construct
__construct( $code)
Definition: ZipDirectoryReader.php:709
ZipDirectoryReader\readEndOfCentralDirectoryRecord
readEndOfCentralDirectoryRecord()
Read the header which is at the end of the central directory, unimaginatively called the "end of cent...
Definition: ZipDirectoryReader.php:195
ZipDirectoryReader\readCentralDirectory
readCentralDirectory( $offset, $size)
Read the central directory at the given location.
Definition: ZipDirectoryReader.php:361
ZipDirectoryReader\$eocdr
$eocdr
Stored headers.
Definition: ZipDirectoryReader.php:114
ZipDirectoryReaderError\getErrorCode
getErrorCode()
Definition: ZipDirectoryReader.php:717
as
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
ZipDirectoryReader\$fileLength
$fileLength
The cached length of the file, or null if it has not been loaded yet.
Definition: ZipDirectoryReader.php:102
ZipDirectoryReader\GENERAL_CD_ENCRYPTED
const GENERAL_CD_ENCRYPTED
The index of the "general field" bit for central directory encryption.
Definition: ZipDirectoryReader.php:128
$e
if( $useReadline) $e
Definition: eval.php:66
ZipDirectoryReader\read
static read( $fileName, $callback, $options=array())
Read a ZIP file and call a function for each file discovered in it.
Definition: ZipDirectoryReader.php:89
ZipDirectoryReader\SEGSIZE
const SEGSIZE
The segment size for the file contents cache.
Definition: ZipDirectoryReader.php:122
Status\newFatal
static newFatal( $message)
Factory function for fatal errors.
Definition: Status.php:63
ZipDirectoryReaderError
Internal exception class.
Definition: ZipDirectoryReader.php:706
ZipDirectoryReader\$zip64
$zip64
The ZIP64 mode.
Definition: ZipDirectoryReader.php:111
$type
$type
Definition: testCompression.php:46