1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.compress.archivers.ar;
19
20 import static org.hamcrest.CoreMatchers.equalTo;
21 import static org.hamcrest.CoreMatchers.not;
22 import static org.hamcrest.CoreMatchers.nullValue;
23 import static org.hamcrest.MatcherAssert.assertThat;
24 import static org.junit.jupiter.api.Assertions.assertEquals;
25 import static org.junit.jupiter.api.Assertions.assertNotNull;
26 import static org.junit.jupiter.api.Assertions.assertNull;
27 import static org.junit.jupiter.api.Assertions.assertThrows;
28
29 import java.io.BufferedInputStream;
30 import java.io.IOException;
31 import java.io.InputStream;
32
33 import org.apache.commons.compress.AbstractTest;
34 import org.apache.commons.compress.archivers.ArchiveEntry;
35 import org.apache.commons.compress.utils.ArchiveUtils;
36 import org.apache.commons.io.IOUtils;
37 import org.junit.jupiter.api.Test;
38 import org.junit.jupiter.params.ParameterizedTest;
39 import org.junit.jupiter.params.provider.ValueSource;
40
41 public class ArArchiveInputStreamTest extends AbstractTest {
42
43 private void checkLongNameEntry(final String archive) throws Exception {
44 try (InputStream fis = newInputStream(archive);
45 ArArchiveInputStream s = new ArArchiveInputStream(new BufferedInputStream(fis))) {
46 ArchiveEntry e = s.getNextEntry();
47 assertEquals("this_is_a_long_file_name.txt", e.getName());
48 assertEquals(14, e.getSize());
49 final byte[] hello = new byte[14];
50 s.read(hello);
51 assertEquals("Hello, world!\n", ArchiveUtils.toAsciiString(hello));
52 e = s.getNextEntry();
53 assertEquals("this_is_a_long_file_name_as_well.txt", e.getName());
54 assertEquals(4, e.getSize());
55 final byte[] bye = new byte[4];
56 s.read(bye);
57 assertEquals("Bye\n", ArchiveUtils.toAsciiString(bye));
58 assertNull(s.getNextEntry());
59 }
60 }
61
62 @Test
63 public void testCantReadAfterClose() throws Exception {
64 try (InputStream in = newInputStream("bla.ar");
65 ArArchiveInputStream archive = new ArArchiveInputStream(in)) {
66 archive.close();
67 assertThrows(IllegalStateException.class, () -> archive.read());
68 }
69 }
70
71 @Test
72 public void testCantReadWithoutOpeningAnEntry() throws Exception {
73 try (InputStream in = newInputStream("bla.ar");
74 ArArchiveInputStream archive = new ArArchiveInputStream(in)) {
75 assertThrows(IllegalStateException.class, () -> archive.read());
76 }
77 }
78
79 @Test
80 public void testCompress661() throws IOException {
81 testCompress661(false);
82 testCompress661(true);
83 }
84
85 private void testCompress661(final boolean checkMarkReadReset) throws IOException {
86 try (InputStream in = newInputStream("org/apache/commons/compress/COMPRESS-661/testARofText.ar");
87 ArArchiveInputStream archive = new ArArchiveInputStream(new BufferedInputStream(in))) {
88 assertNotNull(archive.getNextEntry());
89 if (checkMarkReadReset && archive.markSupported()) {
90
91
92 archive.mark(10);
93 archive.read(new byte[10]);
94 archive.reset();
95 }
96 final byte[] ba = IOUtils.toByteArray(archive);
97 assertEquals("Test d'indexation de Txt\nhttp://www.apache.org\n", new String(ba));
98 assertEquals(-1, archive.read());
99 assertEquals(-1, archive.read());
100 assertNull(archive.getNextEntry());
101 }
102 }
103
104 @Test
105 public void testInvalidBadTableLength() throws Exception {
106 try (InputStream in = newInputStream("org/apache/commons/compress/ar/number_parsing/bad_table_length_gnu-fail.ar");
107 ArArchiveInputStream archive = new ArArchiveInputStream(in)) {
108 assertThrows(IOException.class, archive::getNextEntry);
109 }
110 }
111
112 @ParameterizedTest
113 @ValueSource(strings = { "bad_long_namelen_bsd-fail.ar", "bad_long_namelen_gnu1-fail.ar", "bad_long_namelen_gnu2-fail.ar", "bad_long_namelen_gnu3-fail.ar",
114 "bad_table_length_gnu-fail.ar" })
115 public void testInvalidLongNameLength(final String testFileName) throws Exception {
116 try (InputStream in = newInputStream("org/apache/commons/compress/ar/number_parsing/" + testFileName);
117 ArArchiveInputStream archive = new ArArchiveInputStream(in)) {
118 assertThrows(IOException.class, archive::getNextEntry);
119 }
120 }
121
122 @ParameterizedTest
123 @ValueSource(strings = { "bad_group-fail.ar", "bad_length-fail.ar", "bad_modified-fail.ar", "bad_user-fail.ar" })
124 public void testInvalidNumericFields(final String testFileName) throws Exception {
125 try (InputStream in = newInputStream("org/apache/commons/compress/ar/number_parsing/" + testFileName);
126 ArArchiveInputStream archive = new ArArchiveInputStream(in)) {
127 assertThrows(IOException.class, archive::getNextEntry);
128 }
129 }
130
131 @Test
132 public void testMultiByteReadConsistentlyReturnsMinusOneAtEof() throws Exception {
133 final byte[] buf = new byte[2];
134 try (InputStream in = newInputStream("bla.ar");
135 ArArchiveInputStream archive = new ArArchiveInputStream(in)) {
136 assertNotNull(archive.getNextEntry());
137 IOUtils.toByteArray(archive);
138 assertEquals(-1, archive.read(buf));
139 assertEquals(-1, archive.read(buf));
140 }
141 }
142
143 @Test
144 public void testReadLongNamesBSD() throws Exception {
145 checkLongNameEntry("longfile_bsd.ar");
146 }
147
148 @Test
149 public void testReadLongNamesGNU() throws Exception {
150 checkLongNameEntry("longfile_gnu.ar");
151 }
152
153 @Test
154 public void testSimpleInputStream() throws IOException {
155 try (InputStream fileInputStream = newInputStream("bla.ar");
156
157
158
159
160 InputStream simpleInputStream = new InputStream() {
161 @Override
162 public int read() throws IOException {
163 return fileInputStream.read();
164 }
165 }) {
166
167 try (ArArchiveInputStream archiveInputStream = new ArArchiveInputStream(simpleInputStream)) {
168 final ArArchiveEntry entry1 = archiveInputStream.getNextEntry();
169 assertThat(entry1, not(nullValue()));
170 assertThat(entry1.getName(), equalTo("test1.xml"));
171 assertThat(entry1.getLength(), equalTo(610L));
172
173 final ArArchiveEntry entry2 = archiveInputStream.getNextEntry();
174 assertThat(entry2.getName(), equalTo("test2.xml"));
175 assertThat(entry2.getLength(), equalTo(82L));
176
177 assertThat(archiveInputStream.getNextEntry(), nullValue());
178 }
179 }
180 }
181
182 @SuppressWarnings("deprecation")
183 @Test
184 public void testSimpleInputStreamDeprecated() throws IOException {
185 try (InputStream fileInputStream = newInputStream("bla.ar");
186
187
188
189
190 InputStream simpleInputStream = new InputStream() {
191 @Override
192 public int read() throws IOException {
193 return fileInputStream.read();
194 }
195 }) {
196
197 try (ArArchiveInputStream archiveInputStream = new ArArchiveInputStream(simpleInputStream)) {
198 final ArArchiveEntry entry1 = archiveInputStream.getNextArEntry();
199 assertThat(entry1, not(nullValue()));
200 assertThat(entry1.getName(), equalTo("test1.xml"));
201 assertThat(entry1.getLength(), equalTo(610L));
202
203 final ArArchiveEntry entry2 = archiveInputStream.getNextArEntry();
204 assertThat(entry2.getName(), equalTo("test2.xml"));
205 assertThat(entry2.getLength(), equalTo(82L));
206
207 assertThat(archiveInputStream.getNextArEntry(), nullValue());
208 }
209 }
210 }
211
212 @Test
213 public void testSingleByteReadConsistentlyReturnsMinusOneAtEof() throws Exception {
214 try (InputStream in = newInputStream("bla.ar");
215 ArArchiveInputStream archive = new ArArchiveInputStream(in)) {
216 assertNotNull(archive.getNextEntry());
217 IOUtils.toByteArray(archive);
218 assertEquals(-1, archive.read());
219 assertEquals(-1, archive.read());
220 }
221 }
222
223 }