View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.commons.compress;
20  
21  import static org.junit.Assert.assertNull;
22  import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
23  import static org.junit.jupiter.api.Assertions.assertEquals;
24  import static org.junit.jupiter.api.Assertions.assertNotNull;
25  import static org.junit.jupiter.api.Assertions.assertThrows;
26  import static org.junit.jupiter.api.Assertions.assertTrue;
27  
28  import java.io.BufferedInputStream;
29  import java.io.IOException;
30  import java.io.InputStream;
31  import java.nio.file.Files;
32  import java.nio.file.Path;
33  
34  import org.apache.commons.compress.archivers.ArchiveEntry;
35  import org.apache.commons.compress.archivers.ArchiveException;
36  import org.apache.commons.compress.archivers.ArchiveInputStream;
37  import org.apache.commons.compress.archivers.ArchiveStreamFactory;
38  import org.apache.commons.compress.archivers.ar.ArArchiveInputStream;
39  import org.apache.commons.compress.archivers.arj.ArjArchiveInputStream;
40  import org.apache.commons.compress.archivers.cpio.CpioArchiveInputStream;
41  import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
42  import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
43  import org.junit.jupiter.api.Test;
44  
45  public final class DetectArchiverTest extends AbstractTest {
46  
47      final ClassLoader classLoader = getClass().getClassLoader();
48  
49      private void checkDetectedType(final String type, final Path path) throws ArchiveException, IOException {
50          try (BufferedInputStream inputStream = new BufferedInputStream(Files.newInputStream(path))) {
51              // SPECIAL case:
52              // For now JAR files are detected as ZIP files.
53              assertEquals(ArchiveStreamFactory.JAR.equals(type) ? ArchiveStreamFactory.ZIP : type, ArchiveStreamFactory.detect(inputStream));
54          }
55      }
56  
57      private void checkEmptyArchive(final String type) throws Exception {
58          final Path path = createEmptyArchive(type); // will be deleted by tearDown()
59          assertDoesNotThrow(() -> {
60              try (BufferedInputStream inputStream = new BufferedInputStream(Files.newInputStream(path));
61                      ArchiveInputStream<?> ais = factory.createArchiveInputStream(inputStream)) {
62                  // empty
63              }
64          }, "Should have recognized empty archive for " + type);
65          checkDetectedType(type, path);
66      }
67  
68      @SuppressWarnings("resource") // Caller closes
69      private <T extends ArchiveInputStream<? extends E>, E extends ArchiveEntry> T createArchiveInputStream(final String resource)
70              throws ArchiveException, IOException {
71          return factory.createArchiveInputStream(createBufferedInputStream(resource));
72      }
73  
74      private BufferedInputStream createBufferedInputStream(final String resource) throws IOException {
75          return new BufferedInputStream(newInputStream(resource));
76      }
77  
78      @Test
79      public void testCOMPRESS_117() throws Exception {
80          try (ArchiveInputStream<?> tar = createArchiveInputStream("COMPRESS-117.tar")) {
81              assertNotNull(tar);
82              assertTrue(tar instanceof TarArchiveInputStream);
83          }
84      }
85  
86      @Test
87      public void testCOMPRESS_335() throws Exception {
88          try (ArchiveInputStream<?> tar = createArchiveInputStream("COMPRESS-335.tar")) {
89              assertNotNull(tar);
90              assertTrue(tar instanceof TarArchiveInputStream);
91          }
92      }
93  
94      @Test
95      public void testDetection() throws Exception {
96  
97          try (ArchiveInputStream<?> ar = createArchiveInputStream("bla.ar")) {
98              assertNotNull(ar);
99              assertTrue(ar instanceof ArArchiveInputStream);
100         }
101 
102         try (ArchiveInputStream<?> tar = createArchiveInputStream("bla.tar")) {
103             assertNotNull(tar);
104             assertTrue(tar instanceof TarArchiveInputStream);
105         }
106 
107         try (ArchiveInputStream<?> zip = createArchiveInputStream("bla.zip")) {
108             assertNotNull(zip);
109             assertTrue(zip instanceof ZipArchiveInputStream);
110         }
111 
112         try (ArchiveInputStream<?> jar = createArchiveInputStream("bla.jar")) {
113             assertNotNull(jar);
114             assertTrue(jar instanceof ZipArchiveInputStream);
115         }
116 
117         try (ArchiveInputStream<?> cpio = createArchiveInputStream("bla.cpio")) {
118             assertNotNull(cpio);
119             assertTrue(cpio instanceof CpioArchiveInputStream);
120         }
121 
122         try (ArchiveInputStream<?> arj = createArchiveInputStream("bla.arj")) {
123             assertNotNull(arj);
124             assertTrue(arj instanceof ArjArchiveInputStream);
125         }
126 
127 // Not yet implemented
128 //        final ArchiveInputStream<?> tgz = getStreamFor("bla.tgz");
129 //        assertNotNull(tgz);
130 //        assertTrue(tgz instanceof TarArchiveInputStream);
131 
132     }
133 
134     @Test
135     public void testDetectionNotArchive() {
136         assertThrows(ArchiveException.class, () -> createArchiveInputStream("test.txt"));
137     }
138 
139     // Check that the empty archives created by the code are readable
140 
141     // Not possible to detect empty "ar" archive as it is completely empty
142 //    public void testEmptyArArchive() throws Exception {
143 //        emptyArchive("ar");
144 //    }
145 
146     @Test
147     public void testDetectOldTarFormatArchive() throws Exception {
148         try (ArchiveInputStream<?> tar = createArchiveInputStream("COMPRESS-612/test-times-star-folder.tar")) {
149             assertNotNull(tar);
150             assertTrue(tar instanceof TarArchiveInputStream);
151         }
152     }
153 
154     @Test
155     public void testEmptyCpioArchive() throws Exception {
156         checkEmptyArchive("cpio");
157     }
158 
159     @Test
160     public void testEmptyJarArchive() throws Exception {
161         checkEmptyArchive("jar");
162     }
163 
164     @Test
165     public void testEmptyTarArchive() throws Exception {
166         // Can't detect empty tar archive from its contents.
167         final Path path = createEmptyArchive("tar"); // will be deleted by tearDown()
168         assertThrows(ArchiveException.class, () -> checkDetectedType("tar", path));
169     }
170 
171     @Test
172     public void testEmptyZipArchive() throws Exception {
173         checkEmptyArchive("zip");
174     }
175 
176     /**
177      * Tests COMPRESS-644.
178      */
179     @Test
180     public void testIgnoreZeroByteEntryInTarDetect() {
181         assertThrows(ArchiveException.class, () -> {
182             try (InputStream in = createBufferedInputStream("org/apache/commons/compress/COMPRESS-644/ARW05UP.ICO")) {
183                 assertNull(ArchiveStreamFactory.detect(in));
184             }
185         });
186     }
187 }