1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.commons.compress.archivers.zip;
21
22 import static org.apache.commons.compress.AbstractTest.getFile;
23 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
24 import static org.junit.jupiter.api.Assertions.assertEquals;
25 import static org.junit.jupiter.api.Assertions.assertFalse;
26 import static org.junit.jupiter.api.Assertions.assertNotNull;
27 import static org.junit.jupiter.api.Assertions.assertNull;
28 import static org.junit.jupiter.api.Assertions.assertThrows;
29 import static org.junit.jupiter.api.Assertions.assertTrue;
30 import static org.junit.jupiter.api.Assumptions.assumeTrue;
31
32 import java.io.BufferedOutputStream;
33 import java.io.File;
34 import java.io.FileOutputStream;
35 import java.io.IOException;
36 import java.io.InputStream;
37 import java.io.RandomAccessFile;
38 import java.nio.file.Files;
39 import java.util.Enumeration;
40 import java.util.Random;
41 import java.util.concurrent.atomic.AtomicInteger;
42 import java.util.zip.ZipEntry;
43
44 import org.apache.commons.compress.AbstractTest;
45 import org.apache.commons.io.RandomAccessFileMode;
46 import org.junit.jupiter.api.Test;
47
48 import shaded.org.apache.commons.io.IOUtils;
49
50
51
52
53 public class Zip64SupportIT {
54
55 interface ZipOutputTest {
56 void test(File f, ZipArchiveOutputStream zos) throws IOException;
57 }
58
59 private static final long FIVE_BILLION = 5000000000L;
60 private static final int ONE_MILLION = 1000000;
61
62 private static final int ONE_HUNDRED_THOUSAND = 100000;
63
64 private static final ZipOutputTest write100KFilesModeNever = (f, zos) -> {
65 zos.setUseZip64(Zip64Mode.Never);
66 final Zip64RequiredException ex = assertThrows(Zip64RequiredException.class, () -> write100KFilesToStream(zos), "expected a Zip64RequiredException");
67 assertEquals(Zip64RequiredException.TOO_MANY_ENTRIES_MESSAGE, ex.getMessage());
68 };
69
70 private static final ZipOutputTest write3EntriesCreatingBigArchiveModeNever = (f, zos) -> {
71 zos.setUseZip64(Zip64Mode.Never);
72 final Zip64RequiredException ex = assertThrows(Zip64RequiredException.class, () -> write3EntriesCreatingBigArchiveToStream(zos),
73 "expected a Zip64RequiredException");
74 assertEquals(Zip64RequiredException.ARCHIVE_TOO_BIG_MESSAGE, ex.getMessage());
75 };
76
77 private static File get100KFileFile() throws Throwable {
78 return getFile("100k_Files.zip");
79 }
80
81 private static File get100KFileFileGeneratedBy7ZIP() throws Throwable {
82 return getFile("100k_Files_7ZIP.zip");
83 }
84
85 private static File get100KFileFileGeneratedByJava7Jar() throws Throwable {
86 return getFile("100k_Files_jar.zip");
87 }
88
89 private static File get100KFileFileGeneratedByPKZip() throws Throwable {
90 return getFile("100k_Files_PKZip.zip");
91 }
92
93 private static File get100KFileFileGeneratedByWinCF() throws Throwable {
94 return getFile("100k_Files_WindowsCompressedFolders.zip");
95 }
96
97 private static File get100KFileFileGeneratedByWinZIP() throws Throwable {
98 return getFile("100k_Files_WinZIP.zip");
99 }
100
101 private static File get5GBZerosFile() throws Throwable {
102 return getFile("5GB_of_Zeros.zip");
103 }
104
105 private static File get5GBZerosFileGeneratedBy7ZIP() throws Throwable {
106 return getFile("5GB_of_Zeros_7ZIP.zip");
107 }
108
109 private static File get5GBZerosFileGeneratedByJava7Jar() throws Throwable {
110 return getFile("5GB_of_Zeros_jar.zip");
111 }
112
113 private static File get5GBZerosFileGeneratedByPKZip() throws Throwable {
114 return getFile("5GB_of_Zeros_PKZip.zip");
115 }
116
117 private static File get5GBZerosFileGeneratedByWinZIP() throws Throwable {
118 return getFile("5GB_of_Zeros_WinZip.zip");
119 }
120
121 private static long getLengthAndPositionAtCentralDirectory(final RandomAccessFile a) throws IOException {
122 final long end = a.length();
123 a.seek(end - 22 - 20);
124 final byte[] sig = new byte[4];
125 a.readFully(sig);
126 if (sig[0] != (byte) 0x50 || sig[1] != (byte) 0x4b || sig[2] != 6 || sig[3] != 7) {
127
128 return getLengthAndPositionAtCentralDirectory32(a, end);
129 }
130
131 final long cdOffsetLoc = end - 22 - 20 - 56 + 48;
132
133 a.seek(cdOffsetLoc);
134 final byte[] cdOffset = new byte[8];
135 a.readFully(cdOffset);
136 a.seek(ZipEightByteInteger.getLongValue(cdOffset));
137 return end;
138 }
139
140 private static long getLengthAndPositionAtCentralDirectory32(final RandomAccessFile a, final long end) throws IOException {
141 a.seek(end - 22 + 16);
142 final byte[] cdOffset = new byte[4];
143 a.readFully(cdOffset);
144 a.seek(ZipLong.getValue(cdOffset));
145 return end;
146 }
147
148 private static File getTempFile(final String testName) throws Throwable {
149 final File f = File.createTempFile("commons-compress-" + testName, ".zip");
150 f.deleteOnExit();
151 return f;
152 }
153
154 private static void read100KFilesImpl(final File f) throws IOException {
155 try (InputStream fin = Files.newInputStream(f.toPath());
156 ZipArchiveInputStream zin = new ZipArchiveInputStream(fin)) {
157 int files = 0;
158 ZipArchiveEntry zae;
159 while ((zae = zin.getNextZipEntry()) != null) {
160 if (!zae.isDirectory()) {
161 files++;
162 assertEquals(0, zae.getSize());
163 }
164 }
165 assertEquals(ONE_HUNDRED_THOUSAND, files);
166 }
167 }
168
169 private static void read100KFilesUsingZipFileImpl(final File file) throws IOException {
170 ZipFile zipFile = null;
171 try {
172 zipFile = ZipFile.builder().setFile(file).get();
173 final AtomicInteger files = new AtomicInteger();
174 zipFile.stream().filter(e -> !e.isDirectory()).forEach(e -> {
175 files.incrementAndGet();
176 assertEquals(0, e.getSize());
177 });
178 assertEquals(ONE_HUNDRED_THOUSAND, files.get());
179 } finally {
180 ZipFile.closeQuietly(zipFile);
181 }
182 }
183
184 private static void read5GBOfZerosImpl(final File f, final String expectedName) throws IOException {
185 try (InputStream fin = Files.newInputStream(f.toPath());
186 ZipArchiveInputStream zin = new ZipArchiveInputStream(fin)) {
187 ZipArchiveEntry zae = zin.getNextZipEntry();
188 while (zae.isDirectory()) {
189 zae = zin.getNextZipEntry();
190 }
191 assertEquals(expectedName, zae.getName());
192 final byte[] buf = new byte[1024 * 1024];
193 long read = 0;
194 final Random r = new Random(System.currentTimeMillis());
195 int readNow;
196 while ((readNow = zin.read(buf, 0, buf.length)) > 0) {
197
198
199 for (int i = 0; i < 1024; i++) {
200 final int idx = r.nextInt(readNow);
201 assertEquals(0, buf[idx], "testing byte " + (read + idx));
202 }
203 read += readNow;
204 }
205 assertEquals(FIVE_BILLION, read);
206 assertNull(zin.getNextZipEntry());
207 assertEquals(FIVE_BILLION, zae.getSize());
208 }
209 }
210
211 private static void read5GBOfZerosUsingZipFileImpl(final File f, final String expectedName) throws IOException {
212 ZipFile zf = null;
213 try {
214 zf = ZipFile.builder().setFile(f).get();
215 final Enumeration<ZipArchiveEntry> e = zf.getEntries();
216 assertTrue(e.hasMoreElements());
217 ZipArchiveEntry zae = e.nextElement();
218 while (zae.isDirectory()) {
219 zae = e.nextElement();
220 }
221 assertEquals(expectedName, zae.getName());
222 assertEquals(FIVE_BILLION, zae.getSize());
223 final byte[] buf = new byte[1024 * 1024];
224 long read = 0;
225 final Random r = new Random(System.currentTimeMillis());
226 int readNow;
227 try (InputStream zin = zf.getInputStream(zae)) {
228 while ((readNow = zin.read(buf, 0, buf.length)) > 0) {
229
230
231 for (int i = 0; i < 1024; i++) {
232 final int idx = r.nextInt(readNow);
233 assertEquals(0, buf[idx], "testing byte " + (read + idx));
234 }
235 read += readNow;
236 }
237 }
238 assertEquals(FIVE_BILLION, read);
239 assertFalse(e.hasMoreElements());
240 } finally {
241 ZipFile.closeQuietly(zf);
242 }
243 }
244
245 private static void withTemporaryArchive(final String testName, final ZipOutputTest test, final boolean useRandomAccessFile) throws Throwable {
246 withTemporaryArchive(testName, test, useRandomAccessFile, null);
247 }
248
249 private static void withTemporaryArchive(final String testName, final ZipOutputTest test, final boolean useRandomAccessFile, final Long splitSize)
250 throws Throwable {
251 File f = getTempFile(testName);
252 File dir = null;
253 if (splitSize != null) {
254 dir = Files.createTempDirectory("commons-compress-" + testName).toFile();
255 dir.deleteOnExit();
256
257 f = new File(dir, "commons-compress-" + testName + ".zip");
258 }
259 BufferedOutputStream os = null;
260 ZipArchiveOutputStream zos = useRandomAccessFile ? new ZipArchiveOutputStream(f)
261 : new ZipArchiveOutputStream(os = new BufferedOutputStream(Files.newOutputStream(f.toPath())));
262 if (splitSize != null) {
263 zos = new ZipArchiveOutputStream(f, splitSize);
264 }
265
266 try {
267 test.test(f, zos);
268 } catch (final IOException ex) {
269 System.err.println("Failed to write archive because of: " + ex.getMessage() + " - likely not enough disk space.");
270 assumeTrue(false);
271 } finally {
272 try {
273 zos.destroy();
274 } finally {
275 try {
276 IOUtils.close(os);
277 AbstractTest.forceDelete(f);
278 } finally {
279 if (dir != null) {
280 final File directory = dir;
281 AbstractTest.forceDelete(directory);
282 }
283 }
284 }
285 }
286 }
287
288 private static ZipOutputTest write100KFiles() {
289 return write100KFiles(Zip64Mode.AsNeeded);
290 }
291
292 private static ZipOutputTest write100KFiles(final Zip64Mode mode) {
293 return (f, zos) -> {
294 if (mode != Zip64Mode.AsNeeded) {
295 zos.setUseZip64(mode);
296 }
297 write100KFilesToStream(zos);
298 try (RandomAccessFile a = RandomAccessFileMode.READ_ONLY.create(f)) {
299 final long end = a.length();
300
301
302
303
304 a.seek(end - 22 );
305 final byte[] eocd = new byte[12];
306 a.readFully(eocd);
307 assertArrayEquals(new byte[] {
308
309 (byte) 0x50, (byte) 0x4b, 5, 6,
310
311 0, 0, 0, 0,
312
313 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, }, eocd);
314
315
316
317
318
319 final long expectedZ64EocdOffset = end - 22
320 - 20
321 - 56 ;
322 final byte[] loc = ZipEightByteInteger.getBytes(expectedZ64EocdOffset);
323 a.seek(end - 22 - 20);
324 final byte[] z64EocdLoc = new byte[20];
325 a.readFully(z64EocdLoc);
326 assertArrayEquals(new byte[] {
327
328 (byte) 0x50, (byte) 0x4b, 6, 7,
329
330 0, 0, 0, 0,
331
332 loc[0], loc[1], loc[2], loc[3], loc[4], loc[5], loc[6], loc[7],
333
334 1, 0, 0, 0, }, z64EocdLoc);
335
336
337
338
339
340 a.seek(expectedZ64EocdOffset);
341 final byte[] z64EocdStart = new byte[40];
342 a.readFully(z64EocdStart);
343 assertArrayEquals(new byte[] {
344
345 (byte) 0x50, (byte) 0x4b, 6, 6,
346
347 44, 0, 0, 0, 0, 0, 0, 0,
348
349 45, 0,
350
351 45, 0,
352
353 0, 0, 0, 0, 0, 0, 0, 0,
354
355 (byte) 0xA0, (byte) 0x86, 1, 0, 0, 0, 0, 0, (byte) 0xA0, (byte) 0x86, 1, 0, 0, 0, 0, 0, }, z64EocdStart);
356 a.seek(expectedZ64EocdOffset + 48 );
357 final byte[] cdOffset = new byte[8];
358 a.readFully(cdOffset);
359 final long cdLoc = ZipEightByteInteger.getLongValue(cdOffset);
360
361
362
363 a.seek(cdLoc);
364 final byte[] sig = new byte[4];
365 a.readFully(sig);
366 assertArrayEquals(new byte[] { (byte) 0x50, (byte) 0x4b, 1, 2, }, sig);
367 }
368 };
369 }
370
371 private static void write100KFilesToStream(final ZipArchiveOutputStream zos) throws IOException {
372 for (int i = 0; i < ONE_HUNDRED_THOUSAND; i++) {
373 final ZipArchiveEntry zae = new ZipArchiveEntry(String.valueOf(i));
374 zae.setSize(0);
375 zos.putArchiveEntry(zae);
376 zos.closeArchiveEntry();
377 }
378 zos.close();
379 }
380
381 private static ZipOutputTest write3EntriesCreatingBigArchive() {
382 return write3EntriesCreatingBigArchive(Zip64Mode.AsNeeded);
383 }
384
385 private static ZipOutputTest write3EntriesCreatingBigArchive(final Zip64Mode mode) {
386 return write3EntriesCreatingBigArchive(mode, false);
387 }
388
389
390
391
392
393
394
395 private static ZipOutputTest write3EntriesCreatingBigArchive(final Zip64Mode mode, final boolean isSplitArchive) {
396 return (f, zos) -> {
397 if (mode != Zip64Mode.AsNeeded) {
398 zos.setUseZip64(mode);
399 }
400 write3EntriesCreatingBigArchiveToStream(zos);
401
402 try (RandomAccessFile a = RandomAccessFileMode.READ_ONLY.create(f)) {
403 getLengthAndPositionAtCentralDirectory(a);
404
405 a.skipBytes(2 * 47
406
407
408 + 2 * (mode == Zip64Mode.Always ? 32 : 0)
409
410 );
411
412
413
414
415 final byte[] header = new byte[12];
416 a.readFully(header);
417 assertArrayEquals(new byte[] {
418
419 (byte) 0x50, (byte) 0x4b, 1, 2,
420
421 45, 0,
422
423 45, 0,
424
425 0, 8,
426
427 0, 0 }, header, "CDH start");
428
429 a.skipBytes(12);
430
431 final byte[] originalSize = new byte[4];
432 a.readFully(originalSize);
433 if (mode == Zip64Mode.Always) {
434 assertArrayEquals(new byte[] { (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, }, originalSize, "CDH original size");
435 } else {
436 assertArrayEquals(new byte[] { 1, 0, 0, 0 }, originalSize, "CDH original size");
437 }
438 final byte[] rest = new byte[19];
439 a.readFully(rest);
440 assertArrayEquals(new byte[] {
441
442 1, 0,
443
444 (byte) (mode == Zip64Mode.Always ? 32 : 12), 0,
445
446 0, 0,
447
448 (byte) (isSplitArchive ? 0xFF : 0), (byte) (isSplitArchive ? 0xFF : 0),
449
450 0, 0, 0, 0, 0, 0,
451
452 (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
453
454 (byte) '2' }, rest, "CDH rest");
455 if (mode == Zip64Mode.Always) {
456 final byte[] extra1 = new byte[12];
457 a.readFully(extra1);
458 assertArrayEquals(new byte[] {
459
460 1, 0,
461
462 28, 0,
463
464 1, 0, 0, 0, 0, 0, 0, 0, }, extra1, "CDH extra");
465
466 a.skipBytes(8);
467 } else {
468 final byte[] extra2 = new byte[4];
469 a.readFully(extra2);
470 assertArrayEquals(new byte[] {
471
472 1, 0,
473
474 8, 0, }, extra2, "CDH extra");
475 }
476
477
478 final byte[] offset = new byte[8];
479 a.readFully(offset);
480
481 a.seek(ZipEightByteInteger.getLongValue(offset));
482 final byte[] sig = new byte[4];
483 a.readFully(sig);
484 assertArrayEquals(new byte[] { (byte) 0x50, (byte) 0x4b, 3, 4, }, sig, "LFH signature");
485 }
486 };
487 }
488
489 private static void write3EntriesCreatingBigArchiveToStream(final ZipArchiveOutputStream zos) throws IOException {
490 final byte[] buf = new byte[ONE_MILLION];
491 ZipArchiveEntry zae;
492 for (int i = 0; i < 2; i++) {
493 zae = new ZipArchiveEntry(String.valueOf(i));
494 zae.setSize(FIVE_BILLION / 2);
495 zae.setMethod(ZipEntry.STORED);
496 zae.setCrc(0x8a408f16L);
497 zos.putArchiveEntry(zae);
498 for (int j = 0; j < FIVE_BILLION / 2 / 1000 / 1000; j++) {
499 zos.write(buf);
500 }
501 zos.closeArchiveEntry();
502 }
503 zae = new ZipArchiveEntry(String.valueOf(2));
504 zae.setSize(1);
505 zae.setMethod(ZipEntry.STORED);
506 zae.setCrc(0x9b9265bL);
507 zos.putArchiveEntry(zae);
508 zos.write(new byte[] { 42 });
509 zos.closeArchiveEntry();
510 zos.close();
511 }
512
513 private static File write5GBZerosFile(final String testName) throws Throwable {
514 final File f = getTempFile(testName);
515 final ZipArchiveOutputStream zos = new ZipArchiveOutputStream(f);
516 try {
517 zos.setUseZip64(Zip64Mode.Always);
518 final byte[] buf = new byte[ONE_MILLION];
519 final ZipArchiveEntry zae = new ZipArchiveEntry("5GB_of_Zeros");
520 zae.setSize(FIVE_BILLION);
521 zae.setMethod(ZipEntry.DEFLATED);
522 zae.setCrc(0x8a408f16L);
523 zos.putArchiveEntry(zae);
524 for (int j = 0; j < FIVE_BILLION / 1000 / 1000; j++) {
525 zos.write(buf);
526 }
527 zos.closeArchiveEntry();
528 zos.close();
529 } catch (final IOException ex) {
530 System.err.println("Failed to write archive because of: " + ex.getMessage() + " - likely not enough disk space.");
531 assumeTrue(false);
532 } finally {
533 zos.destroy();
534 }
535 return f;
536 }
537
538 private static ZipOutputTest writeBigDeflatedEntryToFile(final boolean knownSize) {
539 return writeBigDeflatedEntryToFile(knownSize, Zip64Mode.AsNeeded);
540 }
541
542
543
544
545
546
547
548
549 private static ZipOutputTest writeBigDeflatedEntryToFile(final boolean knownSize, final Zip64Mode mode) {
550 return (f, zos) -> {
551 if (mode != Zip64Mode.AsNeeded) {
552 zos.setUseZip64(mode);
553 }
554 final byte[] buf = new byte[ONE_MILLION];
555 final ZipArchiveEntry zae = new ZipArchiveEntry("0");
556 if (knownSize) {
557 zae.setSize(FIVE_BILLION);
558 }
559 zae.setMethod(ZipEntry.DEFLATED);
560 zos.putArchiveEntry(zae);
561 for (int j = 0; j < FIVE_BILLION / 1000 / 1000; j++) {
562 zos.write(buf);
563 }
564 zos.closeArchiveEntry();
565 zos.close();
566
567 try (RandomAccessFile a = RandomAccessFileMode.READ_ONLY.create(f)) {
568 getLengthAndPositionAtCentralDirectory(a);
569
570
571
572
573
574 byte[] header = new byte[12];
575 a.readFully(header);
576 assertArrayEquals(new byte[] {
577
578 (byte) 0x50, (byte) 0x4b, 1, 2,
579
580 45, 0,
581
582 45, 0,
583
584 0, 8,
585
586 8, 0, }, header, "CDH start");
587
588 a.skipBytes(4);
589 byte[] rest = new byte[26];
590 a.readFully(rest);
591 assertArrayEquals(new byte[] {
592
593 (byte) 0x50, (byte) 0x6F, (byte) 0x31, (byte) 0x5c,
594
595 (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
596
597 (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
598
599 1, 0,
600
601 (byte) (mode == Zip64Mode.Always ? 32 : 20), 0,
602
603 0, 0,
604
605 0, 0,
606
607 0, 0, 0, 0, 0, 0, }, rest, "CDH rest");
608 byte[] offset = new byte[4];
609 a.readFully(offset);
610 if (mode == Zip64Mode.Always) {
611 assertArrayEquals(new byte[] { (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, }, offset, "offset");
612 } else {
613 assertArrayEquals(new byte[] { 0, 0, 0, 0, }, offset, "offset");
614 }
615 assertEquals('0', a.read());
616 byte[] extra = new byte[12];
617 a.readFully(extra);
618
619 assertArrayEquals(new byte[] {
620
621 1, 0,
622
623 (byte) (mode == Zip64Mode.Always ? 28 : 16), 0,
624
625 0, (byte) 0xF2, 5, (byte) 0x2A, 1, 0, 0, 0, }, extra, "CDH extra");
626 if (mode == Zip64Mode.Always) {
627
628 a.skipBytes(8);
629 offset = new byte[8];
630 a.readFully(offset);
631 assertArrayEquals(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, }, offset, "extra offset");
632 }
633
634
635 a.seek(0);
636 header = new byte[10];
637 a.readFully(header);
638 assertArrayEquals(new byte[] {
639
640 (byte) 0x50, (byte) 0x4b, 3, 4,
641
642 45, 0,
643
644 0, 8,
645
646 8, 0, }, header, "LFH start");
647
648 a.skipBytes(4);
649 rest = new byte[17];
650 a.readFully(rest);
651 assertArrayEquals(new byte[] {
652
653 (byte) 0x50, (byte) 0x6F, (byte) 0x31, (byte) 0x5c,
654
655 (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
656
657 (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
658
659 1, 0,
660
661 20, 0,
662
663 (byte) '0' }, rest);
664 extra = new byte[12];
665 a.readFully(extra);
666 assertArrayEquals(new byte[] {
667
668 1, 0,
669
670 16, 0,
671
672 0, (byte) 0xF2, 5, (byte) 0x2A, 1, 0, 0, 0,
673
674 }, extra);
675 }
676 };
677 }
678
679
680
681
682
683
684
685
686 private static ZipOutputTest writeBigDeflatedEntryToFileModeNever(final boolean knownSize) {
687 return (f, zos) -> {
688 zos.setUseZip64(Zip64Mode.Never);
689 final Zip64RequiredException ex = assertThrows(Zip64RequiredException.class, () -> {
690 final byte[] buf = new byte[ONE_MILLION];
691 final ZipArchiveEntry zae = new ZipArchiveEntry("0");
692 if (knownSize) {
693 zae.setSize(FIVE_BILLION);
694 }
695 zae.setMethod(ZipEntry.DEFLATED);
696 zos.putArchiveEntry(zae);
697 for (int j = 0; j < FIVE_BILLION / 1000 / 1000; j++) {
698 zos.write(buf);
699 }
700 zos.closeArchiveEntry();
701 }, "expected a Zip64RequiredException");
702 assertTrue(ex.getMessage().startsWith("0's size"));
703 };
704 }
705
706
707
708
709
710
711
712
713 private static ZipOutputTest writeBigDeflatedEntryToStream(final boolean knownSize, final Zip64Mode mode) {
714 return (f, zos) -> {
715 if (mode != Zip64Mode.AsNeeded) {
716 zos.setUseZip64(mode);
717 }
718 final byte[] buf = new byte[ONE_MILLION];
719 final ZipArchiveEntry zae = new ZipArchiveEntry("0");
720 if (knownSize) {
721 zae.setSize(FIVE_BILLION);
722 }
723 zae.setMethod(ZipEntry.DEFLATED);
724 zos.putArchiveEntry(zae);
725 for (int j = 0; j < FIVE_BILLION / 1000 / 1000; j++) {
726 zos.write(buf);
727 }
728 zos.closeArchiveEntry();
729 zos.close();
730
731 try (RandomAccessFile a = RandomAccessFileMode.READ_ONLY.create(f)) {
732 getLengthAndPositionAtCentralDirectory(a);
733
734 final long cfhPos = a.getFilePointer();
735
736
737
738
739 byte[] header = new byte[12];
740 a.readFully(header);
741 assertArrayEquals(new byte[] {
742
743 (byte) 0x50, (byte) 0x4b, 1, 2,
744
745 45, 0,
746
747 45, 0,
748
749 8, 8,
750
751 8, 0, }, header, "CDH start");
752
753 a.skipBytes(4);
754 byte[] rest = new byte[26];
755 a.readFully(rest);
756 assertArrayEquals(new byte[] {
757
758 (byte) 0x50, (byte) 0x6F, (byte) 0x31, (byte) 0x5c,
759
760 (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
761
762 (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
763
764 1, 0,
765
766 (byte) (mode == Zip64Mode.Always ? 32 : 20), 0,
767
768 0, 0,
769
770 0, 0,
771
772 0, 0, 0, 0, 0, 0, }, rest, "CDH rest");
773 byte[] offset = new byte[4];
774 a.readFully(offset);
775 if (mode == Zip64Mode.Always) {
776 assertArrayEquals(new byte[] { (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, }, offset, "offset");
777 } else {
778 assertArrayEquals(new byte[] { 0, 0, 0, 0, }, offset, "offset");
779 }
780 assertEquals('0', a.read());
781 byte[] extra = new byte[12];
782 a.readFully(extra);
783
784 assertArrayEquals(new byte[] {
785
786 1, 0,
787
788 (byte) (mode == Zip64Mode.Always ? 28 : 16), 0,
789
790 0, (byte) 0xF2, 5, (byte) 0x2A, 1, 0, 0, 0, }, extra, "CDH extra");
791 if (mode == Zip64Mode.Always) {
792
793 a.skipBytes(8);
794 offset = new byte[8];
795 a.readFully(offset);
796 assertArrayEquals(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, }, offset, "extra offset");
797 }
798
799
800 a.seek(cfhPos - 24);
801 byte[] dd = new byte[8];
802 a.readFully(dd);
803 assertArrayEquals(new byte[] {
804
805 (byte) 0x50, (byte) 0x4b, 7, 8,
806
807 (byte) 0x50, (byte) 0x6F, (byte) 0x31, (byte) 0x5c, }, dd, "DD");
808
809 a.skipBytes(8);
810 dd = new byte[8];
811 a.readFully(dd);
812 assertArrayEquals(new byte[] {
813
814 0, (byte) 0xF2, 5, (byte) 0x2A, 1, 0, 0, 0, }, dd, "DD sizes");
815
816
817 a.seek(0);
818 header = new byte[10];
819 a.readFully(header);
820 assertArrayEquals(new byte[] {
821
822 (byte) 0x50, (byte) 0x4b, 3, 4,
823
824 45, 0,
825
826 8, 8,
827
828 8, 0, }, header, "LFH start");
829
830 a.skipBytes(4);
831 rest = new byte[17];
832 a.readFully(rest);
833 assertArrayEquals(new byte[] {
834
835 0, 0, 0, 0,
836
837 (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
838
839 (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
840
841 1, 0,
842
843 20, 0,
844
845 (byte) '0' }, rest, "LFH rest");
846 extra = new byte[20];
847 a.readFully(extra);
848 assertArrayEquals(new byte[] {
849
850 1, 0,
851
852 16, 0,
853
854 0, 0, 0, 0, 0, 0, 0, 0,
855
856 0, 0, 0, 0, 0, 0, 0, 0, }, extra, "LFH extra");
857 }
858 };
859 }
860
861 private static ZipOutputTest writeBigDeflatedEntryUnknownSizeToStream(final Zip64Mode mode) {
862 return (f, zos) -> {
863 final Zip64RequiredException ex = assertThrows(Zip64RequiredException.class, () -> {
864 if (mode != Zip64Mode.AsNeeded) {
865 zos.setUseZip64(mode);
866 }
867 final byte[] buf = new byte[ONE_MILLION];
868 final ZipArchiveEntry zae = new ZipArchiveEntry("0");
869 zae.setMethod(ZipEntry.DEFLATED);
870 zos.putArchiveEntry(zae);
871 for (int j = 0; j < FIVE_BILLION / 1000 / 1000; j++) {
872 zos.write(buf);
873 }
874 zos.closeArchiveEntry();
875 }, "expected a Zip64RequiredException");
876 assertTrue(ex.getMessage().startsWith("0's size"));
877 };
878 }
879
880 private static ZipOutputTest writeBigStoredEntry(final boolean knownSize) {
881 return writeBigStoredEntry(knownSize, Zip64Mode.AsNeeded);
882 }
883
884
885
886
887
888
889
890
891 private static ZipOutputTest writeBigStoredEntry(final boolean knownSize, final Zip64Mode mode) {
892 return (f, zos) -> {
893 if (mode != Zip64Mode.AsNeeded) {
894 zos.setUseZip64(mode);
895 }
896 final byte[] buf = new byte[ONE_MILLION];
897 final ZipArchiveEntry zae = new ZipArchiveEntry("0");
898 if (knownSize) {
899 zae.setSize(FIVE_BILLION);
900 zae.setCrc(0x5c316f50L);
901 }
902 zae.setMethod(ZipEntry.STORED);
903 zos.putArchiveEntry(zae);
904 for (int j = 0; j < FIVE_BILLION / 1000 / 1000; j++) {
905 zos.write(buf);
906 }
907 zos.closeArchiveEntry();
908 zos.close();
909
910 try (RandomAccessFile a = RandomAccessFileMode.READ_ONLY.create(f)) {
911 getLengthAndPositionAtCentralDirectory(a);
912
913
914
915
916 byte[] header = new byte[12];
917 a.readFully(header);
918 assertArrayEquals(new byte[] {
919
920 (byte) 0x50, (byte) 0x4b, 1, 2,
921
922 45, 0,
923
924 45, 0,
925
926 0, 8,
927
928 0, 0 }, header, "CDH start");
929
930 a.skipBytes(4);
931 byte[] rest = new byte[26];
932 a.readFully(rest);
933 assertArrayEquals(new byte[] {
934
935 (byte) 0x50, (byte) 0x6F, (byte) 0x31, (byte) 0x5c,
936
937 (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
938
939 (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
940
941 1, 0,
942
943 (byte) (mode == Zip64Mode.Always ? 32 : 20), 0,
944
945 0, 0,
946
947 0, 0,
948
949 0, 0, 0, 0, 0, 0, }, rest, "CDH rest");
950 byte[] offset = new byte[4];
951 a.readFully(offset);
952 if (mode == Zip64Mode.Always) {
953 assertArrayEquals(new byte[] { (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, }, offset, "offset");
954 } else {
955 assertArrayEquals(new byte[] { 0, 0, 0, 0, }, offset, "offset");
956 }
957 assertEquals('0', a.read());
958 final byte[] extra = new byte[20];
959 a.readFully(extra);
960
961 assertArrayEquals(new byte[] {
962
963 1, 0,
964
965 (byte) (mode == Zip64Mode.Always ? 28 : 16), 0,
966
967 0, (byte) 0xF2, 5, (byte) 0x2A, 1, 0, 0, 0,
968
969 0, (byte) 0xF2, 5, (byte) 0x2A, 1, 0, 0, 0, }, extra, "CDH extra");
970 if (mode == Zip64Mode.Always) {
971 offset = new byte[8];
972 a.readFully(offset);
973 assertArrayEquals(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, }, offset, "extra offset");
974 }
975
976
977 a.seek(0);
978 header = new byte[10];
979 a.readFully(header);
980 assertArrayEquals(new byte[] {
981
982 (byte) 0x50, (byte) 0x4b, 3, 4,
983
984 45, 0,
985
986 0, 8,
987
988 0, 0 }, header, "LFH start");
989
990 a.skipBytes(4);
991 rest = new byte[17];
992 a.readFully(rest);
993 assertArrayEquals(new byte[] {
994
995 (byte) 0x50, (byte) 0x6F, (byte) 0x31, (byte) 0x5c,
996
997 (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
998
999 (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1000
1001 1, 0,
1002
1003 20, 0,
1004
1005 (byte) '0' }, rest, "LFH rest");
1006 a.readFully(extra);
1007
1008 assertArrayEquals(new byte[] {
1009
1010 1, 0,
1011
1012 16, 0,
1013
1014 0, (byte) 0xF2, 5, (byte) 0x2A, 1, 0, 0, 0,
1015
1016 0, (byte) 0xF2, 5, (byte) 0x2A, 1, 0, 0, 0, }, extra, "LFH extra");
1017 }
1018 };
1019 }
1020
1021 private static ZipOutputTest writeBigStoredEntryModeNever(final boolean knownSize) {
1022 return (f, zos) -> {
1023 zos.setUseZip64(Zip64Mode.Never);
1024 final Zip64RequiredException ex = assertThrows(Zip64RequiredException.class, () -> {
1025 final byte[] buf = new byte[ONE_MILLION];
1026 final ZipArchiveEntry zae = new ZipArchiveEntry("0");
1027 if (knownSize) {
1028 zae.setSize(FIVE_BILLION);
1029 zae.setCrc(0x5c316f50L);
1030 }
1031 zae.setMethod(ZipEntry.STORED);
1032 zos.putArchiveEntry(zae);
1033 for (int j = 0; j < FIVE_BILLION / 1000 / 1000; j++) {
1034 zos.write(buf);
1035 }
1036 zos.closeArchiveEntry();
1037 }, "expected a Zip64RequiredException");
1038 assertTrue(ex.getMessage().startsWith("0's size"));
1039 };
1040 }
1041
1042 private static ZipOutputTest writeSmallDeflatedEntryToFile(final boolean knownSize) {
1043 return writeSmallDeflatedEntryToFile(knownSize, Zip64Mode.AsNeeded);
1044 }
1045
1046
1047
1048
1049
1050
1051 private static ZipOutputTest writeSmallDeflatedEntryToFile(final boolean knownSize, final Zip64Mode mode) {
1052 return (f, zos) -> {
1053 if (mode != Zip64Mode.AsNeeded) {
1054 zos.setUseZip64(mode);
1055 }
1056 final byte[] buf = new byte[ONE_MILLION];
1057 final ZipArchiveEntry zae = new ZipArchiveEntry("0");
1058 if (knownSize) {
1059 zae.setSize(ONE_MILLION);
1060 }
1061 zae.setMethod(ZipEntry.DEFLATED);
1062 zos.putArchiveEntry(zae);
1063 zos.write(buf);
1064 zos.closeArchiveEntry();
1065 zos.close();
1066
1067 try (RandomAccessFile a = RandomAccessFileMode.READ_ONLY.create(f)) {
1068 getLengthAndPositionAtCentralDirectory(a);
1069
1070
1071
1072
1073 byte[] header = new byte[12];
1074 a.readFully(header);
1075 assertArrayEquals(new byte[] {
1076
1077 (byte) 0x50, (byte) 0x4b, 1, 2,
1078
1079 20, 0,
1080
1081 20, 0,
1082
1083 0, 8,
1084
1085 8, 0, }, header);
1086
1087 a.skipBytes(4);
1088 byte[] crc = new byte[4];
1089 a.readFully(crc);
1090 assertArrayEquals(new byte[] { (byte) 0x9E, (byte) 0xCB, (byte) 0x79, (byte) 0x12, }, crc);
1091
1092 a.skipBytes(4);
1093 byte[] rest = new byte[23];
1094 a.readFully(rest);
1095 assertArrayEquals(new byte[] {
1096
1097 (byte) 0x40, (byte) 0x42, (byte) 0x0F, 0,
1098
1099 1, 0,
1100
1101 0, 0,
1102
1103 0, 0,
1104
1105 0, 0,
1106
1107 0, 0, 0, 0, 0, 0,
1108
1109 0, 0, 0, 0,
1110
1111 (byte) '0' }, rest);
1112
1113
1114 a.seek(0);
1115 header = new byte[10];
1116 a.readFully(header);
1117 assertArrayEquals(new byte[] {
1118
1119 (byte) 0x50, (byte) 0x4b, 3, 4,
1120
1121 20, 0,
1122
1123 0, 8,
1124
1125 8, 0, }, header);
1126
1127 a.skipBytes(4);
1128 crc = new byte[4];
1129 a.readFully(crc);
1130 assertArrayEquals(new byte[] { (byte) 0x9E, (byte) 0xCB, (byte) 0x79, (byte) 0x12, }, crc);
1131
1132 a.skipBytes(4);
1133 rest = new byte[9];
1134 a.readFully(rest);
1135
1136 final boolean hasExtra = mode == Zip64Mode.AsNeeded && !knownSize;
1137
1138 assertArrayEquals(new byte[] {
1139
1140 (byte) 0x40, (byte) 0x42, (byte) 0x0F, 0,
1141
1142 1, 0,
1143
1144 (byte) (!hasExtra ? 0 : 20), 0,
1145
1146 (byte) '0' }, rest);
1147 if (hasExtra) {
1148 final byte[] extra = new byte[12];
1149 a.readFully(extra);
1150 assertArrayEquals(new byte[] {
1151
1152 1, 0,
1153
1154 16, 0,
1155
1156 (byte) 0x40, (byte) 0x42, (byte) 0x0F, 0, 0, 0, 0, 0,
1157
1158
1159
1160
1161 }, extra);
1162 }
1163 }
1164 };
1165 }
1166
1167
1168
1169
1170
1171
1172 private static ZipOutputTest writeSmallDeflatedEntryToFileModeAlways(final boolean knownSize) {
1173 return (f, zos) -> {
1174 zos.setUseZip64(Zip64Mode.Always);
1175 final byte[] buf = new byte[ONE_MILLION];
1176 final ZipArchiveEntry zae = new ZipArchiveEntry("0");
1177 if (knownSize) {
1178 zae.setSize(ONE_MILLION);
1179 }
1180 zae.setMethod(ZipEntry.DEFLATED);
1181 zos.putArchiveEntry(zae);
1182 zos.write(buf);
1183 zos.closeArchiveEntry();
1184 zos.close();
1185
1186 try (RandomAccessFile a = RandomAccessFileMode.READ_ONLY.create(f)) {
1187 getLengthAndPositionAtCentralDirectory(a);
1188
1189
1190
1191
1192 byte[] header = new byte[12];
1193 a.readFully(header);
1194 assertArrayEquals(new byte[] {
1195
1196 (byte) 0x50, (byte) 0x4b, 1, 2,
1197
1198 45, 0,
1199
1200 45, 0,
1201
1202 0, 8,
1203
1204 8, 0, }, header, "CDH start");
1205
1206 a.skipBytes(4);
1207 byte[] crc = new byte[4];
1208 a.readFully(crc);
1209 assertArrayEquals(new byte[] { (byte) 0x9E, (byte) 0xCB, (byte) 0x79, (byte) 0x12, }, crc, "CDH CRC");
1210
1211 a.skipBytes(4);
1212 byte[] rest = new byte[23];
1213 a.readFully(rest);
1214 assertArrayEquals(new byte[] {
1215
1216 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
1217
1218 1, 0,
1219
1220 32, 0,
1221
1222 0, 0,
1223
1224 0, 0,
1225
1226 0, 0, 0, 0, 0, 0,
1227
1228 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
1229
1230 (byte) '0' }, rest, "CDH rest");
1231 byte[] extra = new byte[12];
1232 a.readFully(extra);
1233 assertArrayEquals(new byte[] {
1234
1235 1, 0,
1236
1237 28, 0,
1238
1239 (byte) 0x40, (byte) 0x42, (byte) 0x0F, 0, 0, 0, 0, 0, }, extra, "CDH extra");
1240
1241 a.skipBytes(8);
1242 final byte[] offset = new byte[8];
1243 a.readFully(offset);
1244 assertArrayEquals(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, }, offset, "extra offset");
1245
1246
1247 a.seek(0);
1248 header = new byte[10];
1249 a.readFully(header);
1250 assertArrayEquals(new byte[] {
1251
1252 (byte) 0x50, (byte) 0x4b, 3, 4,
1253
1254 45, 0,
1255
1256 0, 8,
1257
1258 8, 0, }, header, "LFH start");
1259
1260 a.skipBytes(4);
1261 crc = new byte[4];
1262 a.readFully(crc);
1263 assertArrayEquals(new byte[] { (byte) 0x9E, (byte) 0xCB, (byte) 0x79, (byte) 0x12, }, crc, "LFH CRC");
1264 rest = new byte[13];
1265 a.readFully(rest);
1266
1267 assertArrayEquals(new byte[] {
1268
1269 (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1270
1271 (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1272
1273 1, 0,
1274
1275 20, 0,
1276
1277 (byte) '0' }, rest, "LFH rest");
1278
1279 extra = new byte[12];
1280 a.readFully(extra);
1281 assertArrayEquals(new byte[] {
1282
1283 1, 0,
1284
1285 16, 0,
1286
1287 (byte) 0x40, (byte) 0x42, (byte) 0x0F, 0, 0, 0, 0, 0,
1288
1289
1290
1291
1292 }, extra, "LFH extra");
1293 }
1294 };
1295 }
1296
1297
1298
1299
1300
1301
1302 private static ZipOutputTest writeSmallDeflatedEntryToStream(final boolean knownSize, final Zip64Mode mode) {
1303 return (f, zos) -> {
1304 if (mode != Zip64Mode.AsNeeded) {
1305 zos.setUseZip64(mode);
1306 }
1307 final byte[] buf = new byte[ONE_MILLION];
1308 final ZipArchiveEntry zae = new ZipArchiveEntry("0");
1309 if (knownSize) {
1310 zae.setSize(ONE_MILLION);
1311 }
1312 zae.setMethod(ZipEntry.DEFLATED);
1313 zos.putArchiveEntry(zae);
1314 zos.write(buf);
1315 zos.closeArchiveEntry();
1316 zos.close();
1317
1318 try (RandomAccessFile a = RandomAccessFileMode.READ_ONLY.create(f)) {
1319 getLengthAndPositionAtCentralDirectory(a);
1320
1321 final long cfhPos = a.getFilePointer();
1322
1323
1324
1325 byte[] header = new byte[12];
1326 a.readFully(header);
1327 assertArrayEquals(new byte[] {
1328
1329 (byte) 0x50, (byte) 0x4b, 1, 2,
1330
1331 20, 0,
1332
1333 20, 0,
1334
1335 8, 8,
1336
1337 8, 0, }, header);
1338
1339 a.skipBytes(4);
1340 final byte[] crc = new byte[4];
1341 a.readFully(crc);
1342 assertArrayEquals(new byte[] { (byte) 0x9E, (byte) 0xCB, (byte) 0x79, (byte) 0x12, }, crc);
1343
1344 a.skipBytes(4);
1345 byte[] rest = new byte[23];
1346 a.readFully(rest);
1347 assertArrayEquals(new byte[] {
1348
1349 (byte) 0x40, (byte) 0x42, (byte) 0x0F, 0,
1350
1351 1, 0,
1352
1353 0, 0,
1354
1355 0, 0,
1356
1357 0, 0,
1358
1359 0, 0, 0, 0, 0, 0,
1360
1361 0, 0, 0, 0,
1362
1363 (byte) '0' }, rest);
1364
1365
1366 a.seek(cfhPos - 16);
1367 byte[] dd = new byte[8];
1368 a.readFully(dd);
1369 assertArrayEquals(new byte[] {
1370
1371 (byte) 0x50, (byte) 0x4b, 7, 8,
1372
1373 (byte) 0x9E, (byte) 0xCB, (byte) 0x79, (byte) 0x12, }, dd);
1374
1375 a.skipBytes(4);
1376 dd = new byte[4];
1377 a.readFully(dd);
1378 assertArrayEquals(new byte[] {
1379
1380 (byte) 0x40, (byte) 0x42, (byte) 0x0F, 0, }, dd);
1381
1382
1383 a.seek(0);
1384 header = new byte[10];
1385 a.readFully(header);
1386 assertArrayEquals(new byte[] {
1387
1388 (byte) 0x50, (byte) 0x4b, 3, 4,
1389
1390 20, 0,
1391
1392 8, 8,
1393
1394 8, 0, }, header);
1395
1396 a.skipBytes(4);
1397 rest = new byte[17];
1398 a.readFully(rest);
1399 assertArrayEquals(new byte[] {
1400
1401 0, 0, 0, 0,
1402
1403 0, 0, 0, 0,
1404
1405 0, 0, 0, 0,
1406
1407 1, 0,
1408
1409 0, 0,
1410
1411 (byte) '0' }, rest);
1412 }
1413 };
1414
1415 }
1416
1417
1418
1419
1420
1421
1422 private static ZipOutputTest writeSmallDeflatedEntryToStreamModeAlways(final boolean knownSize) {
1423 return (f, zos) -> {
1424 zos.setUseZip64(Zip64Mode.Always);
1425 final byte[] buf = new byte[ONE_MILLION];
1426 final ZipArchiveEntry zae = new ZipArchiveEntry("0");
1427 if (knownSize) {
1428 zae.setSize(ONE_MILLION);
1429 }
1430 zae.setMethod(ZipEntry.DEFLATED);
1431 zos.putArchiveEntry(zae);
1432 zos.write(buf);
1433 zos.closeArchiveEntry();
1434 zos.close();
1435
1436 try (RandomAccessFile a = RandomAccessFileMode.READ_ONLY.create(f)) {
1437 getLengthAndPositionAtCentralDirectory(a);
1438
1439 final long cfhPos = a.getFilePointer();
1440
1441
1442
1443 byte[] header = new byte[12];
1444 a.readFully(header);
1445 assertArrayEquals(new byte[] {
1446
1447 (byte) 0x50, (byte) 0x4b, 1, 2,
1448
1449 45, 0,
1450
1451 45, 0,
1452
1453 8, 8,
1454
1455 8, 0, }, header, "CDH start");
1456
1457 a.skipBytes(4);
1458 final byte[] crc = new byte[4];
1459 a.readFully(crc);
1460 assertArrayEquals(new byte[] { (byte) 0x9E, (byte) 0xCB, (byte) 0x79, (byte) 0x12, }, crc);
1461
1462 a.skipBytes(4);
1463 byte[] rest = new byte[23];
1464 a.readFully(rest);
1465 assertArrayEquals(new byte[] {
1466
1467 (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1468
1469 1, 0,
1470
1471 32, 0,
1472
1473 0, 0,
1474
1475 0, 0,
1476
1477 0, 0, 0, 0, 0, 0,
1478
1479 (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1480
1481 (byte) '0' }, rest, "CDH rest");
1482 byte[] extra = new byte[12];
1483 a.readFully(extra);
1484 assertArrayEquals(new byte[] {
1485
1486 1, 0,
1487
1488 28, 0,
1489
1490 (byte) 0x40, (byte) 0x42, (byte) 0x0F, 0, 0, 0, 0, 0, }, extra, "CDH extra");
1491
1492 a.skipBytes(8);
1493 final byte[] offset = new byte[8];
1494 a.readFully(offset);
1495 assertArrayEquals(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, }, offset, "extra offset");
1496
1497
1498 a.seek(cfhPos - 24);
1499 byte[] dd = new byte[8];
1500 a.readFully(dd);
1501 assertArrayEquals(new byte[] {
1502
1503 (byte) 0x50, (byte) 0x4b, 7, 8,
1504
1505 (byte) 0x9E, (byte) 0xCB, (byte) 0x79, (byte) 0x12, }, dd, "DD");
1506
1507 a.skipBytes(8);
1508 dd = new byte[8];
1509 a.readFully(dd);
1510 assertArrayEquals(new byte[] {
1511
1512 (byte) 0x40, (byte) 0x42, (byte) 0x0F, 0, 0, 0, 0, 0 }, dd, "DD size");
1513
1514
1515 a.seek(0);
1516 header = new byte[10];
1517 a.readFully(header);
1518 assertArrayEquals(new byte[] {
1519
1520 (byte) 0x50, (byte) 0x4b, 3, 4,
1521
1522 45, 0,
1523
1524 8, 8,
1525
1526 8, 0, }, header, "LFH start");
1527
1528 a.skipBytes(4);
1529 rest = new byte[17];
1530 a.readFully(rest);
1531 assertArrayEquals(new byte[] {
1532
1533 0, 0, 0, 0,
1534
1535 (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1536
1537 (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1538
1539 1, 0,
1540
1541 20, 0,
1542
1543 (byte) '0' }, rest, "LFH rest");
1544
1545 extra = new byte[20];
1546 a.readFully(extra);
1547 assertArrayEquals(new byte[] {
1548
1549 1, 0,
1550
1551 16, 0,
1552
1553 0, 0, 0, 0, 0, 0, 0, 0,
1554
1555 0, 0, 0, 0, 0, 0, 0, 0, }, extra, "LFH extra");
1556 }
1557 };
1558
1559 }
1560
1561 private static ZipOutputTest writeSmallStoredEntry(final boolean knownSize) {
1562 return writeSmallStoredEntry(knownSize, Zip64Mode.AsNeeded);
1563 }
1564
1565
1566
1567
1568
1569
1570
1571
1572 private static ZipOutputTest writeSmallStoredEntry(final boolean knownSize, final Zip64Mode mode) {
1573 return (f, zos) -> {
1574 if (mode != Zip64Mode.AsNeeded) {
1575 zos.setUseZip64(mode);
1576 }
1577 final byte[] buf = new byte[ONE_MILLION];
1578 final ZipArchiveEntry zae = new ZipArchiveEntry("0");
1579 if (knownSize) {
1580 zae.setSize(ONE_MILLION);
1581 zae.setCrc(0x1279CB9EL);
1582 }
1583 zae.setMethod(ZipEntry.STORED);
1584 zos.putArchiveEntry(zae);
1585 zos.write(buf);
1586 zos.closeArchiveEntry();
1587 zos.close();
1588
1589 try (RandomAccessFile a = RandomAccessFileMode.READ_ONLY.create(f)) {
1590 getLengthAndPositionAtCentralDirectory(a);
1591
1592
1593
1594
1595 byte[] header = new byte[12];
1596 a.readFully(header);
1597 assertArrayEquals(new byte[] {
1598
1599 (byte) 0x50, (byte) 0x4b, 1, 2,
1600
1601 20, 0,
1602
1603 10, 0,
1604
1605 0, 8,
1606
1607 0, 0 }, header, "CDH start");
1608
1609 a.skipBytes(4);
1610 byte[] rest = new byte[31];
1611 a.readFully(rest);
1612
1613 assertArrayEquals(new byte[] {
1614
1615 (byte) 0x9E, (byte) 0xCB, (byte) 0x79, (byte) 0x12,
1616
1617 (byte) 0x40, (byte) 0x42, (byte) 0x0F, 0,
1618
1619 (byte) 0x40, (byte) 0x42, (byte) 0x0F, 0,
1620
1621 1, 0,
1622
1623 0, 0,
1624
1625 0, 0,
1626
1627 0, 0,
1628
1629 0, 0, 0, 0, 0, 0,
1630
1631 0, 0, 0, 0,
1632
1633 (byte) '0' }, rest, "CDH rest");
1634
1635
1636
1637
1638
1639 final boolean hasExtra = mode == Zip64Mode.Always || mode == Zip64Mode.AsNeeded && !knownSize;
1640 a.seek(0);
1641 header = new byte[10];
1642 a.readFully(header);
1643 assertArrayEquals(new byte[] {
1644
1645 (byte) 0x50, (byte) 0x4b, 3, 4,
1646
1647 10, 0,
1648
1649 0, 8,
1650
1651 0, 0 }, header, "LFH start");
1652
1653 a.skipBytes(4);
1654 rest = new byte[17];
1655 a.readFully(rest);
1656
1657 assertArrayEquals(new byte[] {
1658
1659 (byte) 0x9E, (byte) 0xCB, (byte) 0x79, (byte) 0x12,
1660
1661 (byte) 0x40, (byte) 0x42, (byte) 0x0F, 0,
1662
1663 (byte) 0x40, (byte) 0x42, (byte) 0x0F, 0,
1664
1665 1, 0,
1666
1667 (byte) (!hasExtra ? 0 : 20), 0,
1668
1669 (byte) '0' }, rest, "LFH rest");
1670 if (hasExtra) {
1671 final byte[] extra = new byte[20];
1672 a.readFully(extra);
1673 assertArrayEquals(new byte[] {
1674
1675 1, 0,
1676
1677 16, 0,
1678
1679 (byte) 0x40, (byte) 0x42, (byte) 0x0F, 0, 0, 0, 0, 0,
1680
1681 (byte) 0x40, (byte) 0x42, (byte) 0x0F, 0, 0, 0, 0, 0, }, extra, "ZIP64 extra field");
1682 }
1683 }
1684 };
1685 }
1686
1687
1688
1689
1690
1691
1692
1693
1694 private static ZipOutputTest writeSmallStoredEntryModeAlways(final boolean knownSize) {
1695 return (f, zos) -> {
1696 zos.setUseZip64(Zip64Mode.Always);
1697 final byte[] buf = new byte[ONE_MILLION];
1698 final ZipArchiveEntry zae = new ZipArchiveEntry("0");
1699 if (knownSize) {
1700 zae.setSize(ONE_MILLION);
1701 zae.setCrc(0x1279CB9EL);
1702 }
1703 zae.setMethod(ZipEntry.STORED);
1704 zos.putArchiveEntry(zae);
1705 zos.write(buf);
1706 zos.closeArchiveEntry();
1707 zos.close();
1708
1709 try (RandomAccessFile a = RandomAccessFileMode.READ_ONLY.create(f)) {
1710 getLengthAndPositionAtCentralDirectory(a);
1711
1712
1713
1714 byte[] header = new byte[12];
1715 a.readFully(header);
1716 assertArrayEquals(new byte[] {
1717
1718 (byte) 0x50, (byte) 0x4b, 1, 2,
1719
1720 45, 0,
1721
1722 45, 0,
1723
1724 0, 8,
1725
1726 0, 0 }, header, "CDH start");
1727
1728 a.skipBytes(4);
1729 byte[] rest = new byte[31];
1730 a.readFully(rest);
1731
1732 assertArrayEquals(new byte[] {
1733
1734 (byte) 0x9E, (byte) 0xCB, (byte) 0x79, (byte) 0x12,
1735
1736 (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1737
1738 (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1739
1740 1, 0,
1741
1742 32, 0,
1743
1744 0, 0,
1745
1746 0, 0,
1747
1748 0, 0, 0, 0, 0, 0,
1749
1750 (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1751
1752 (byte) '0' }, rest, "CDH rest");
1753
1754 byte[] extra = new byte[28];
1755 a.readFully(extra);
1756 assertArrayEquals(new byte[] {
1757
1758 1, 0,
1759
1760 28, 0,
1761
1762 (byte) 0x40, (byte) 0x42, (byte) 0x0F, 0, 0, 0, 0, 0,
1763
1764 (byte) 0x40, (byte) 0x42, (byte) 0x0F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, extra, "CDH extra");
1765
1766
1767
1768
1769 a.seek(0);
1770 header = new byte[10];
1771 a.readFully(header);
1772 assertArrayEquals(new byte[] {
1773
1774 (byte) 0x50, (byte) 0x4b, 3, 4,
1775
1776 45, 0,
1777
1778 0, 8,
1779
1780 0, 0 }, header, "LFH start");
1781
1782 a.skipBytes(4);
1783 rest = new byte[17];
1784 a.readFully(rest);
1785
1786 assertArrayEquals(new byte[] {
1787
1788 (byte) 0x9E, (byte) 0xCB, (byte) 0x79, (byte) 0x12,
1789
1790 (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1791
1792 (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
1793
1794 1, 0,
1795
1796 20, 0,
1797
1798 (byte) '0' }, rest, "LFH rest");
1799
1800 extra = new byte[20];
1801 a.readFully(extra);
1802 assertArrayEquals(new byte[] {
1803
1804 1, 0,
1805
1806 16, 0,
1807
1808 (byte) 0x40, (byte) 0x42, (byte) 0x0F, 0, 0, 0, 0, 0,
1809
1810 (byte) 0x40, (byte) 0x42, (byte) 0x0F, 0, 0, 0, 0, 0, }, extra, "LFH extra");
1811 }
1812 };
1813 }
1814
1815 private File buildZipWithZip64Mode(final String fileName, final Zip64Mode zip64Mode, final File inputFile) throws Throwable {
1816 final File outputFile = getTempFile(fileName);
1817 outputFile.createNewFile();
1818
1819 try (ZipArchiveOutputStream outputStream = new ZipArchiveOutputStream(new BufferedOutputStream(new FileOutputStream(outputFile)))) {
1820 outputStream.setUseZip64(zip64Mode);
1821 outputStream.setCreateUnicodeExtraFields(ZipArchiveOutputStream.UnicodeExtraFieldPolicy.ALWAYS);
1822 outputStream.putArchiveEntry(new ZipArchiveEntry("input.bin"));
1823 outputStream.write(inputFile);
1824 outputStream.closeArchiveEntry();
1825 }
1826 return outputFile;
1827 }
1828
1829 @Test
1830 void testRead100KFilesGeneratedBy7ZIPUsingInputStream() throws Throwable {
1831 read100KFilesImpl(get100KFileFileGeneratedBy7ZIP());
1832 }
1833
1834 @Test
1835 void testRead100KFilesGeneratedBy7ZIPUsingZipFile() throws Throwable {
1836 read100KFilesUsingZipFileImpl(get100KFileFileGeneratedBy7ZIP());
1837 }
1838
1839 @Test
1840 void testRead100KFilesGeneratedByJava7JarUsingInputStream() throws Throwable {
1841 read100KFilesImpl(get100KFileFileGeneratedByJava7Jar());
1842 }
1843
1844 @Test
1845 void testRead100KFilesGeneratedByJava7JarUsingZipFile() throws Throwable {
1846 read100KFilesUsingZipFileImpl(get100KFileFileGeneratedByJava7Jar());
1847 }
1848
1849 @Test
1850 void testRead100KFilesGeneratedByPKZipUsingInputStream() throws Throwable {
1851 read100KFilesImpl(get100KFileFileGeneratedByPKZip());
1852 }
1853
1854 @Test
1855 void testRead100KFilesGeneratedByPKZipUsingZipFile() throws Throwable {
1856 read100KFilesUsingZipFileImpl(get100KFileFileGeneratedByPKZip());
1857 }
1858
1859 @Test
1860 void testRead100KFilesGeneratedByWinCFUsingInputStream() throws Throwable {
1861 read100KFilesImpl(get100KFileFileGeneratedByWinCF());
1862 }
1863
1864 @Test
1865 void testRead100KFilesGeneratedByWinCFUsingZipFile() throws Throwable {
1866 read100KFilesUsingZipFileImpl(get100KFileFileGeneratedByWinCF());
1867 }
1868
1869 @Test
1870 void testRead100KFilesGeneratedByWinZIPUsingInputStream() throws Throwable {
1871 read100KFilesImpl(get100KFileFileGeneratedByWinZIP());
1872 }
1873
1874 @Test
1875 void testRead100KFilesGeneratedByWinZIPUsingZipFile() throws Throwable {
1876 read100KFilesUsingZipFileImpl(get100KFileFileGeneratedByWinZIP());
1877 }
1878
1879 @Test
1880 void testRead100KFilesUsingInputStream() throws Throwable {
1881 read100KFilesImpl(get100KFileFile());
1882 }
1883
1884 @Test
1885 void testRead100KFilesUsingZipFile() throws Throwable {
1886 read100KFilesUsingZipFileImpl(get100KFileFile());
1887 }
1888
1889 @Test
1890 void testRead3EntriesCreatingBigArchiveFileUsingZipFile() throws Throwable {
1891 withTemporaryArchive("read3EntriesCreatingBigArchiveFileUsingZipFile", (f, zos) -> {
1892 write3EntriesCreatingBigArchiveToStream(zos);
1893 ZipFile zf = null;
1894 try {
1895 zf = ZipFile.builder().setFile(f).get();
1896 int idx = 0;
1897 for (final Enumeration<ZipArchiveEntry> e = zf.getEntriesInPhysicalOrder(); e.hasMoreElements();) {
1898 final ZipArchiveEntry zae = e.nextElement();
1899 assertEquals(String.valueOf(idx), zae.getName());
1900 if (idx++ < 2) {
1901 assertEquals(FIVE_BILLION / 2, zae.getSize());
1902 } else {
1903 assertEquals(1, zae.getSize());
1904 try (InputStream i = zf.getInputStream(zae)) {
1905 assertNotNull(i);
1906 assertEquals(42, i.read());
1907 }
1908 }
1909 }
1910 } finally {
1911 ZipFile.closeQuietly(zf);
1912 }
1913 }, true);
1914 }
1915
1916 @Test
1917 void testRead5GBOfZerosGeneratedBy7ZIPUsingInputStream() throws Throwable {
1918 read5GBOfZerosImpl(get5GBZerosFileGeneratedBy7ZIP(), "5GB_of_Zeros");
1919 }
1920
1921 @Test
1922 void testRead5GBOfZerosGeneratedBy7ZIPUsingZipFile() throws Throwable {
1923 read5GBOfZerosUsingZipFileImpl(get5GBZerosFileGeneratedBy7ZIP(), "5GB_of_Zeros");
1924 }
1925
1926 @Test
1927 void testRead5GBOfZerosGeneratedByJava7JarUsingInputStream() throws Throwable {
1928 read5GBOfZerosImpl(get5GBZerosFileGeneratedByJava7Jar(), "5GB_of_Zeros");
1929 }
1930
1931 @Test
1932 void testRead5GBOfZerosGeneratedByJava7JarUsingZipFile() throws Throwable {
1933 read5GBOfZerosUsingZipFileImpl(get5GBZerosFileGeneratedByJava7Jar(), "5GB_of_Zeros");
1934 }
1935
1936 @Test
1937 void testRead5GBOfZerosGeneratedByPKZipUsingInputStream() throws Throwable {
1938 read5GBOfZerosImpl(get5GBZerosFileGeneratedByPKZip(), "zip6/5GB_of_Zeros");
1939 }
1940
1941 @Test
1942 void testRead5GBOfZerosGeneratedByPKZipUsingZipFile() throws Throwable {
1943 read5GBOfZerosUsingZipFileImpl(get5GBZerosFileGeneratedByPKZip(), "zip6/5GB_of_Zeros");
1944 }
1945
1946 @Test
1947 void testRead5GBOfZerosGeneratedByWinZIPUsingInputStream() throws Throwable {
1948 read5GBOfZerosImpl(get5GBZerosFileGeneratedByWinZIP(), "5GB_of_Zeros");
1949 }
1950
1951 @Test
1952 void testRead5GBOfZerosGeneratedByWinZIPUsingZipFile() throws Throwable {
1953 read5GBOfZerosUsingZipFileImpl(get5GBZerosFileGeneratedByWinZIP(), "5GB_of_Zeros");
1954 }
1955
1956 @Test
1957 void testRead5GBOfZerosUsingInputStream() throws Throwable {
1958 read5GBOfZerosImpl(get5GBZerosFile(), "5GB_of_Zeros");
1959 }
1960
1961 @Test
1962 void testRead5GBOfZerosUsingZipFile() throws Throwable {
1963 read5GBOfZerosUsingZipFileImpl(get5GBZerosFile(), "5GB_of_Zeros");
1964 }
1965
1966 @Test
1967 void testReadSelfGenerated100KFilesUsingZipFile() throws Throwable {
1968 withTemporaryArchive("readSelfGenerated100KFilesUsingZipFile()", (f, zos) -> {
1969 write100KFilesToStream(zos);
1970 read100KFilesUsingZipFileImpl(f);
1971 }, true);
1972 }
1973
1974 @Test
1975 void testWrite100KFilesFile() throws Throwable {
1976 withTemporaryArchive("write100KFilesFile", write100KFiles(), true);
1977 }
1978
1979 @Test
1980 void testWrite100KFilesFileModeAlways() throws Throwable {
1981 withTemporaryArchive("write100KFilesFileModeAlways", write100KFiles(Zip64Mode.Always), true);
1982 }
1983
1984 @Test
1985 void testWrite100KFilesFileModeNever() throws Throwable {
1986 withTemporaryArchive("write100KFilesFileModeNever", write100KFilesModeNever, true);
1987 }
1988
1989 @Test
1990 void testWrite100KFilesStream() throws Throwable {
1991 withTemporaryArchive("write100KFilesStream", write100KFiles(), false);
1992 }
1993
1994 @Test
1995 void testWrite100KFilesStreamModeAlways() throws Throwable {
1996 withTemporaryArchive("write100KFilesStreamModeAlways", write100KFiles(Zip64Mode.Always), false);
1997 }
1998
1999 @Test
2000 void testWrite100KFilesStreamModeNever() throws Throwable {
2001 withTemporaryArchive("write100KFilesStreamModeNever", write100KFilesModeNever, false);
2002 }
2003
2004 @Test
2005 void testWrite3EntriesCreatingBigArchiveFile() throws Throwable {
2006 withTemporaryArchive("write3EntriesCreatingBigArchiveFile", write3EntriesCreatingBigArchive(), true);
2007 }
2008
2009 @Test
2010 void testWrite3EntriesCreatingBigArchiveFileModeAlways() throws Throwable {
2011 withTemporaryArchive("write3EntriesCreatingBigArchiveFileModeAlways", write3EntriesCreatingBigArchive(Zip64Mode.Always), true);
2012 }
2013
2014 @Test
2015 void testWrite3EntriesCreatingBigArchiveFileModeNever() throws Throwable {
2016 withTemporaryArchive("write3EntriesCreatingBigArchiveFileModeNever", write3EntriesCreatingBigArchiveModeNever, true);
2017 }
2018
2019 @Test
2020 void testWrite3EntriesCreatingBigArchiveStream() throws Throwable {
2021 withTemporaryArchive("write3EntriesCreatingBigArchiveStream", write3EntriesCreatingBigArchive(), false);
2022 }
2023
2024 @Test
2025 void testWrite3EntriesCreatingBigArchiveStreamModeAlways() throws Throwable {
2026 withTemporaryArchive("write3EntriesCreatingBigArchiveStreamModeAlways", write3EntriesCreatingBigArchive(Zip64Mode.Always), false);
2027 }
2028
2029 @Test
2030 void testWrite3EntriesCreatingBigArchiveStreamModeNever() throws Throwable {
2031 withTemporaryArchive("write3EntriesCreatingBigArchiveStreamModeNever", write3EntriesCreatingBigArchiveModeNever, false);
2032 }
2033
2034 @Test
2035 void testWrite3EntriesCreatingManySplitArchiveFileModeAlways() throws Throwable {
2036
2037 withTemporaryArchive("write3EntriesCreatingManySplitArchiveFileModeAlways", write3EntriesCreatingBigArchive(Zip64Mode.Always, true), true, 65536L);
2038 }
2039
2040 @Test
2041 void testWrite3EntriesCreatingManySplitArchiveFileModeNever() throws Throwable {
2042 withTemporaryArchive("write3EntriesCreatingManySplitArchiveFileModeNever", write3EntriesCreatingBigArchiveModeNever, true, 65536L);
2043 }
2044
2045 @Test
2046 void testWriteAndRead5GBOfZerosUsingZipFile() throws Throwable {
2047 File f = null;
2048 try {
2049 f = write5GBZerosFile("writeAndRead5GBOfZerosUsingZipFile");
2050 read5GBOfZerosUsingZipFileImpl(f, "5GB_of_Zeros");
2051 } finally {
2052 AbstractTest.forceDelete(f);
2053 }
2054 }
2055
2056 @Test
2057 void testWriteBigDeflatedEntryKnownSizeToFile() throws Throwable {
2058 withTemporaryArchive("writeBigDeflatedEntryKnownSizeToFile", writeBigDeflatedEntryToFile(true), true);
2059 }
2060
2061 @Test
2062 void testWriteBigDeflatedEntryKnownSizeToFileModeAlways() throws Throwable {
2063 withTemporaryArchive("writeBigDeflatedEntryKnownSizeToFileModeAlways", writeBigDeflatedEntryToFile(true, Zip64Mode.Always), true);
2064 }
2065
2066 @Test
2067 void testWriteBigDeflatedEntryKnownSizeToFileModeNever() throws Throwable {
2068 withTemporaryArchive("writeBigDeflatedEntryKnownSizeToFileModeNever", writeBigDeflatedEntryToFileModeNever(true), true);
2069 }
2070
2071 @Test
2072 void testWriteBigDeflatedEntryKnownSizeToStream() throws Throwable {
2073 withTemporaryArchive("writeBigDeflatedEntryKnownSizeToStream", writeBigDeflatedEntryToStream(true, Zip64Mode.AsNeeded), false);
2074 }
2075
2076 @Test
2077 void testWriteBigDeflatedEntryKnownSizeToStreamModeAlways() throws Throwable {
2078 withTemporaryArchive("writeBigDeflatedEntryKnownSizeToStreamModeAlways", writeBigDeflatedEntryToStream(true, Zip64Mode.Always), false);
2079 }
2080
2081 @Test
2082 void testWriteBigDeflatedEntryKnownSizeToStreamModeNever() throws Throwable {
2083 withTemporaryArchive("writeBigDeflatedEntryKnownSizeToStreamModeNever", (f, zos) -> {
2084 zos.setUseZip64(Zip64Mode.Never);
2085 final Zip64RequiredException ex = assertThrows(Zip64RequiredException.class, () -> {
2086 final ZipArchiveEntry zae = new ZipArchiveEntry("0");
2087 zae.setSize(FIVE_BILLION);
2088 zae.setMethod(ZipEntry.DEFLATED);
2089 zos.putArchiveEntry(zae);
2090 }, "expected a Zip64RequiredException");
2091 assertTrue(ex.getMessage().startsWith("0's size"));
2092 }, false);
2093 }
2094
2095 @Test
2096 void testWriteBigDeflatedEntryUnknownSizeToFile() throws Throwable {
2097 withTemporaryArchive("writeBigDeflatedEntryUnknownSizeToFile", writeBigDeflatedEntryToFile(false), true);
2098 }
2099
2100 @Test
2101 void testWriteBigDeflatedEntryUnknownSizeToFileModeAlways() throws Throwable {
2102 withTemporaryArchive("writeBigDeflatedEntryUnknownSizeToFileModeAlways", writeBigDeflatedEntryToFile(false, Zip64Mode.Always), true);
2103 }
2104
2105 @Test
2106 void testWriteBigDeflatedEntryUnknownSizeToFileModeNever() throws Throwable {
2107 withTemporaryArchive("writeBigDeflatedEntryUnknownSizeToFileModeNever", writeBigDeflatedEntryToFileModeNever(false), true);
2108 }
2109
2110 @Test
2111 void testWriteBigDeflatedEntryUnknownSizeToStream() throws Throwable {
2112 withTemporaryArchive("writeBigDeflatedEntryUnknownSizeToStream", writeBigDeflatedEntryUnknownSizeToStream(Zip64Mode.AsNeeded), false);
2113 }
2114
2115 @Test
2116 void testWriteBigDeflatedEntryUnknownSizeToStreamModeAlways() throws Throwable {
2117 withTemporaryArchive("writeBigDeflatedEntryUnknownSizeToStreamModeAlways", writeBigDeflatedEntryToStream(false, Zip64Mode.Always), false);
2118 }
2119
2120 @Test
2121 void testWriteBigDeflatedEntryUnknownSizeToStreamModeNever() throws Throwable {
2122 withTemporaryArchive("writeBigDeflatedEntryUnknownSizeToStreamModeNever", writeBigDeflatedEntryUnknownSizeToStream(Zip64Mode.Never), false);
2123 }
2124
2125 @Test
2126 void testWriteBigStoredEntryKnownSizeToFile() throws Throwable {
2127 withTemporaryArchive("writeBigStoredEntryKnownSizeToFile", writeBigStoredEntry(true), true);
2128 }
2129
2130 @Test
2131 void testWriteBigStoredEntryKnownSizeToFileModeAlways() throws Throwable {
2132 withTemporaryArchive("writeBigStoredEntryKnownSizeToFileModeAlways", writeBigStoredEntry(true, Zip64Mode.Always), true);
2133 }
2134
2135 @Test
2136 void testWriteBigStoredEntryKnownSizeToFileModeNever() throws Throwable {
2137 withTemporaryArchive("writeBigStoredEntryKnownSizeToFileModeNever", writeBigStoredEntryModeNever(true), true);
2138 }
2139
2140
2141
2142
2143 @Test
2144 void testWriteBigStoredEntryToStream() throws Throwable {
2145 withTemporaryArchive("writeBigStoredEntryToStream", writeBigStoredEntry(true), false);
2146 }
2147
2148 @Test
2149 void testWriteBigStoredEntryToStreamModeAlways() throws Throwable {
2150 withTemporaryArchive("writeBigStoredEntryToStreamModeAlways", writeBigStoredEntry(true, Zip64Mode.Always), false);
2151 }
2152
2153 @Test
2154 void testWriteBigStoredEntryToStreamModeNever() throws Throwable {
2155 withTemporaryArchive("writeBigStoredEntryToStreamModeNever", writeBigStoredEntryModeNever(true), false);
2156 }
2157
2158 @Test
2159 void testWriteBigStoredEntryUnknownSizeToFile() throws Throwable {
2160 withTemporaryArchive("writeBigStoredEntryUnknownSizeToFile", writeBigStoredEntry(false), true);
2161 }
2162
2163 @Test
2164 void testWriteBigStoredEntryUnknownSizeToFileModeAlways() throws Throwable {
2165 withTemporaryArchive("writeBigStoredEntryUnknownSizeToFileModeAlways", writeBigStoredEntry(false, Zip64Mode.Always), true);
2166 }
2167
2168 @Test
2169 void testWriteBigStoredEntryUnknownSizeToFileModeNever() throws Throwable {
2170 withTemporaryArchive("writeBigStoredEntryUnknownSizeToFileModeNever", writeBigStoredEntryModeNever(false), true);
2171 }
2172
2173 @Test
2174 void testWriteSmallDeflatedEntryKnownSizeToFile() throws Throwable {
2175 withTemporaryArchive("writeSmallDeflatedEntryKnownSizeToFile", writeSmallDeflatedEntryToFile(true), true);
2176 }
2177
2178 @Test
2179 void testWriteSmallDeflatedEntryKnownSizeToFileModeAlways() throws Throwable {
2180 withTemporaryArchive("writeSmallDeflatedEntryKnownSizeToFileModeAlways", writeSmallDeflatedEntryToFileModeAlways(true), true);
2181 }
2182
2183 @Test
2184 void testWriteSmallDeflatedEntryKnownSizeToFileModeNever() throws Throwable {
2185 withTemporaryArchive("writeSmallDeflatedEntryKnownSizeToFileModeNever", writeSmallDeflatedEntryToFile(true, Zip64Mode.Never), true);
2186 }
2187
2188 @Test
2189 void testWriteSmallDeflatedEntryKnownSizeToStream() throws Throwable {
2190 withTemporaryArchive("writeSmallDeflatedEntryKnownSizeToStream", writeSmallDeflatedEntryToStream(true, Zip64Mode.AsNeeded), false);
2191 }
2192
2193 @Test
2194 void testWriteSmallDeflatedEntryKnownSizeToStreamModeAlways() throws Throwable {
2195 withTemporaryArchive("writeSmallDeflatedEntryKnownSizeToStreamModeAlways", writeSmallDeflatedEntryToStreamModeAlways(true), false);
2196 }
2197
2198 @Test
2199 void testWriteSmallDeflatedEntryKnownSizeToStreamModeNever() throws Throwable {
2200 withTemporaryArchive("writeSmallDeflatedEntryKnownSizeToStreamModeNever", writeSmallDeflatedEntryToStream(true, Zip64Mode.Never), false);
2201 }
2202
2203 @Test
2204 void testWriteSmallDeflatedEntryUnknownSizeToFile() throws Throwable {
2205 withTemporaryArchive("writeSmallDeflatedEntryUnknownSizeToFile", writeSmallDeflatedEntryToFile(false), true);
2206 }
2207
2208 @Test
2209 void testWriteSmallDeflatedEntryUnknownSizeToFileModeAlways() throws Throwable {
2210 withTemporaryArchive("writeSmallDeflatedEntryUnknownSizeToFileModeAlways", writeSmallDeflatedEntryToFileModeAlways(false), true);
2211 }
2212
2213 @Test
2214 void testWriteSmallDeflatedEntryUnknownSizeToFileModeNever() throws Throwable {
2215 withTemporaryArchive("writeSmallDeflatedEntryUnknownSizeToFileModeNever", writeSmallDeflatedEntryToFile(false, Zip64Mode.Never), true);
2216 }
2217
2218 @Test
2219 void testWriteSmallDeflatedEntryUnknownSizeToStream() throws Throwable {
2220 withTemporaryArchive("writeSmallDeflatedEntryUnknownSizeToStream", writeSmallDeflatedEntryToStream(false, Zip64Mode.AsNeeded), false);
2221 }
2222
2223 @Test
2224 void testWriteSmallDeflatedEntryUnknownSizeToStreamModeAlways() throws Throwable {
2225 withTemporaryArchive("writeSmallDeflatedEntryUnknownSizeToStreamModeAlways", writeSmallDeflatedEntryToStreamModeAlways(false), false);
2226 }
2227
2228 @Test
2229 void testWriteSmallDeflatedEntryUnknownSizeToStreamModeNever() throws Throwable {
2230 withTemporaryArchive("writeSmallDeflatedEntryUnknownSizeToStreamModeNever", writeSmallDeflatedEntryToStream(false, Zip64Mode.Never), false);
2231 }
2232
2233 @Test
2234 void testWriteSmallStoredEntryKnownSizeToFile() throws Throwable {
2235 withTemporaryArchive("writeSmallStoredEntryKnownSizeToFile", writeSmallStoredEntry(true), true);
2236 }
2237
2238 @Test
2239 void testWriteSmallStoredEntryKnownSizeToFileModeAlways() throws Throwable {
2240 withTemporaryArchive("writeSmallStoredEntryKnownSizeToFileModeAlways", writeSmallStoredEntryModeAlways(true), true);
2241 }
2242
2243 @Test
2244 void testWriteSmallStoredEntryKnownSizeToFileModeNever() throws Throwable {
2245 withTemporaryArchive("writeSmallStoredEntryKnownSizeToFileModeNever", writeSmallStoredEntry(true, Zip64Mode.Never), true);
2246 }
2247
2248 @Test
2249 void testWriteSmallStoredEntryToStream() throws Throwable {
2250 withTemporaryArchive("writeSmallStoredEntryToStream", writeSmallStoredEntry(true), false);
2251 }
2252
2253 @Test
2254 void testWriteSmallStoredEntryToStreamModeAlways() throws Throwable {
2255 withTemporaryArchive("writeSmallStoredEntryToStreamModeAlways", writeSmallStoredEntryModeAlways(true), false);
2256 }
2257
2258 @Test
2259 void testWriteSmallStoredEntryToStreamModeNever() throws Throwable {
2260 withTemporaryArchive("writeSmallStoredEntryToStreamModeNever", writeSmallStoredEntry(true, Zip64Mode.Never), false);
2261 }
2262
2263 @Test
2264 void testWriteSmallStoredEntryUnknownSizeToFile() throws Throwable {
2265 withTemporaryArchive("writeSmallStoredEntryUnknownSizeToFile", writeSmallStoredEntry(false), true);
2266 }
2267
2268 @Test
2269 void testWriteSmallStoredEntryUnknownSizeToFileModeAlways() throws Throwable {
2270 withTemporaryArchive("writeSmallStoredEntryUnknownSizeToFileModeAlways", writeSmallStoredEntryModeAlways(false), true);
2271 }
2272
2273 @Test
2274 void testWriteSmallStoredEntryUnknownSizeToFileModeNever() throws Throwable {
2275 withTemporaryArchive("writeSmallStoredEntryUnknownSizeToFileModeNever", writeSmallStoredEntry(false, Zip64Mode.Never), true);
2276 }
2277
2278 @Test
2279 void testZip64ModeAlwaysWithCompatibility() throws Throwable {
2280 final File inputFile = getFile("test3.xml");
2281
2282
2283
2284 final File zipUsingModeAlwaysWithCompatibility = buildZipWithZip64Mode("testZip64ModeAlwaysWithCompatibility-output-1",
2285 Zip64Mode.AlwaysWithCompatibility, inputFile);
2286 final ZipFile zipFileWithAlwaysWithCompatibility = ZipFile.builder().setFile(zipUsingModeAlwaysWithCompatibility).get();
2287 ZipArchiveEntry entry = zipFileWithAlwaysWithCompatibility.getEntries().nextElement();
2288 for (final ZipExtraField extraField : entry.getExtraFields()) {
2289 if (!(extraField instanceof Zip64ExtendedInformationExtraField)) {
2290 continue;
2291 }
2292
2293 assertNull(((Zip64ExtendedInformationExtraField) extraField).getRelativeHeaderOffset());
2294 assertNull(((Zip64ExtendedInformationExtraField) extraField).getDiskStartNumber());
2295 }
2296
2297
2298
2299 final File zipUsingModeAlways = buildZipWithZip64Mode("testZip64ModeAlwaysWithCompatibility-output-2", Zip64Mode.Always, inputFile);
2300 final ZipFile zipFileWithAlways = ZipFile.builder().setFile(zipUsingModeAlways).get();
2301 entry = zipFileWithAlways.getEntries().nextElement();
2302 for (final ZipExtraField extraField : entry.getExtraFields()) {
2303 if (!(extraField instanceof Zip64ExtendedInformationExtraField)) {
2304 continue;
2305 }
2306
2307 assertNotNull(((Zip64ExtendedInformationExtraField) extraField).getRelativeHeaderOffset());
2308 assertNotNull(((Zip64ExtendedInformationExtraField) extraField).getDiskStartNumber());
2309 }
2310 }
2311 }