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   *   https://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.compressors;
20  
21  import static org.junit.jupiter.api.Assertions.assertEquals;
22  import static org.junit.jupiter.api.Assertions.assertFalse;
23  import static org.junit.jupiter.api.Assertions.assertTrue;
24  
25  import java.io.File;
26  import java.io.InputStream;
27  import java.io.OutputStream;
28  import java.nio.file.Files;
29  import java.util.ArrayList;
30  import java.util.HashMap;
31  import java.util.List;
32  import java.util.Map;
33  
34  import org.apache.commons.compress.AbstractTest;
35  import org.apache.commons.compress.archivers.ArchiveInputStream;
36  import org.apache.commons.compress.archivers.ArchiveStreamFactory;
37  import org.apache.commons.compress.archivers.jar.JarArchiveOutputStream;
38  import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
39  import org.apache.commons.compress.compressors.pack200.Pack200CompressorInputStream;
40  import org.apache.commons.compress.compressors.pack200.Pack200CompressorOutputStream;
41  import org.apache.commons.compress.compressors.pack200.Pack200Strategy;
42  import org.apache.commons.io.IOUtils;
43  import org.junit.jupiter.api.Test;
44  
45  public final class Pack200Test extends AbstractTest {
46  
47      private void jarArchiveCreation(final Pack200Strategy mode) throws Exception {
48          final File output = newTempFile("bla.pack");
49  
50          final File file1 = getFile("test1.xml");
51          final File file2 = getFile("test2.xml");
52  
53          try (OutputStream out = new Pack200CompressorOutputStream(Files.newOutputStream(output.toPath()), mode);
54                  JarArchiveOutputStream os = ArchiveStreamFactory.DEFAULT.createArchiveOutputStream("jar", out)) {
55  
56              os.putArchiveEntry(new ZipArchiveEntry("testdata/test1.xml"));
57              os.write(file1);
58              os.closeArchiveEntry();
59  
60              os.putArchiveEntry(new ZipArchiveEntry("testdata/test2.xml"));
61              os.write(file2);
62              os.closeArchiveEntry();
63          }
64  
65          try (InputStream is = new Pack200CompressorInputStream(output);
66                  ArchiveInputStream<?> in = ArchiveStreamFactory.DEFAULT.createArchiveInputStream("jar", is)) {
67              final List<String> files = new ArrayList<>();
68              files.add("testdata/test1.xml");
69              files.add("testdata/test2.xml");
70              checkArchiveContent(in, files);
71          }
72      }
73  
74      private void jarUnarchiveAll(final boolean useFile, final Pack200Strategy mode) throws Exception {
75          final File input = getFile("bla.pack");
76          try (InputStream is = useFile ? new Pack200CompressorInputStream(input, mode)
77                  : new Pack200CompressorInputStream(Files.newInputStream(input.toPath()), mode);
78                  ArchiveInputStream<?> in = ArchiveStreamFactory.DEFAULT.createArchiveInputStream("jar", is)) {
79              in.forEach(entry -> {
80                  final File archiveEntry = newTempFile(entry.getName());
81                  archiveEntry.getParentFile().mkdirs();
82                  if (entry.isDirectory()) {
83                      archiveEntry.mkdir();
84                  } else {
85                      Files.copy(in, archiveEntry.toPath());
86                  }
87              });
88          }
89      }
90  
91      private void multiByteReadConsistentlyReturnsMinusOneAtEof(final Pack200Strategy s) throws Exception {
92          final File input = getFile("bla.pack");
93          final byte[] buf = new byte[2];
94          try (Pack200CompressorInputStream in = new Pack200CompressorInputStream(input, s)) {
95              IOUtils.toByteArray(in);
96              assertEquals(-1, in.read(buf));
97              assertEquals(-1, in.read(buf));
98          }
99      }
100 
101     private void singleByteReadConsistentlyReturnsMinusOneAtEof(final Pack200Strategy s) throws Exception {
102         final File input = getFile("bla.pack");
103         try (Pack200CompressorInputStream in = new Pack200CompressorInputStream(input, s)) {
104             IOUtils.toByteArray(in);
105             assertEquals(-1, in.read());
106             assertEquals(-1, in.read());
107         }
108     }
109 
110     @Test
111     void testBadSignature() throws Exception {
112         try (InputStream is = newInputStream("bla.jar")) {
113             final byte[] sig = new byte[4];
114             is.read(sig);
115             assertFalse(Pack200CompressorInputStream.matches(sig, 4));
116         }
117     }
118 
119     @Test
120     void testGoodSignature() throws Exception {
121         try (InputStream is = newInputStream("bla.pack")) {
122             final byte[] sig = new byte[4];
123             is.read(sig);
124             assertTrue(Pack200CompressorInputStream.matches(sig, 4));
125         }
126     }
127 
128     @Test
129     void testInputStreamMethods() throws Exception {
130         final Map<String, String> m = new HashMap<>();
131         m.put("foo", "bar");
132         try (InputStream is = new Pack200CompressorInputStream(newInputStream("bla.jar"), m)) {
133             // packed file is a jar, which is a ZIP, so it starts with
134             // a local file header
135             assertTrue(is.markSupported());
136             is.mark(5);
137             assertEquals(0x50, is.read());
138             final byte[] rest = new byte[3];
139             assertEquals(3, is.read(rest));
140             assertEquals(0x4b, rest[0]);
141             assertEquals(3, rest[1]);
142             assertEquals(4, rest[2]);
143             assertEquals(1, is.skip(1));
144             is.reset();
145             assertEquals(0x50, is.read());
146             assertTrue(is.available() > 0);
147         }
148     }
149 
150     @Test
151     void testJarArchiveCreationInMemory() throws Exception {
152         jarArchiveCreation(Pack200Strategy.IN_MEMORY);
153     }
154 
155     @Test
156     void testJarArchiveCreationTempFile() throws Exception {
157         jarArchiveCreation(Pack200Strategy.TEMP_FILE);
158     }
159 
160     @Test
161     void testJarUnarchiveAllFileArgInMemory() throws Exception {
162         jarUnarchiveAll(true, Pack200Strategy.IN_MEMORY);
163     }
164 
165     @Test
166     void testJarUnarchiveAllFileTempFile() throws Exception {
167         jarUnarchiveAll(true, Pack200Strategy.TEMP_FILE);
168     }
169 
170     @Test
171     void testJarUnarchiveAllInMemory() throws Exception {
172         jarUnarchiveAll(false, Pack200Strategy.IN_MEMORY);
173     }
174 
175     @Test
176     void testJarUnarchiveAllTempFile() throws Exception {
177         jarUnarchiveAll(false, Pack200Strategy.TEMP_FILE);
178     }
179 
180     @Test
181     void testMultiByteReadFromMemoryConsistentlyReturnsMinusOneAtEof() throws Exception {
182         multiByteReadConsistentlyReturnsMinusOneAtEof(Pack200Strategy.IN_MEMORY);
183     }
184 
185     @Test
186     void testMultiByteReadFromTempFileConsistentlyReturnsMinusOneAtEof() throws Exception {
187         multiByteReadConsistentlyReturnsMinusOneAtEof(Pack200Strategy.TEMP_FILE);
188     }
189 
190     @Test
191     void testOutputStreamMethods() throws Exception {
192         final File output = newTempFile("bla.pack");
193         final Map<String, String> m = new HashMap<>();
194         m.put("foo", "bar");
195         try (OutputStream out = Files.newOutputStream(output.toPath());
196                 Pack200CompressorOutputStream os = new Pack200CompressorOutputStream(out, m)) {
197             os.write(1);
198             os.write(new byte[] { 2, 3 });
199             os.close();
200             assertTrue(os.isClosed());
201         }
202     }
203 
204     @Test
205     void testShortSignature() throws Exception {
206         try (InputStream is = newInputStream("bla.pack")) {
207             final byte[] sig = new byte[2];
208             is.read(sig);
209             assertFalse(Pack200CompressorInputStream.matches(sig, 2));
210         }
211     }
212 
213     @Test
214     void testSingleByteReadFromMemoryConsistentlyReturnsMinusOneAtEof() throws Exception {
215         singleByteReadConsistentlyReturnsMinusOneAtEof(Pack200Strategy.IN_MEMORY);
216     }
217 
218     @Test
219     void testSingleByteReadFromTempFileConsistentlyReturnsMinusOneAtEof() throws Exception {
220         singleByteReadConsistentlyReturnsMinusOneAtEof(Pack200Strategy.TEMP_FILE);
221     }
222 
223 }