16bd77683de703a6df640e863b38a73041e8c0c1bElliott Hughes/*
26bd77683de703a6df640e863b38a73041e8c0c1bElliott Hughes * Copyright (C) 2010 The Android Open Source Project
3f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes *
46bd77683de703a6df640e863b38a73041e8c0c1bElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
56bd77683de703a6df640e863b38a73041e8c0c1bElliott Hughes * you may not use this file except in compliance with the License.
66bd77683de703a6df640e863b38a73041e8c0c1bElliott Hughes * You may obtain a copy of the License at
7f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes *
86bd77683de703a6df640e863b38a73041e8c0c1bElliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
9f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes *
106bd77683de703a6df640e863b38a73041e8c0c1bElliott Hughes * Unless required by applicable law or agreed to in writing, software
116bd77683de703a6df640e863b38a73041e8c0c1bElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
126bd77683de703a6df640e863b38a73041e8c0c1bElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136bd77683de703a6df640e863b38a73041e8c0c1bElliott Hughes * See the License for the specific language governing permissions and
146bd77683de703a6df640e863b38a73041e8c0c1bElliott Hughes * limitations under the License.
156bd77683de703a6df640e863b38a73041e8c0c1bElliott Hughes */
166bd77683de703a6df640e863b38a73041e8c0c1bElliott Hughes
174557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonpackage libcore.java.util.zip;
186bd77683de703a6df640e863b38a73041e8c0c1bElliott Hughes
19406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughesimport java.io.BufferedOutputStream;
206bd77683de703a6df640e863b38a73041e8c0c1bElliott Hughesimport java.io.File;
216bd77683de703a6df640e863b38a73041e8c0c1bElliott Hughesimport java.io.FileInputStream;
226bd77683de703a6df640e863b38a73041e8c0c1bElliott Hughesimport java.io.FileOutputStream;
23406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughesimport java.io.IOException;
24fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Changimport java.time.LocalDate;
25fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Changimport java.time.ZoneId;
26fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Changimport java.time.temporal.ChronoUnit;
27f2cfb1223a3a2f682d657d97cdb0cd9108c5c30cvichangimport java.util.ArrayList;
286bd77683de703a6df640e863b38a73041e8c0c1bElliott Hughesimport java.util.Arrays;
296bd77683de703a6df640e863b38a73041e8c0c1bElliott Hughesimport java.util.List;
30355a98498e4bc434dde8809eacf6e150f9b25f89Jesse Wilsonimport java.util.jar.JarEntry;
314557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport java.util.zip.ZipEntry;
324557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport java.util.zip.ZipFile;
334557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport java.util.zip.ZipInputStream;
344557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport java.util.zip.ZipOutputStream;
356bd77683de703a6df640e863b38a73041e8c0c1bElliott Hughes
366bd77683de703a6df640e863b38a73041e8c0c1bElliott Hughespublic class ZipEntryTest extends junit.framework.TestCase {
37fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang  // The zip format differentiates between times before and after 1/1/1980. A timestamp before 1980
38fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang  // will produce a different zip binary. ZipOutputStream.putNextEntry defaults the entry times to
39fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang  // the current system clock value. This time can be used explicitly to ensure the behavior of most
40fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang  // tests is independent of the system clock.
41fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang  private static final long ENTRY_TIME = 1262304000000L; //  January 1, 2010 12:00:00 AM GMT
42fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang
43406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes  private static ZipOutputStream createZipOutputStream(File f) throws IOException {
44406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    return new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(f)));
45406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes  }
46406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes
47406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes  private static String makeString(int count, String s) {
48406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    StringBuilder sb = new StringBuilder();
49406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    for (int i = 0; i < count; ++i) {
50406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes      sb.append(s);
51406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    }
52406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    return sb.toString();
53406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes  }
54406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes
55f2cfb1223a3a2f682d657d97cdb0cd9108c5c30cvichang  private List<File> temporaryFiles = new ArrayList<>();
56f2cfb1223a3a2f682d657d97cdb0cd9108c5c30cvichang
57f2cfb1223a3a2f682d657d97cdb0cd9108c5c30cvichang  private File createTemporaryZipFile() throws IOException {
58f2cfb1223a3a2f682d657d97cdb0cd9108c5c30cvichang    File result = File.createTempFile("ZipFileTest", "zip");
59f2cfb1223a3a2f682d657d97cdb0cd9108c5c30cvichang    temporaryFiles.add(result);
60f2cfb1223a3a2f682d657d97cdb0cd9108c5c30cvichang    return result;
61f2cfb1223a3a2f682d657d97cdb0cd9108c5c30cvichang  }
62f2cfb1223a3a2f682d657d97cdb0cd9108c5c30cvichang
63f2cfb1223a3a2f682d657d97cdb0cd9108c5c30cvichang  @Override
64f2cfb1223a3a2f682d657d97cdb0cd9108c5c30cvichang  public void tearDown() throws Exception {
65f2cfb1223a3a2f682d657d97cdb0cd9108c5c30cvichang    for (File file : temporaryFiles) {
66f2cfb1223a3a2f682d657d97cdb0cd9108c5c30cvichang      file.delete();
67f2cfb1223a3a2f682d657d97cdb0cd9108c5c30cvichang    }
68f2cfb1223a3a2f682d657d97cdb0cd9108c5c30cvichang    temporaryFiles.clear();
69f2cfb1223a3a2f682d657d97cdb0cd9108c5c30cvichang    super.tearDown();
70f2cfb1223a3a2f682d657d97cdb0cd9108c5c30cvichang  }
71f2cfb1223a3a2f682d657d97cdb0cd9108c5c30cvichang
72406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes  // http://code.google.com/p/android/issues/detail?id=4690
73406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes  public void test_utf8FileNames() throws Exception {
74406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    // Create a zip file containing non-ASCII filenames.
75406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    File f = File.createTempFile("your", "mum");
76406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    List<String> filenames = Arrays.asList("us-ascii",
77406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes                                           "\u043c\u0430\u0440\u0442\u0430", // russian
78406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes                                           "\u1f00\u03c0\u1f78", // greek
79406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes                                           "\u30b3\u30f3\u30cb\u30c1\u30cf"); // japanese
80406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    ZipOutputStream out = new ZipOutputStream(new FileOutputStream(f));
81406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    for (String filename : filenames) {
82406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes      out.putNextEntry(new ZipEntry(filename));
83406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes      out.closeEntry(); // Empty files are fine.
84406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    }
85406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    out.close();
86406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    // Read it back, and check we find all those names.
87406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    // This failed when we were mangling the encoding.
88406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    ZipFile zipFile = new ZipFile(f);
89406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    for (String filename : filenames) {
90406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes      assertNotNull(filename, zipFile.getEntry(filename));
91406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    }
92406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    // Check that ZipInputStream works too.
93406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    ZipInputStream in = new ZipInputStream(new FileInputStream(f));
94406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    ZipEntry entry;
95406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    int entryCount = 0;
96406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    while ((entry = in.getNextEntry()) != null) {
97406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes      assertTrue(entry.getName(), filenames.contains(entry.getName()));
98406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes      ++entryCount;
99406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    }
100406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    assertEquals(filenames.size(), entryCount);
101406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    in.close();
102406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes  }
103406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes
104406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes  // http://b/2099615
105406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes  public void testClone() {
106406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    byte[] extra = { 5, 7, 9 };
107406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    JarEntry jarEntry = new JarEntry("foo");
108406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    jarEntry.setExtra(extra);
109406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    assertSame("Expected no defensive copy of extra", extra, jarEntry.getExtra());
110406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes
111406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    ZipEntry clone = (ZipEntry) jarEntry.clone();
112406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    assertEquals(JarEntry.class, clone.getClass());
113406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    assertNotSame(extra, clone.getExtra());
114406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes  }
115406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes
116406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes  public void testTooLongName() throws Exception {
117406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    String tooLongName = makeString(65536, "z");
118406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    try {
119406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes      new ZipEntry(tooLongName);
120406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes      fail();
121406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    } catch (IllegalArgumentException expected) {
122406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    }
123406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes  }
124406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes
125406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes  public void testMaxLengthName() throws Exception {
126406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    String maxLengthName = makeString(65535, "z");
127406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes
128406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    File f = createTemporaryZipFile();
129406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    ZipOutputStream out = createZipOutputStream(f);
130406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    out.putNextEntry(new ZipEntry(maxLengthName));
131406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    out.closeEntry();
132406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    out.close();
133406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes
134406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    // Read it back, and check that we see the entry.
135406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    ZipFile zipFile = new ZipFile(f);
136406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    assertNotNull(zipFile.getEntry(maxLengthName));
137406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    zipFile.close();
138406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes  }
139406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes
140406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes  public void testTooLongExtra() throws Exception {
141406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    byte[] tooLongExtra = new byte[65536];
142406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    ZipEntry ze = new ZipEntry("x");
143406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    try {
144406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes      ze.setExtra(tooLongExtra);
145406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes      fail();
146406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    } catch (IllegalArgumentException expected) {
1476bd77683de703a6df640e863b38a73041e8c0c1bElliott Hughes    }
148406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes  }
149406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes
150406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes  public void testMaxLengthExtra() throws Exception {
151406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    byte[] maxLengthExtra = new byte[65535];
152355a98498e4bc434dde8809eacf6e150f9b25f89Jesse Wilson
153406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    File f = createTemporaryZipFile();
154406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    ZipOutputStream out = createZipOutputStream(f);
155406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    ZipEntry ze = new ZipEntry("x");
15612f5c69e074d6ef012706068416f0a61b70b4e52Narayan Kamath    ze.setSize(0);
157fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang    ze.setTime(ENTRY_TIME);
158406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    ze.setExtra(maxLengthExtra);
159406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    out.putNextEntry(ze);
160406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    out.closeEntry();
161406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    out.close();
162406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes
163406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    // Read it back, and check that we see the entry.
164406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    ZipFile zipFile = new ZipFile(f);
165406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    assertEquals(maxLengthExtra.length, zipFile.getEntry("x").getExtra().length);
166406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    zipFile.close();
167406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes  }
168406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes
169fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang  public void testSetTime() throws Exception {
170fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang    // Set a time before the lower bound of dos time, year 1980
171fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang    checkSetTime(0L); // January 1, 1970 12:00:00 AM GMT
172fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang    checkSetTime(31536000000L); // January 1, 1971 12:00:00 AM GMT
173fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang    checkSetTime(315187200000L); // December 28, 1979 12:00:00 AM GMT
174fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang    // December 31, 1979 11:59:59 AM Local time
175fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang    checkSetTime(LocalDate.of(1980, 1, 1).atStartOfDay().minus(1, ChronoUnit.SECONDS)
176fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang                    .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
177fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang
178fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang    // January 1, 1980 12:00:00 AM Local time
179fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang    checkSetTime(LocalDate.of(1980, 1, 1).atStartOfDay().atZone(ZoneId.systemDefault())
180fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang            .toInstant().toEpochMilli());
181fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang    // Set a time after the lower bound of dos time, year 1980
182fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang    checkSetTime(315705600000L); // January 3, 1980 12:00:00 AM GMT
183fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang    checkSetTime(ENTRY_TIME); // January 1, 2010 12:00:00 AM
184fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang
185fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang    // Set a time after upper bound of dos time.
186fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang    checkSetTime(4134153600000L); // January 3, 2101 12:00:00 AM GMT
187fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang  }
188fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang
189f2cfb1223a3a2f682d657d97cdb0cd9108c5c30cvichang  private void checkSetTime(long time) throws IOException {
190fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang    File f = createTemporaryZipFile();
191fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang    ZipOutputStream out = createZipOutputStream(f);
192fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang    ZipEntry ze = new ZipEntry("x");
193fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang    ze.setSize(0);
194fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang    ze.setTime(time);
195fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang    out.putNextEntry(ze);
196fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang    out.closeEntry();
197fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang    out.close();
198fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang
199fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang    // Read it back, and check that we see the entry.
200fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang    ZipFile zipFile = new ZipFile(f);
201fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang    assertEquals(time, zipFile.getEntry("x").getTime());
202fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang    zipFile.close();
203fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang  }
20412f5c69e074d6ef012706068416f0a61b70b4e52Narayan Kamath
2058456b1f15317e7fd59267ab8cafe0a78f1d5b1a0Shubham Ajmera  // TODO: This test does not compile because we need to add a ZipOutputStream constructor
2068456b1f15317e7fd59267ab8cafe0a78f1d5b1a0Shubham Ajmera  // that forces zip64. This also needs followup changes in ZipInputStream et al. to assume zip64
2078456b1f15317e7fd59267ab8cafe0a78f1d5b1a0Shubham Ajmera  // if the header says so, and to not depend purely on the entry length.
2088456b1f15317e7fd59267ab8cafe0a78f1d5b1a0Shubham Ajmera  //
2098456b1f15317e7fd59267ab8cafe0a78f1d5b1a0Shubham Ajmera  // public void testMaxLengthExtra_zip64() throws Exception {
2108456b1f15317e7fd59267ab8cafe0a78f1d5b1a0Shubham Ajmera  //   // Not quite the max length (65535), but large enough that there's no space
2118456b1f15317e7fd59267ab8cafe0a78f1d5b1a0Shubham Ajmera  //   // for the zip64 extended info header.
2128456b1f15317e7fd59267ab8cafe0a78f1d5b1a0Shubham Ajmera  //   byte[] maxLengthExtra = new byte[65530];
2138456b1f15317e7fd59267ab8cafe0a78f1d5b1a0Shubham Ajmera  //
2148456b1f15317e7fd59267ab8cafe0a78f1d5b1a0Shubham Ajmera  //   File f = createTemporaryZipFile();
2158456b1f15317e7fd59267ab8cafe0a78f1d5b1a0Shubham Ajmera  //   ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(f)),
2168456b1f15317e7fd59267ab8cafe0a78f1d5b1a0Shubham Ajmera  //           true /* forceZip64 */);
2178456b1f15317e7fd59267ab8cafe0a78f1d5b1a0Shubham Ajmera  //   ZipEntry ze = new ZipEntry("x");
2188456b1f15317e7fd59267ab8cafe0a78f1d5b1a0Shubham Ajmera  //
2198456b1f15317e7fd59267ab8cafe0a78f1d5b1a0Shubham Ajmera  //   ze.setExtra(maxLengthExtra);
2208456b1f15317e7fd59267ab8cafe0a78f1d5b1a0Shubham Ajmera  //   try {
2218456b1f15317e7fd59267ab8cafe0a78f1d5b1a0Shubham Ajmera  //     out.putNextEntry(ze);
2228456b1f15317e7fd59267ab8cafe0a78f1d5b1a0Shubham Ajmera  //     fail();
2238456b1f15317e7fd59267ab8cafe0a78f1d5b1a0Shubham Ajmera  //   } catch (ZipException expected) {
2248456b1f15317e7fd59267ab8cafe0a78f1d5b1a0Shubham Ajmera  //   }
2258456b1f15317e7fd59267ab8cafe0a78f1d5b1a0Shubham Ajmera  // }
22612f5c69e074d6ef012706068416f0a61b70b4e52Narayan Kamath
22712f5c69e074d6ef012706068416f0a61b70b4e52Narayan Kamath
228a812a87e69850d1492c45bd88d7ff3dbf21d5075Narayan Kamath  public void testTooLongComment() throws Exception {
229406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    String tooLongComment = makeString(65536, "z");
230406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    ZipEntry ze = new ZipEntry("x");
231406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    try {
232406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes      ze.setComment(tooLongComment);
233406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes      fail();
234406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    } catch (IllegalArgumentException expected) {
235355a98498e4bc434dde8809eacf6e150f9b25f89Jesse Wilson    }
236406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes  }
237406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes
238406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes  public void testMaxLengthComment() throws Exception {
239406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    String maxLengthComment = makeString(65535, "z");
240406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes
241406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    File f = createTemporaryZipFile();
242406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    ZipOutputStream out = createZipOutputStream(f);
243406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    ZipEntry ze = new ZipEntry("x");
244406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    ze.setComment(maxLengthComment);
245406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    out.putNextEntry(ze);
246406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    out.closeEntry();
247406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    out.close();
248406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes
249406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    // Read it back, and check that we see the entry.
250406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    ZipFile zipFile = new ZipFile(f);
251406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    assertEquals(maxLengthComment, zipFile.getEntry("x").getComment());
252406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes    zipFile.close();
253406b85296a7ba29d2f480280d2f2a96133f940ecElliott Hughes  }
254c242577b1569f97f806ef176e4549141df147b78Kenny Root
255c242577b1569f97f806ef176e4549141df147b78Kenny Root  public void testCommentAndExtraInSameOrder() throws Exception {
256c242577b1569f97f806ef176e4549141df147b78Kenny Root    String comment = makeString(17, "z");
257c242577b1569f97f806ef176e4549141df147b78Kenny Root    byte[] extra = makeString(11, "a").getBytes();
258c242577b1569f97f806ef176e4549141df147b78Kenny Root
259c242577b1569f97f806ef176e4549141df147b78Kenny Root    File f = createTemporaryZipFile();
260c242577b1569f97f806ef176e4549141df147b78Kenny Root    ZipOutputStream out = createZipOutputStream(f);
26112f5c69e074d6ef012706068416f0a61b70b4e52Narayan Kamath
26212f5c69e074d6ef012706068416f0a61b70b4e52Narayan Kamath    // Regular (non zip64) format.
263c242577b1569f97f806ef176e4549141df147b78Kenny Root    ZipEntry ze = new ZipEntry("x");
26412f5c69e074d6ef012706068416f0a61b70b4e52Narayan Kamath    ze.setSize(0);
265fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang    ze.setTime(ENTRY_TIME);
26612f5c69e074d6ef012706068416f0a61b70b4e52Narayan Kamath    ze.setExtra(extra);
26712f5c69e074d6ef012706068416f0a61b70b4e52Narayan Kamath    ze.setComment(comment);
26812f5c69e074d6ef012706068416f0a61b70b4e52Narayan Kamath    out.putNextEntry(ze);
26912f5c69e074d6ef012706068416f0a61b70b4e52Narayan Kamath    out.closeEntry();
27012f5c69e074d6ef012706068416f0a61b70b4e52Narayan Kamath
27112f5c69e074d6ef012706068416f0a61b70b4e52Narayan Kamath    // An entry without a length is assumed to be zip64.
27212f5c69e074d6ef012706068416f0a61b70b4e52Narayan Kamath    ze = new ZipEntry("y");
273fac06a434f4498173f0d2ed675eae7285ec3ef18Victor Chang    ze.setTime(ENTRY_TIME);
274c242577b1569f97f806ef176e4549141df147b78Kenny Root    ze.setExtra(extra);
275c242577b1569f97f806ef176e4549141df147b78Kenny Root    ze.setComment(comment);
276c242577b1569f97f806ef176e4549141df147b78Kenny Root    out.putNextEntry(ze);
277c242577b1569f97f806ef176e4549141df147b78Kenny Root    out.closeEntry();
278c242577b1569f97f806ef176e4549141df147b78Kenny Root    out.close();
279c242577b1569f97f806ef176e4549141df147b78Kenny Root
280c242577b1569f97f806ef176e4549141df147b78Kenny Root    // Read it back and make sure comments and extra are in the right order
281c242577b1569f97f806ef176e4549141df147b78Kenny Root    ZipFile zipFile = new ZipFile(f);
282c242577b1569f97f806ef176e4549141df147b78Kenny Root    try {
283c242577b1569f97f806ef176e4549141df147b78Kenny Root      assertEquals(comment, zipFile.getEntry("x").getComment());
284c242577b1569f97f806ef176e4549141df147b78Kenny Root      assertTrue(Arrays.equals(extra, zipFile.getEntry("x").getExtra()));
28512f5c69e074d6ef012706068416f0a61b70b4e52Narayan Kamath
28612f5c69e074d6ef012706068416f0a61b70b4e52Narayan Kamath      assertEquals(comment, zipFile.getEntry("y").getComment());
28712f5c69e074d6ef012706068416f0a61b70b4e52Narayan Kamath      assertTrue(Arrays.equals(extra, zipFile.getEntry("y").getExtra()));
288c242577b1569f97f806ef176e4549141df147b78Kenny Root    } finally {
289c242577b1569f97f806ef176e4549141df147b78Kenny Root      zipFile.close();
290c242577b1569f97f806ef176e4549141df147b78Kenny Root    }
291c242577b1569f97f806ef176e4549141df147b78Kenny Root  }
2926bd77683de703a6df640e863b38a73041e8c0c1bElliott Hughes}
293