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  import static org.junit.Assert.assertArrayEquals;
23  import static org.junit.Assert.assertEquals;
24  import static org.junit.Assert.assertTrue;
25  import static org.junit.Assert.fail;
26  
27  import java.io.BufferedInputStream;
28  import java.io.EOFException;
29  import java.io.FileInputStream;
30  import java.io.IOException;
31  import java.io.InputStream;
32  import java.util.Arrays;
33  
34  import org.apache.commons.compress.utils.IOUtils;
35  import org.junit.Test;
36  
37  public class ZipArchiveInputStreamTest {
38  
39      /**
40       * @see "https://issues.apache.org/jira/browse/COMPRESS-176"
41       */
42      @Test
43      public void winzipBackSlashWorkaround() throws Exception {
44          ZipArchiveInputStream in = null;
45          try {
46              in = new ZipArchiveInputStream(new FileInputStream(getFile("test-winzip.zip")));
47              ZipArchiveEntry zae = in.getNextZipEntry();
48              zae = in.getNextZipEntry();
49              zae = in.getNextZipEntry();
50              assertEquals("\u00e4/", zae.getName());
51          } finally {
52              if (in != null) {
53                  in.close();
54              }
55          }
56      }
57  
58      /**
59       * @see "https://issues.apache.org/jira/browse/COMPRESS-189"
60       */
61      @Test
62      public void properUseOfInflater() throws Exception {
63          ZipFile zf = null;
64          ZipArchiveInputStream in = null;
65          try {
66              zf = new ZipFile(getFile("COMPRESS-189.zip"));
67              final ZipArchiveEntry zae = zf.getEntry("USD0558682-20080101.ZIP");
68              in = new ZipArchiveInputStream(new BufferedInputStream(zf.getInputStream(zae)));
69              ZipArchiveEntry innerEntry;
70              while ((innerEntry = in.getNextZipEntry()) != null) {
71                  if (innerEntry.getName().endsWith("XML")) {
72                      assertTrue(0 < in.read());
73                  }
74              }
75          } finally {
76              if (zf != null) {
77                  zf.close();
78              }
79              if (in != null) {
80                  in.close();
81              }
82          }
83      }
84  
85      @Test
86      public void shouldConsumeArchiveCompletely() throws Exception {
87          final InputStream is = ZipArchiveInputStreamTest.class
88              .getResourceAsStream("/archive_with_trailer.zip");
89          final ZipArchiveInputStream zip = new ZipArchiveInputStream(is);
90          while (zip.getNextZipEntry() != null) {
91              // just consume the archive
92          }
93          final byte[] expected = new byte[] {
94              'H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!', '\n'
95          };
96          final byte[] actual = new byte[expected.length];
97          is.read(actual);
98          assertArrayEquals(expected, actual);
99          zip.close();
100     }
101 
102     /**
103      * @see "https://issues.apache.org/jira/browse/COMPRESS-219"
104      */
105     @Test
106     public void shouldReadNestedZip() throws IOException {
107         ZipArchiveInputStream in = null;
108         try {
109             in = new ZipArchiveInputStream(new FileInputStream(getFile("COMPRESS-219.zip")));
110             extractZipInputStream(in);
111         } finally {
112             if (in != null) {
113                 in.close();
114             }
115         }
116     }
117 
118     private void extractZipInputStream(final ZipArchiveInputStream in)
119         throws IOException {
120         ZipArchiveEntry zae = in.getNextZipEntry();
121         while (zae != null) {
122             if (zae.getName().endsWith(".zip")) {
123                 extractZipInputStream(new ZipArchiveInputStream(in));
124             }
125             zae = in.getNextZipEntry();
126         }
127     }
128 
129     @Test
130     public void testUnshrinkEntry() throws Exception {
131         final ZipArchiveInputStream in = new ZipArchiveInputStream(new FileInputStream(getFile("SHRUNK.ZIP")));
132         
133         ZipArchiveEntry entry = in.getNextZipEntry();
134         assertEquals("method", ZipMethod.UNSHRINKING.getCode(), entry.getMethod());
135         assertTrue(in.canReadEntryData(entry));
136         
137         FileInputStream original = new FileInputStream(getFile("test1.xml"));
138         try {
139             assertArrayEquals(IOUtils.toByteArray(original), IOUtils.toByteArray(in));
140         } finally {
141             original.close();
142         }
143         
144         entry = in.getNextZipEntry();
145         assertEquals("method", ZipMethod.UNSHRINKING.getCode(), entry.getMethod());
146         assertTrue(in.canReadEntryData(entry));
147         
148         original = new FileInputStream(getFile("test2.xml"));
149         try {
150             assertArrayEquals(IOUtils.toByteArray(original), IOUtils.toByteArray(in));
151         } finally {
152             original.close();
153         }
154     }
155 
156 
157     /**
158      * Test case for 
159      * <a href="https://issues.apache.org/jira/browse/COMPRESS-264"
160      * >COMPRESS-264</a>.
161      */
162     @Test
163     public void testReadingOfFirstStoredEntry() throws Exception {
164         final ZipArchiveInputStream in = new ZipArchiveInputStream(new FileInputStream(getFile("COMPRESS-264.zip")));
165         
166         try {
167             final ZipArchiveEntry ze = in.getNextZipEntry();
168             assertEquals(5, ze.getSize());
169             assertArrayEquals(new byte[] {'d', 'a', 't', 'a', '\n'},
170                               IOUtils.toByteArray(in));
171         } finally {
172             in.close();
173         }
174     }
175 
176     /**
177      * Test case for
178      * <a href="https://issues.apache.org/jira/browse/COMPRESS-351"
179      * >COMPRESS-351</a>.
180      */
181     @Test
182     public void testMessageWithCorruptFileName() throws Exception {
183         final ZipArchiveInputStream in = new ZipArchiveInputStream(new FileInputStream(getFile("COMPRESS-351.zip")));
184         try {
185             ZipArchiveEntry ze = in.getNextZipEntry();
186             while (ze != null) {
187                 ze = in.getNextZipEntry();
188             }
189             fail("expected EOFException");
190         } catch (EOFException ex) {
191             String m = ex.getMessage();
192             assertTrue(m.startsWith("Truncated ZIP entry: ?2016")); // the first character is not printable
193         } finally {
194             in.close();
195         }
196     }
197 
198     @Test
199     public void testUnzipBZip2CompressedEntry() throws Exception {
200         final ZipArchiveInputStream in = new ZipArchiveInputStream(new FileInputStream(getFile("bzip2-zip.zip")));
201         
202         try {
203             final ZipArchiveEntry ze = in.getNextZipEntry();
204             assertEquals(42, ze.getSize());
205             final byte[] expected = new byte[42];
206             Arrays.fill(expected , (byte)'a');
207             assertArrayEquals(expected, IOUtils.toByteArray(in));
208         } finally {
209             in.close();
210         }
211     }
212 }