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  
20  package org.apache.commons.compress.archivers.arj;
21  
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.assertFalse;
25  import static org.junit.jupiter.api.Assertions.assertNotNull;
26  import static org.junit.jupiter.api.Assertions.assertThrows;
27  import static org.junit.jupiter.api.Assertions.assertTrue;
28  import static org.junit.jupiter.api.Assertions.fail;
29  
30  import java.io.IOException;
31  import java.io.InputStream;
32  import java.nio.charset.Charset;
33  import java.util.Calendar;
34  import java.util.TimeZone;
35  
36  import org.apache.commons.compress.AbstractTest;
37  import org.apache.commons.compress.archivers.ArchiveException;
38  import org.apache.commons.io.IOUtils;
39  import org.apache.commons.io.output.ByteArrayOutputStream;
40  import org.junit.jupiter.api.Test;
41  
42  /**
43   * Tests {@link ArjArchiveInputStream}.
44   */
45  class ArjArchiveInputStreamTest extends AbstractTest {
46  
47      private void assertArjArchiveEntry(final ArjArchiveEntry entry) {
48          assertNotNull(entry.getName());
49          assertNotNull(entry.getLastModifiedDate());
50          assertDoesNotThrow(entry::getHostOs);
51          assertDoesNotThrow(entry::getMethod);
52          assertDoesNotThrow(entry::getMode);
53          assertDoesNotThrow(entry::getSize);
54          assertDoesNotThrow(entry::getUnixMode);
55          assertDoesNotThrow(entry::isDirectory);
56          assertDoesNotThrow(entry::isHostOsUnix);
57          assertDoesNotThrow(entry::hashCode);
58          assertDoesNotThrow(entry::toString);
59          assertDoesNotThrow(() -> entry.resolveIn(getTempDirPath()));
60      }
61  
62      @SuppressWarnings("deprecation")
63      private void assertArjArchiveInputStream(final ArjArchiveInputStream archive) {
64          assertDoesNotThrow(archive::available);
65          assertDoesNotThrow(archive::getArchiveComment);
66          assertDoesNotThrow(archive::getArchiveName);
67          assertDoesNotThrow(archive::getBytesRead);
68          assertDoesNotThrow(archive::getCharset);
69          assertDoesNotThrow(archive::getCount);
70          assertDoesNotThrow(archive::hashCode);
71          assertDoesNotThrow(archive::markSupported);
72      }
73  
74      private void assertForEach(final ArjArchiveInputStream archive) throws IOException {
75          assertArjArchiveInputStream(archive);
76          archive.forEach(entry -> {
77              assertArjArchiveEntry(entry);
78              // inside the loop, just in case.
79              assertArjArchiveInputStream(archive);
80          });
81      }
82  
83      @Test
84      void testFirstHeaderSizeSetToZero() throws Exception {
85          try (InputStream in = newInputStream("org/apache/commons/compress/arj/zero_sized_headers-fail.arj")) {
86              final ArchiveException ex = assertThrows(ArchiveException.class, () -> {
87                  try (ArjArchiveInputStream archive = new ArjArchiveInputStream(in)) {
88                      // Do nothing, ArchiveException already thrown
89                      fail("ArchiveException not thrown.");
90                  }
91              });
92              assertTrue(ex.getCause() instanceof IOException);
93          }
94      }
95  
96      @Test
97      void testForEach() throws Exception {
98          final StringBuilder expected = new StringBuilder();
99          expected.append("test1.xml<?xml version=\"1.0\"?>\n");
100         expected.append("<empty/>test2.xml<?xml version=\"1.0\"?>\n");
101         expected.append("<empty/>\n");
102         final StringBuilder result = new StringBuilder();
103         try (ArjArchiveInputStream in = new ArjArchiveInputStream(newInputStream("bla.arj"))) {
104             in.forEach(entry -> {
105                 result.append(entry.getName());
106                 int tmp;
107                 // read() one at a time
108                 while ((tmp = in.read()) != -1) {
109                     result.append((char) tmp);
110                 }
111                 assertFalse(entry.isDirectory());
112                 assertArjArchiveEntry(entry);
113             });
114         }
115         assertEquals(expected.toString(), result.toString());
116     }
117 
118     @Test
119     void testGetNextEntry() throws Exception {
120         final StringBuilder expected = new StringBuilder();
121         expected.append("test1.xml<?xml version=\"1.0\"?>\n");
122         expected.append("<empty/>test2.xml<?xml version=\"1.0\"?>\n");
123         expected.append("<empty/>\n");
124         final StringBuilder result = new StringBuilder();
125         try (ArjArchiveInputStream in = new ArjArchiveInputStream(newInputStream("bla.arj"))) {
126             ArjArchiveEntry entry;
127             while ((entry = in.getNextEntry()) != null) {
128                 result.append(entry.getName());
129                 int tmp;
130                 // read() one at a time
131                 while ((tmp = in.read()) != -1) {
132                     result.append((char) tmp);
133                 }
134                 assertFalse(entry.isDirectory());
135                 assertArjArchiveEntry(entry);
136             }
137         }
138         assertEquals(expected.toString(), result.toString());
139     }
140 
141     @Test
142     void testMultiByteReadConsistentlyReturnsMinusOneAtEof() throws Exception {
143         final byte[] buf = new byte[2];
144         try (InputStream in = newInputStream("bla.arj");
145                 ArjArchiveInputStream archive = new ArjArchiveInputStream(in)) {
146             assertNotNull(archive.getNextEntry());
147             IOUtils.toByteArray(archive);
148             assertEquals(-1, archive.read(buf));
149             assertEquals(-1, archive.read(buf));
150             assertForEach(archive);
151         }
152     }
153 
154     @Test
155     void testRead() throws Exception {
156         final StringBuilder expected = new StringBuilder();
157         expected.append("test1.xml<?xml version=\"1.0\"?>\n");
158         expected.append("<empty/>test2.xml<?xml version=\"1.0\"?>\n");
159         expected.append("<empty/>\n");
160         final Charset charset = Charset.defaultCharset();
161         try (ByteArrayOutputStream result = new ByteArrayOutputStream();
162                 ArjArchiveInputStream in = new ArjArchiveInputStream(newInputStream("bla.arj"))) {
163             ArjArchiveEntry entry;
164             while ((entry = in.getNextEntry()) != null) {
165                 result.write(entry.getName().getBytes(charset));
166                 int tmp;
167                 // read() one at a time
168                 while ((tmp = in.read()) != -1) {
169                     result.write(tmp);
170                 }
171                 assertFalse(entry.isDirectory());
172                 assertArjArchiveEntry(entry);
173             }
174             result.flush();
175             assertEquals(expected.toString(), result.toString(charset));
176         }
177     }
178 
179     @Test
180     void testReadByteArray() throws Exception {
181         final StringBuilder expected = new StringBuilder();
182         expected.append("test1.xml<?xml version=\"1.0\"?>\n");
183         expected.append("<empty/>test2.xml<?xml version=\"1.0\"?>\n");
184         expected.append("<empty/>\n");
185         final Charset charset = Charset.defaultCharset();
186         try (ByteArrayOutputStream result = new ByteArrayOutputStream();
187                 ArjArchiveInputStream in = new ArjArchiveInputStream(newInputStream("bla.arj"))) {
188             in.forEach(entry -> {
189                 result.write(entry.getName().getBytes(charset));
190                 final byte[] tmp = new byte[2];
191                 // read(byte[]) at a time
192                 int count;
193                 while ((count = in.read(tmp)) != -1) {
194                     result.write(tmp, 0, count);
195                 }
196                 assertFalse(entry.isDirectory());
197                 assertArjArchiveEntry(entry);
198             });
199             result.flush();
200             assertEquals(expected.toString(), result.toString(charset));
201         }
202     }
203 
204     @Test
205     void testReadByteArrayIndex() throws Exception {
206         final StringBuilder expected = new StringBuilder();
207         expected.append("test1.xml<?xml version=\"1.0\"?>\n");
208         expected.append("<empty/>test2.xml<?xml version=\"1.0\"?>\n");
209         expected.append("<empty/>\n");
210         final Charset charset = Charset.defaultCharset();
211         try (ByteArrayOutputStream result = new ByteArrayOutputStream();
212                 ArjArchiveInputStream in = new ArjArchiveInputStream(newInputStream("bla.arj"))) {
213             in.forEach(entry -> {
214                 result.write(entry.getName().getBytes(charset));
215                 final byte[] tmp = new byte[10];
216                 // read(byte[],int,int) at a time
217                 int count;
218                 while ((count = in.read(tmp, 0, 2)) != -1) {
219                     result.write(tmp, 0, count);
220                 }
221                 assertFalse(entry.isDirectory());
222                 assertArjArchiveEntry(entry);
223             });
224             result.flush();
225             assertEquals(expected.toString(), result.toString(charset));
226         }
227     }
228 
229     @Test
230     void testReadingOfAttributesDosVersion() throws Exception {
231         try (ArjArchiveInputStream archive = new ArjArchiveInputStream(newInputStream("bla.arj"))) {
232             final ArjArchiveEntry entry = archive.getNextEntry();
233             assertEquals("test1.xml", entry.getName());
234             assertEquals(30, entry.getSize());
235             assertEquals(0, entry.getUnixMode());
236             final Calendar cal = Calendar.getInstance();
237             cal.set(2008, 9, 6, 23, 50, 52);
238             cal.set(Calendar.MILLISECOND, 0);
239             assertEquals(cal.getTime(), entry.getLastModifiedDate());
240             assertForEach(archive);
241         }
242     }
243 
244     @Test
245     void testReadingOfAttributesUnixVersion() throws Exception {
246         try (ArjArchiveInputStream in = new ArjArchiveInputStream(newInputStream("bla.unix.arj"))) {
247             final ArjArchiveEntry entry = in.getNextEntry();
248             assertEquals("test1.xml", entry.getName());
249             assertEquals(30, entry.getSize());
250             assertEquals(0664, entry.getUnixMode() & 07777 /* UnixStat.PERM_MASK */);
251             final Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT+0000"));
252             cal.set(2008, 9, 6, 21, 50, 52);
253             cal.set(Calendar.MILLISECOND, 0);
254             assertEquals(cal.getTime(), entry.getLastModifiedDate());
255             assertForEach(in);
256         }
257     }
258 
259     @Test
260     void testSingleByteReadConsistentlyReturnsMinusOneAtEof() throws Exception {
261         try (InputStream in = newInputStream("bla.arj");
262                 ArjArchiveInputStream archive = new ArjArchiveInputStream(in)) {
263             assertNotNull(archive.getNextEntry());
264             IOUtils.toByteArray(archive);
265             assertEquals(-1, archive.read());
266             assertEquals(-1, archive.read());
267             assertForEach(archive);
268         }
269     }
270 
271 }