Skip to content

Commit dbb87c7

Browse files
authored
turn on zip64 only when needed (#15)
1 parent 3b598fa commit dbb87c7

File tree

4 files changed

+44
-19
lines changed

4 files changed

+44
-19
lines changed

config/config.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
return [
77
// Default options for our archives
88
'archive' => [
9-
'zip64' => env('ZIPSTREAM_ENABLE_ZIP64', true),
10-
119
'predict' => env('ZIPSTREAM_PREDICT_SIZE', true)
1210
],
1311

src/ZipStream.php

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -160,15 +160,15 @@ public function getMeta(): Collection
160160
public function process(): int
161161
{
162162
$this->bytesSent = 0;
163+
$this->configureZip64();
163164

164165
event(new ZipStreaming($this));
165166

166-
$this->queue->map->toZipStreamFile($this)->each->process();
167-
168167
$predicted = $this->canPredictZipSize()
169168
? $this->predictZipSize()
170169
: false;
171170

171+
$this->queue->map->toZipStreamFile($this)->each->process();
172172
$this->finish();
173173
$this->getOutputStream()->close();
174174

@@ -178,13 +178,23 @@ public function process(): int
178178

179179
event(new ZipStreamed($this));
180180

181-
if ($predicted && $predicted != $this->getFinalSize()) {
181+
if ($predicted !== false && $predicted != $this->getFinalSize()) {
182182
event(new ZipSizePredictionFailed($this, $predicted, $this->getFinalSize()));
183183
}
184184

185185
return $this->getFinalSize();
186186
}
187187

188+
public function configureZip64()
189+
{
190+
$this->opt->setEnableZip64(
191+
// More than 65535 files
192+
count($this->files) > 0xFFFF
193+
// Filesize over max 32 bit integer
194+
|| $this->queue->sum->getFilesize() > 0xFFFFFFFF
195+
);
196+
}
197+
188198
/**
189199
* @return StreamedResponse
190200
*/
@@ -324,17 +334,33 @@ public function predictZipSize(): int
324334
return $this->predictedSize;
325335
}
326336

337+
$this->configureZip64();
338+
$this->predictedSize = $this->calculateZipSize();
339+
340+
// It's conceivable that we didn't need Zip64 until the zip headers/decriptors were added.
341+
// If so, turn on Zip64 and calculate again.
342+
if(!$this->opt->isEnableZip64() && $this->predictedSize > 0xFFFFFFFF) {
343+
$this->opt->setEnableZip64(true);
344+
$this->predictedSize = $this->calculateZipSize();
345+
}
346+
347+
return $this->predictedSize;
348+
}
349+
350+
/**
351+
* @return int
352+
*/
353+
protected function calculateZipSize(): int
354+
{
327355
$this->bytesSent = 0;
328356
$this->calculateOnly = true;
329357

330358
$this->queue->map->toZipStreamFile($this)->each->calculate();
331359
$this->finish();
332360

333-
$this->predictedSize = $this->queue->sum->getFilesize() + $this->getFinalSize();
334-
335361
$this->calculateOnly = false;
336362

337-
return $this->predictedSize;
363+
return $this->queue->sum->getFilesize() + $this->getFinalSize();
338364
}
339365

340366
/**

src/ZipStreamServiceProvider.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ public function provides()
5555
protected function buildArchiveOptions(array $config)
5656
{
5757
return tap(new ArchiveOptions(), function(ArchiveOptions $options) use($config) {
58-
$options->setEnableZip64($config['zip64']);
5958
$options->setZeroHeader(true);
6059
});
6160
}

tests/ZipTest.php

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,18 @@ public function testSaveZipOutput()
2929
file_put_contents("/tmp/test2.txt", "this is the second test file for test run $testrun");
3030

3131
/** @var ZipStream $zip */
32-
$zip = Zip::create("my.zip", ["/tmp/test1.txt", "/tmp/test2.txt"]);
32+
$zip = Zip::create("small.zip", ["/tmp/test1.txt", "/tmp/test2.txt"]);
3333
$sizePrediction = $zip->predictZipSize();
3434
$zip->saveTo("/tmp");
3535

36-
$this->assertTrue(file_exists("/tmp/my.zip"));
37-
$this->assertEquals($sizePrediction, filesize("/tmp/my.zip"));
36+
$this->assertFalse($zip->opt->isEnableZip64());
37+
$this->assertTrue(file_exists("/tmp/small.zip"));
38+
$this->assertEquals($sizePrediction, filesize("/tmp/small.zip"));
3839

39-
$z = zip_open("/tmp/my.zip");
40+
$z = zip_open("/tmp/small.zip");
4041
$this->assertEquals("this is the first test file for test run $testrun", zip_entry_read(zip_read($z)));
4142

42-
unlink("/tmp/my.zip");
43+
unlink("/tmp/small.zip");
4344
}
4445

4546
public function testSaveZip64Output()
@@ -51,16 +52,17 @@ public function testSaveZip64Output()
5152
exec('dd if=/dev/zero count=1024 bs=1048576 >/tmp/medfile.txt');
5253

5354
/** @var ZipStream $zip */
54-
$zip = Zip::create("my.zip", ["/tmp/test1.txt", "/tmp/test2.txt", "/tmp/bigfile.txt", "/tmp/medfile.txt"]);
55+
$zip = Zip::create("large.zip", ["/tmp/test1.txt", "/tmp/test2.txt", "/tmp/bigfile.txt", "/tmp/medfile.txt"]);
5556
$sizePrediction = $zip->predictZipSize();
5657
$zip->saveTo("/tmp");
5758

58-
$this->assertTrue(file_exists("/tmp/my.zip"));
59-
$this->assertEquals($sizePrediction, filesize("/tmp/my.zip"));
59+
$this->assertTrue($zip->opt->isEnableZip64());
60+
$this->assertTrue(file_exists("/tmp/large.zip"));
61+
$this->assertEquals($sizePrediction, filesize("/tmp/large.zip"));
6062

61-
$z = zip_open("/tmp/my.zip");
63+
$z = zip_open("/tmp/large.zip");
6264
$this->assertEquals("this is the first test file for test run $testrun", zip_entry_read(zip_read($z)));
6365

64-
unlink("/tmp/my.zip");
66+
unlink("/tmp/large.zip");
6567
}
6668
}

0 commit comments

Comments
 (0)