Exemplo n.º 1
0
 private function buildZip64EndOfCentralDirectoryLocator($cdRecLength)
 {
     $zip64RecStart = Count64::construct($this->offset, !$this->zip64)->add($cdRecLength);
     return '' . pack32le(self::ZIP64_END_OF_CENTRAL_DIR_LOCATOR) . pack32le(0) . pack64le($zip64RecStart) . pack32le(1);
     // total number of disks                       4 bytes
 }
 protected function assertOutputZipfileOK($files, $options)
 {
     if (0 < sizeof($files)) {
         // php5.3 does not combine empty arrays
         $files = array_combine(array_map(function ($element) {
             return $element->filename;
         }, $files), $files);
     }
     $output = $this->getOutput();
     $eocdrec = EndOfCentralDirectoryRecord::constructFromString($output);
     $this->assertEquals(strlen($output) - 1, $eocdrec->end, "EOCDR last item in file");
     if ($options['zip64']) {
         $eocdrec->assertValues(array("numberDisk" => 0xffff, "numberDiskStartCD" => 0xffff, "numberEntriesDisk" => 0xffff, "numberEntriesCD" => 0xffff, "size" => 0xffffffff, "offsetStart" => 0xffffffff, "lengthComment" => 0, "comment" => ''));
         $z64eocdloc = Zip64EndOfCentralDirectoryLocator::constructFromString($output, strlen($output) - ($eocdrec->begin + 1));
         $this->assertEquals($z64eocdloc->end + 1, $eocdrec->begin, "Z64EOCDL directly before EOCDR");
         $z64eocdloc->assertValues(array("numberDiskStartZ64EOCDL" => 0, "numberDisks" => 1));
         $z64eocdrec = Zip64EndOfCentralDirectoryRecord::constructFromString($output, strlen($output) - ($z64eocdloc->begin + 1));
         $this->assertEquals(Count64::construct($z64eocdrec->begin), $z64eocdloc->offsetStart, "Z64EOCDR begin");
         $this->assertEquals($z64eocdrec->end + 1, $z64eocdloc->begin, "Z64EOCDR directly before Z64EOCDL");
         $z64eocdrec->assertValues(array("size" => Count64::construct(44), "madeByVersion" => pack16le(self::ATTR_MADE_BY_VERSION), "versionToExtract" => pack16le($this->getVersionToExtract($options['zip64'], False)), "numberDisk" => 0, "numberDiskStartCDR" => 0, "numberEntriesDisk" => Count64::construct(sizeof($files)), "numberEntriesCD" => Count64::construct(sizeof($files))));
         $sizeCD = $z64eocdrec->sizeCD->getLoBytes();
         $offsetCD = $z64eocdrec->offsetStart->getLoBytes();
         $beginFollowingRecord = $z64eocdrec->begin;
     } else {
         $eocdrec->assertValues(array("numberDisk" => 0, "numberDiskStartCD" => 0, "numberEntriesDisk" => sizeof($files), "numberEntriesCD" => sizeof($files), "lengthComment" => 0, "comment" => ''));
         $sizeCD = $eocdrec->size;
         $offsetCD = $eocdrec->offsetStart;
         $beginFollowingRecord = $eocdrec->begin;
     }
     $cdheaders = array();
     $pos = $offsetCD;
     $cdhead = null;
     while ($pos < $beginFollowingRecord) {
         $cdhead = CentralDirectoryHeader::constructFromString($output, $pos);
         $filename = $cdhead->filename;
         $pos = $cdhead->end + 1;
         $cdheaders[$filename] = $cdhead;
         $this->assertArrayHasKey($filename, $files, "CDH entry has valid name");
         $cdhead->assertValues(array("madeByVersion" => pack16le(self::ATTR_MADE_BY_VERSION), "versionToExtract" => pack16le($this->getVersionToExtract($options['zip64'], File::DIR == $files[$filename]->type)), "gpFlags" => File::FILE == $files[$filename]->type ? pack16le(GPFLAGS::ADD) : pack16le(GPFLAGS::NONE), "gzMethod" => File::FILE == $files[$filename]->type ? pack16le($options['compress']) : pack16le(COMPR::STORE), "dosTime" => pack32le(ZipStreamer::getDosTime($files[$filename]->date)), "lengthFilename" => strlen($filename), "lengthComment" => 0, "fileAttrInternal" => pack16le(0x0), "fileAttrExternal" => File::FILE == $files[$filename]->type ? pack32le(self::EXT_FILE_ATTR_FILE) : pack32le(self::EXT_FILE_ATTR_DIR)));
         if ($options['zip64']) {
             $cdhead->assertValues(array("sizeCompressed" => 0xffffffff, "size" => 0xffffffff, "lengthExtraField" => 32, "diskNumberStart" => 0xffff, "offsetStart" => 0xffffffff));
             $cdhead->z64Ext->assertValues(array("sizeField" => 28, "size" => Count64::construct($files[$filename]->getSize()), "diskNumberStart" => 0));
         } else {
             $cdhead->assertValues(array("size" => $files[$filename]->getSize(), "lengthExtraField" => 0, "diskNumberStart" => 0));
         }
     }
     if (0 < sizeof($files)) {
         $this->assertEquals($cdhead->end + 1, $beginFollowingRecord, "CDH directly before following record");
         $this->assertEquals(sizeof($files), sizeof($cdheaders), "CDH has correct number of entries");
         $this->assertEquals($sizeCD, $beginFollowingRecord - $offsetCD, "CDH has correct size");
     } else {
         $this->assertNull($cdhead);
     }
     $first = True;
     foreach ($cdheaders as $filename => $cdhead) {
         if ($options['zip64']) {
             $sizeCompressed = $cdhead->z64Ext->sizeCompressed->getLoBytes();
             $offsetStart = $cdhead->z64Ext->offsetStart->getLoBytes();
         } else {
             $sizeCompressed = $cdhead->sizeCompressed;
             $offsetStart = $cdhead->offsetStart;
         }
         if ($first) {
             $this->assertEquals(0, $offsetStart, "first file directly at beginning of zipfile");
         } else {
             $this->assertEquals($endLastFile + 1, $offsetStart, "file immediately after last file");
         }
         $file = FileEntry::constructFromString($output, $offsetStart, $sizeCompressed);
         $this->assertEquals($files[$filename]->data, $file->data);
         $this->assertEquals(crc32($files[$filename]->data), $cdhead->dataCRC32);
         if (GPFLAGS::ADD & $file->lfh->gpFlags) {
             $this->assertNotNull($file->dd, "data descriptor present (flag ADD set)");
         }
         if ($options['zip64']) {
             $file->lfh->assertValues(array("sizeCompressed" => 0xffffffff, "size" => 0xffffffff));
             $file->lfh->z64Ext->assertValues(array("sizeField" => 28, "size" => Count64::construct(0), "sizeCompressed" => Count64::construct(0), "diskNumberStart" => 0));
         } else {
             $file->lfh->assertValues(array("sizeCompressed" => 0, "size" => 0));
         }
         $file->lfh->assertValues(array("versionToExtract" => pack16le($this->getVersionToExtract($options['zip64'], File::DIR == $files[$filename]->type)), "gpFlags" => File::FILE == $files[$filename]->type ? GPFLAGS::ADD : GPFLAGS::NONE, "gzMethod" => File::FILE == $files[$filename]->type ? $options['compress'] : COMPR::STORE, "dosTime" => pack32le(ZipStreamer::getDosTime($files[$filename]->date)), "dataCRC32" => 0x0, "lengthFilename" => strlen($filename), "filename" => $filename));
         $endLastFile = $file->end;
         $first = False;
     }
     if (0 < sizeof($files)) {
         $this->assertEquals($offsetCD, $endLastFile + 1, "last file directly before CDH");
     } else {
         $this->assertEquals(0, $beginFollowingRecord, "empty zip file, CD records at beginning of file");
     }
 }
Exemplo n.º 3
0
 public function readFromString($str, $pos, $size = -1)
 {
     $this->begin = $pos;
     $this->dataCRC32 = (int) unpack32le(readstr($str, $pos, 4));
     if (20 == $size) {
         $this->sizeCompressed = unpack64le(readstr($str, $pos, 8));
         $this->size = unpack64le(readstr($str, $pos, 8));
     } else {
         $this->sizeCompressed = Count64::construct((int) unpack32le(readstr($str, $pos, 4)));
         $this->size = Count64::construct((int) unpack32le(readstr($str, $pos, 4)));
     }
     $this->end = $pos - 1;
 }
Exemplo n.º 4
0
/**
 * Unpack 8 byte binary string, little endian format to 8 byte data
 *
 * @param string $data binary string
 * @return Count64Base data
 */
function unpack64le($data)
{
    $bytes = unpack('V2', $data);
    return Count64::construct(array($bytes[1], $bytes[2]));
}