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