public static function getMagicBytes() { if (!array_key_exists(static::$MAGIC, self::$magicBytes)) { if (2 == static::$magicLength) { self::$magicBytes[static::$MAGIC] = pack16le(static::$MAGIC); } else { self::$magicBytes[static::$MAGIC] = pack32le(static::$MAGIC); } } return self::$magicBytes[static::$MAGIC]; }
private function write_block($header, $data) { return '' . pack8($header) . pack16le(strlen($data)) . pack16le(0xffff ^ strlen($data)) . $data . ''; }
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"); } }