View Javadoc

1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one or more
3    *  contributor license agreements.  See the NOTICE file distributed with
4    *  this work for additional information regarding copyright ownership.
5    *  The ASF licenses this file to You under the Apache License, Version 2.0
6    *  (the "License"); you may not use this file except in compliance with
7    *  the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   *
17   */
18  
19  package org.apache.commons.compress.archivers.zip;
20  
21  import static org.apache.commons.compress.AbstractTestCase.getFile;
22  
23  import java.io.File;
24  import java.io.FileOutputStream;
25  import java.io.InputStream;
26  import java.io.OutputStream;
27  import java.util.ArrayList;
28  import java.util.Collections;
29  import java.util.Enumeration;
30  import java.util.TreeMap;
31  import java.util.zip.ZipEntry;
32  
33  import junit.framework.TestCase;
34  
35  public class ZipFileTest extends TestCase {
36      private ZipFile zf = null;
37  
38      @Override
39      public void tearDown() {
40          ZipFile.closeQuietly(zf);
41      }
42  
43      public void testCDOrder() throws Exception {
44          readOrderTest();
45          ArrayList<ZipArchiveEntry> l = Collections.list(zf.getEntries());
46          assertEntryName(l, 0, "AbstractUnicodeExtraField");
47          assertEntryName(l, 1, "AsiExtraField");
48          assertEntryName(l, 2, "ExtraFieldUtils");
49          assertEntryName(l, 3, "FallbackZipEncoding");
50          assertEntryName(l, 4, "GeneralPurposeBit");
51          assertEntryName(l, 5, "JarMarker");
52          assertEntryName(l, 6, "NioZipEncoding");
53          assertEntryName(l, 7, "Simple8BitZipEncoding");
54          assertEntryName(l, 8, "UnicodeCommentExtraField");
55          assertEntryName(l, 9, "UnicodePathExtraField");
56          assertEntryName(l, 10, "UnixStat");
57          assertEntryName(l, 11, "UnparseableExtraFieldData");
58          assertEntryName(l, 12, "UnrecognizedExtraField");
59          assertEntryName(l, 13, "ZipArchiveEntry");
60          assertEntryName(l, 14, "ZipArchiveInputStream");
61          assertEntryName(l, 15, "ZipArchiveOutputStream");
62          assertEntryName(l, 16, "ZipEncoding");
63          assertEntryName(l, 17, "ZipEncodingHelper");
64          assertEntryName(l, 18, "ZipExtraField");
65          assertEntryName(l, 19, "ZipUtil");
66          assertEntryName(l, 20, "ZipLong");
67          assertEntryName(l, 21, "ZipShort");
68          assertEntryName(l, 22, "ZipFile");
69      }
70  
71      public void testPhysicalOrder() throws Exception {
72          readOrderTest();
73          ArrayList<ZipArchiveEntry> l = Collections.list(zf.getEntriesInPhysicalOrder());
74          assertEntryName(l, 0, "AbstractUnicodeExtraField");
75          assertEntryName(l, 1, "AsiExtraField");
76          assertEntryName(l, 2, "ExtraFieldUtils");
77          assertEntryName(l, 3, "FallbackZipEncoding");
78          assertEntryName(l, 4, "GeneralPurposeBit");
79          assertEntryName(l, 5, "JarMarker");
80          assertEntryName(l, 6, "NioZipEncoding");
81          assertEntryName(l, 7, "Simple8BitZipEncoding");
82          assertEntryName(l, 8, "UnicodeCommentExtraField");
83          assertEntryName(l, 9, "UnicodePathExtraField");
84          assertEntryName(l, 10, "UnixStat");
85          assertEntryName(l, 11, "UnparseableExtraFieldData");
86          assertEntryName(l, 12, "UnrecognizedExtraField");
87          assertEntryName(l, 13, "ZipArchiveEntry");
88          assertEntryName(l, 14, "ZipArchiveInputStream");
89          assertEntryName(l, 15, "ZipArchiveOutputStream");
90          assertEntryName(l, 16, "ZipEncoding");
91          assertEntryName(l, 17, "ZipEncodingHelper");
92          assertEntryName(l, 18, "ZipExtraField");
93          assertEntryName(l, 19, "ZipFile");
94          assertEntryName(l, 20, "ZipLong");
95          assertEntryName(l, 21, "ZipShort");
96          assertEntryName(l, 22, "ZipUtil");
97      }
98  
99      public void testDoubleClose() throws Exception {
100         readOrderTest();
101         zf.close();
102         try {
103             zf.close();
104         } catch (Exception ex) {
105             fail("Caught exception of second close");
106         }
107     }
108 
109     public void testReadingOfStoredEntry() throws Exception {
110         File f = File.createTempFile("commons-compress-zipfiletest", ".zip");
111         f.deleteOnExit();
112         OutputStream o = null;
113         InputStream i = null;
114         try {
115             o = new FileOutputStream(f);
116             ZipArchiveOutputStream zo = new ZipArchiveOutputStream(o);
117             ZipArchiveEntry ze = new ZipArchiveEntry("foo");
118             ze.setMethod(ZipEntry.STORED);
119             ze.setSize(4);
120             ze.setCrc(0xb63cfbcdl);
121             zo.putArchiveEntry(ze);
122             zo.write(new byte[] { 1, 2, 3, 4 });
123             zo.closeArchiveEntry();
124             zo.close();
125             o.close();
126             o  = null;
127 
128             zf = new ZipFile(f);
129             ze = zf.getEntry("foo");
130             assertNotNull(ze);
131             i = zf.getInputStream(ze);
132             byte[] b = new byte[4];
133             assertEquals(4, i.read(b));
134             assertEquals(-1, i.read());
135         } finally {
136             if (o != null) {
137                 o.close();
138             }
139             if (i != null) {
140                 i.close();
141             }
142             f.delete();
143         }
144     }
145 
146     /**
147      * @see "https://issues.apache.org/jira/browse/COMPRESS-176"
148      */
149     public void testWinzipBackSlashWorkaround() throws Exception {
150         File archive = getFile("test-winzip.zip");
151         zf = new ZipFile(archive);
152         assertNull(zf.getEntry("\u00e4\\\u00fc.txt"));
153         assertNotNull(zf.getEntry("\u00e4/\u00fc.txt"));
154     }
155 
156     /**
157      * Test case for 
158      * <a href="https://issues.apache.org/jira/browse/COMPRESS-208"
159      * >COMPRESS-208</a>.
160      */
161     public void testSkipsPK00Prefix() throws Exception {
162         File archive = getFile("COMPRESS-208.zip");
163         zf = new ZipFile(archive);
164         assertNotNull(zf.getEntry("test1.xml"));
165         assertNotNull(zf.getEntry("test2.xml"));
166     }
167 
168     public void testUnixSymlinkSampleFile() throws Exception {
169         final String entryPrefix = "COMPRESS-214_unix_symlinks/";
170         final TreeMap<String, String> expectedVals = new TreeMap<String, String>();
171 
172         // I threw in some Japanese characters to keep things interesting.
173         expectedVals.put(entryPrefix + "link1", "../COMPRESS-214_unix_symlinks/./a/b/c/../../../\uF999");
174         expectedVals.put(entryPrefix + "link2", "../COMPRESS-214_unix_symlinks/./a/b/c/../../../g");
175         expectedVals.put(entryPrefix + "link3", "../COMPRESS-214_unix_symlinks/././a/b/c/../../../\u76F4\u6A39");
176         expectedVals.put(entryPrefix + "link4", "\u82B1\u5B50/\u745B\u5B50");
177         expectedVals.put(entryPrefix + "\uF999", "./\u82B1\u5B50/\u745B\u5B50/\u5897\u8C37/\uF999");
178         expectedVals.put(entryPrefix + "g", "./a/b/c/d/e/f/g");
179         expectedVals.put(entryPrefix + "\u76F4\u6A39", "./g");
180 
181         // Notice how a directory link might contain a trailing slash, or it might not.
182         // Also note:  symlinks are always stored as files, even if they link to directories.
183         expectedVals.put(entryPrefix + "link5", "../COMPRESS-214_unix_symlinks/././a/b");
184         expectedVals.put(entryPrefix + "link6", "../COMPRESS-214_unix_symlinks/././a/b/");
185 
186         // I looked into creating a test with hard links, but zip does not appear to
187         // support hard links, so nevermind.
188 
189         File archive = getFile("COMPRESS-214_unix_symlinks.zip");
190 
191         zf = new ZipFile(archive);
192         Enumeration<ZipArchiveEntry> en = zf.getEntries();
193         while (en.hasMoreElements()) {
194             ZipArchiveEntry zae = en.nextElement();
195             String link = zf.getUnixSymlink(zae);
196             if (zae.isUnixSymlink()) {
197                 String name = zae.getName();
198                 String expected = expectedVals.get(name);
199                 assertEquals(expected, link);
200             } else {
201                 // Should be null if it's not a symlink!
202                 assertNull(link);
203             }
204         }
205     }
206 
207     /*
208      * ordertest.zip has been handcrafted.
209      *
210      * It contains enough files so any random coincidence of
211      * entries.keySet() and central directory order would be unlikely
212      * - in fact testCDOrder fails in svn revision 920284.
213      *
214      * The central directory has ZipFile and ZipUtil swapped so
215      * central directory order is different from entry data order.
216      */
217     private void readOrderTest() throws Exception {
218         File archive = getFile("ordertest.zip");
219         zf = new ZipFile(archive);
220     }
221 
222     private static void assertEntryName(ArrayList<ZipArchiveEntry> entries,
223                                         int index,
224                                         String expectedName) {
225         ZipArchiveEntry ze = entries.get(index);
226         assertEquals("src/main/java/org/apache/commons/compress/archivers/zip/"
227                      + expectedName + ".java",
228                      ze.getName());
229     }
230 }