1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.commons.compress.harmony.unpack200;
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.assertNotNull;
24 import static org.junit.jupiter.api.Assertions.assertThrows;
25 import static org.junit.jupiter.api.Assertions.assertTrue;
26
27 import java.io.BufferedInputStream;
28 import java.io.BufferedOutputStream;
29 import java.io.BufferedReader;
30 import java.io.File;
31 import java.io.FileInputStream;
32 import java.io.FileOutputStream;
33 import java.io.IOException;
34 import java.io.InputStream;
35 import java.io.InputStreamReader;
36 import java.net.URL;
37 import java.util.Enumeration;
38 import java.util.jar.JarEntry;
39 import java.util.jar.JarFile;
40 import java.util.jar.JarOutputStream;
41 import java.util.zip.ZipEntry;
42
43 import org.apache.commons.compress.AbstractTempDirTest;
44 import org.apache.commons.io.input.BoundedInputStream;
45 import org.apache.commons.io.output.NullOutputStream;
46 import org.junit.jupiter.api.Test;
47 import org.junit.jupiter.params.ParameterizedTest;
48 import org.junit.jupiter.params.provider.ValueSource;
49
50
51
52
53 class ArchiveTest extends AbstractTempDirTest {
54
55 @Test
56 void testAlternativeConstructor() throws Exception {
57 final String inputFile = new File(Archive.class.getResource("/pack200/sql.pack.gz").toURI()).getPath();
58 final File file = createTempFile("sql", ".jar");
59 final String outputFile = file.getPath();
60 new Archive(inputFile, outputFile).unpack();
61 }
62
63 @Test
64 void testDeflateHint() throws Exception {
65 File file = createTempFile("sql", ".jar");
66 try (InputStream in = Archive.class.getResourceAsStream("/pack200/sql.pack.gz");
67 JarOutputStream out = new JarOutputStream(new FileOutputStream(file))) {
68 final Archive archive = new Archive(in, out);
69 archive.setDeflateHint(true);
70 archive.unpack();
71 }
72 try (JarFile jarFile = new JarFile(file)) {
73 assertEquals(ZipEntry.DEFLATED, jarFile.getEntry("bin/test/org/apache/harmony/sql/tests/internal/rowset/CachedRowSetImplTest.class").getMethod());
74 try (InputStream in = Archive.class.getResourceAsStream("/pack200/sql.pack.gz")) {
75 file = createTempFile("sql", ".jar");
76 try (JarOutputStream out = new JarOutputStream(new FileOutputStream(file))) {
77 final Archive archive = new Archive(in, out);
78 archive.setDeflateHint(false);
79 archive.unpack();
80 }
81 }
82 }
83 try (JarFile jarFile = new JarFile(file)) {
84 assertEquals(ZipEntry.STORED, jarFile.getEntry("bin/test/org/apache/harmony/sql/tests/internal/rowset/CachedRowSetImplTest.class").getMethod());
85 }
86 }
87
88 @Test
89 void testJustResourcesGZip() throws Exception {
90 final File file = createTempFile("Just", "ResourcesGz.jar");
91 try (InputStream in = Archive.class.getResourceAsStream("/pack200/JustResources.pack.gz");
92 JarOutputStream out = new JarOutputStream(new FileOutputStream(file))) {
93 new Archive(in, out).unpack();
94 }
95 }
96
97
98 @Test
99 void testLoggingOptions() throws Exception {
100
101 File file = createTempFile("logtest", ".jar");
102 File logFile = createTempFile("logfile", ".txt");
103 try (InputStream in = Archive.class.getResourceAsStream("/pack200/sql.pack.gz");
104 JarOutputStream out = new JarOutputStream(new FileOutputStream(file))) {
105 final Archive archive = new Archive(in, out);
106 archive.setLogFile(logFile.getPath());
107 archive.unpack();
108 }
109
110 assertEquals(0, logFile.length());
111
112 file = createTempFile("logtest", ".jar");
113 try (InputStream in = Archive.class.getResourceAsStream("/pack200/sql.pack.gz");
114 JarOutputStream out = new JarOutputStream(new FileOutputStream(file))) {
115 final Archive archive = new Archive(in, out);
116 logFile = createTempFile("logfile", ".txt");
117 archive.setLogFile(logFile.getPath());
118 archive.setVerbose(true);
119 archive.unpack();
120 }
121
122 assertTrue(logFile.length() > 0);
123
124 final long length = logFile.length();
125 file = createTempFile("logtest", ".jar");
126 try (InputStream in = Archive.class.getResourceAsStream("/pack200/sql.pack.gz");
127 JarOutputStream out = new JarOutputStream(new FileOutputStream(file))) {
128 final Archive archive = new Archive(in, out);
129 archive.setLogFile(logFile.getPath(), true);
130 archive.setVerbose(true);
131 archive.unpack();
132 }
133 assertTrue(logFile.length() > length);
134 file = createTempFile("logtest", ".jar");
135 try (InputStream in = Archive.class.getResourceAsStream("/pack200/sql.pack.gz");
136 JarOutputStream out = new JarOutputStream(new FileOutputStream(file))) {
137 final Archive archive = new Archive(in, out);
138 archive.setLogFile(logFile.getPath(), false);
139 archive.setVerbose(true);
140 archive.unpack();
141 }
142 assertEquals(logFile.length(), length);
143
144 file = createTempFile("logtest", ".jar");
145 try (InputStream in = Archive.class.getResourceAsStream("/pack200/sql.pack.gz");
146 JarOutputStream out = new JarOutputStream(new FileOutputStream(file))) {
147 final Archive archive = new Archive(in, out);
148 logFile = createTempFile("logfile", ".txt");
149 archive.setLogFile(logFile.getPath());
150 archive.setQuiet(true);
151 archive.unpack();
152 }
153
154 assertEquals(0, logFile.length());
155 }
156
157 @ParameterizedTest
158 @ValueSource(strings = {
159
160 "bandint_oom.pack",
161 "cpfloat_oom.pack",
162 "cputf8_oom.pack",
163 "favoured_oom.pack",
164 "filebits_oom.pack",
165 "flags_oom.pack",
166 "references_oom.pack",
167 "segment_header_oom.pack",
168 "signatures_oom.pack"
169
170 })
171
172 void testParsingOOMBounded(final String testFileName) throws Exception {
173 final URL url = Segment.class.getResource("/org/apache/commons/compress/pack/" + testFileName);
174 try (BoundedInputStream in = Pack200UnpackerAdapter.newBoundedInputStream(url);
175 JarOutputStream out = new JarOutputStream(NullOutputStream.INSTANCE)) {
176 assertThrows(IOException.class, () -> new Archive(in, out).unpack());
177 }
178 }
179
180 @ParameterizedTest
181 @ValueSource(strings = {
182
183 "bandint_oom.pack",
184 "cpfloat_oom.pack",
185 "cputf8_oom.pack",
186 "favoured_oom.pack",
187 "filebits_oom.pack",
188 "flags_oom.pack",
189 "references_oom.pack",
190 "segment_header_oom.pack",
191 "signatures_oom.pack"
192
193 })
194
195 void testParsingOOMUnbounded(final String testFileName) throws Exception {
196 try (InputStream is = Segment.class.getResourceAsStream("/org/apache/commons/compress/pack/" + testFileName);
197 JarOutputStream out = new JarOutputStream(NullOutputStream.INSTANCE)) {
198 assertThrows(IOException.class, () -> new Archive(is, out).unpack());
199 }
200 }
201
202 @Test
203 void testRemovePackFile() throws Exception {
204 final File copy = createTempFile("sqlcopy", ".pack.gz");
205 final File original = new File(Archive.class.getResource("/pack200/sql.pack.gz").toURI());
206 try (BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(original));
207 BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(copy))) {
208 final byte[] bytes = new byte[256];
209 int read = inputStream.read(bytes);
210 while (read > 0) {
211 outputStream.write(bytes, 0, read);
212 read = inputStream.read(bytes);
213 }
214 }
215 final String inputFileName = copy.getPath();
216 final File file = createTempFile("sqlout", ".jar");
217 final String outputFileName = file.getPath();
218 final Archive archive = new Archive(inputFileName, outputFileName);
219 archive.setRemovePackFile(true);
220 archive.unpack();
221 assertFalse(copy.exists());
222 }
223
224
225 @Test
226 void testWithAnnotations() throws Exception {
227 final File file = createTempFile("annotations", ".jar");
228 try (InputStream in = Archive.class.getResourceAsStream("/pack200/annotations.pack.gz");
229 JarOutputStream out = new JarOutputStream(new FileOutputStream(file))) {
230 final Archive archive = new Archive(in, out);
231 archive.unpack();
232 }
233 }
234
235
236 @Test
237 void testWithE0() throws Exception {
238 final File file = createTempFile("simple-e0", ".jar");
239 try (InputStream in = Archive.class.getResourceAsStream("/pack200/simple-E0.pack.gz");
240 JarOutputStream out = new JarOutputStream(new FileOutputStream(file))) {
241 final Archive archive = new Archive(in, out);
242 archive.unpack();
243 }
244 }
245
246
247 @Test
248 void testWithJNDIE1() throws Exception {
249 final File file = createTempFile("jndi-e1", ".jar");
250 try (InputStream in = Archive.class.getResourceAsStream("/pack200/jndi-e1.pack.gz");
251 JarOutputStream out = new JarOutputStream(new FileOutputStream(file))) {
252 final Archive archive = new Archive(in, out);
253 archive.unpack();
254 }
255 }
256
257
258
259 @Test
260 void testWithLargeClass() throws Exception {
261 final File file = createTempFile("largeClass", ".jar");
262 try (InputStream in = Archive.class.getResourceAsStream("/pack200/LargeClass.pack.gz");
263 JarOutputStream out = new JarOutputStream(new FileOutputStream(file))) {
264 final Archive archive = new Archive(in, out);
265 archive.unpack();
266 }
267 }
268
269
270 @Test
271 void testWithPack200() throws Exception {
272 final File file = createTempFile("p200", ".jar");
273 try (InputStream in = Archive.class.getResourceAsStream("/pack200/pack200.pack.gz");
274 JarOutputStream out = new JarOutputStream(new FileOutputStream(file))) {
275 final Archive archive = new Archive(in, out);
276 archive.unpack();
277 }
278 }
279
280
281 @Test
282 void testWithPack200E1() throws Exception {
283 final File file = createTempFile("p200-e1", ".jar");
284 try (InputStream in = Archive.class.getResourceAsStream("/pack200/pack200-e1.pack.gz");
285 JarOutputStream out = new JarOutputStream(new FileOutputStream(file))) {
286 final Archive archive = new Archive(in, out);
287 archive.unpack();
288 }
289 }
290
291
292 @Test
293 void testWithSql() throws Exception {
294 final File file = createTempFile("sql", ".jar");
295 try (InputStream in = Archive.class.getResourceAsStream("/pack200/sql.pack.gz");
296 JarOutputStream out = new JarOutputStream(new FileOutputStream(file))) {
297 new Archive(in, out).unpack();
298 }
299 final File compareFile = new File(Archive.class.getResource("/pack200/sqlUnpacked.jar").toURI());
300 try (JarFile jarFile = new JarFile(file);
301 JarFile jarFile2 = new JarFile(compareFile)) {
302
303 final long differenceInJarSizes = Math.abs(compareFile.length() - file.length());
304 assertTrue(differenceInJarSizes < 100, "Expected jar files to be a similar size, difference was " + differenceInJarSizes + " bytes");
305
306 final Enumeration<JarEntry> entries = jarFile.entries();
307 final Enumeration<JarEntry> entries2 = jarFile2.entries();
308 while (entries.hasMoreElements() && entries2.hasMoreElements()) {
309
310 final JarEntry entry = entries.nextElement();
311 assertNotNull(entry);
312 final String name = entry.getName();
313
314 final JarEntry entry2 = entries2.nextElement();
315 assertNotNull(entry2);
316 final String name2 = entry2.getName();
317
318 assertEquals(name, name2);
319
320 try (InputStream ours = jarFile.getInputStream(entry);
321 InputStream expected = jarFile2.getInputStream(entry2);
322 BufferedReader reader1 = new BufferedReader(new InputStreamReader(ours));
323 BufferedReader reader2 = new BufferedReader(new InputStreamReader(expected))) {
324 String line1 = reader1.readLine();
325 String line2 = reader2.readLine();
326 int i = 1;
327 while (line1 != null || line2 != null) {
328 assertEquals(line2, line1, "Unpacked class files differ for " + name);
329 line1 = reader1.readLine();
330 line2 = reader2.readLine();
331 i++;
332 }
333 assertTrue(i > 0);
334 }
335 }
336 }
337 }
338
339
340 @Test
341 void testWithSqlE1() throws Exception {
342 final File file = createTempFile("sql-e1", ".jar");
343 try (InputStream in = Archive.class.getResourceAsStream("/pack200/sql-e1.pack.gz");
344 JarOutputStream out = new JarOutputStream(new FileOutputStream(file))) {
345 final Archive archive = new Archive(in, out);
346 archive.unpack();
347 }
348 }
349
350 }