1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.commons.compress.archivers;
20
21 import static org.junit.jupiter.api.Assertions.assertEquals;
22 import static org.junit.jupiter.api.Assertions.assertNotNull;
23 import static org.junit.jupiter.api.Assertions.assertNull;
24 import static org.junit.jupiter.api.Assumptions.assumeTrue;
25
26 import java.io.File;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.nio.file.Files;
30 import java.nio.file.attribute.BasicFileAttributes;
31 import java.security.NoSuchAlgorithmException;
32
33 import javax.crypto.Cipher;
34
35 import org.apache.commons.compress.AbstractTest;
36 import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
37 import org.apache.commons.compress.archivers.sevenz.SevenZFile;
38 import org.apache.commons.compress.archivers.sevenz.SevenZMethod;
39 import org.apache.commons.compress.archivers.sevenz.SevenZOutputFile;
40 import org.apache.commons.compress.utils.TimeUtilsTest;
41 import org.junit.jupiter.api.BeforeEach;
42 import org.junit.jupiter.api.Test;
43
44 class SevenZTest extends AbstractTest {
45
46 private static void assumeStrongCryptoIsAvailable() throws NoSuchAlgorithmException {
47 assumeTrue(Cipher.getMaxAllowedKeyLength("AES/ECB/PKCS5Padding") >= 256, "test requires strong crypto");
48 }
49
50 private File output;
51
52 private final File file1;
53 private final File file2;
54
55 SevenZTest() throws IOException {
56 file1 = getFile("test1.xml");
57 file2 = getFile("test2.xml");
58 }
59
60 private void copy(final File src, final SevenZOutputFile dst) throws IOException {
61 try (InputStream fis = Files.newInputStream(src.toPath())) {
62 final byte[] buffer = new byte[8 * 1024];
63 int bytesRead;
64 while ((bytesRead = fis.read(buffer)) >= 0) {
65 dst.write(buffer, 0, bytesRead);
66 }
67 }
68 }
69
70 private void createArchive(final SevenZMethod method) throws Exception {
71 try (SevenZOutputFile outArchive = new SevenZOutputFile(output)) {
72 outArchive.setContentCompression(method);
73 SevenZArchiveEntry entry;
74
75 entry = outArchive.createArchiveEntry(file1, file1.getName());
76 outArchive.putArchiveEntry(entry);
77 copy(file1, outArchive);
78 outArchive.closeArchiveEntry();
79
80 entry = outArchive.createArchiveEntry(file2, file2.getName());
81 outArchive.putArchiveEntry(entry);
82 copy(file2, outArchive);
83 outArchive.closeArchiveEntry();
84 }
85 }
86
87 private void multiByteReadConsistentlyReturnsMinusOneAtEof(final SevenZFile archive) throws Exception {
88 final byte[] buf = new byte[2];
89 assertNotNull(archive.getNextEntry());
90 assertNotNull(archive.getNextEntry());
91 readFully(archive);
92 assertEquals(-1, archive.read(buf));
93 assertEquals(-1, archive.read(buf));
94 }
95
96 private void multiByteReadConsistentlyReturnsMinusOneAtEof(final SevenZMethod method) throws Exception {
97 createArchive(method);
98 try (SevenZFile archive = SevenZFile.builder().setFile(output).get()) {
99 multiByteReadConsistentlyReturnsMinusOneAtEof(archive);
100 }
101 }
102
103 private void readFully(final SevenZFile archive) throws IOException {
104 final byte[] buf = new byte[1024];
105 int x = 0;
106 while (0 <= (x = archive.read(buf))) {
107
108 }
109 }
110
111 @BeforeEach
112 public void setUp() throws Exception {
113 output = newTempFile("bla.7z");
114 }
115
116 private void singleByteReadConsistentlyReturnsMinusOneAtEof(final SevenZFile archive) throws Exception {
117 assertNotNull(archive.getNextEntry());
118 assertNotNull(archive.getNextEntry());
119 readFully(archive);
120 assertEquals(-1, archive.read());
121 assertEquals(-1, archive.read());
122 }
123
124 private void singleByteReadConsistentlyReturnsMinusOneAtEof(final SevenZMethod method) throws Exception {
125 createArchive(method);
126 try (SevenZFile archive = SevenZFile.builder().setFile(output).get()) {
127 singleByteReadConsistentlyReturnsMinusOneAtEof(archive);
128 }
129 }
130
131 @Test
132 void testMultiByteReadConsistentlyReturnsMinusOneAtEofUsingAES() throws Exception {
133 assumeStrongCryptoIsAvailable();
134 try (SevenZFile archive = new SevenZFile(getFile("bla.encrypted.7z"), "foo".toCharArray())) {
135 multiByteReadConsistentlyReturnsMinusOneAtEof(archive);
136 }
137 }
138
139 @Test
140 void testMultiByteReadConsistentlyReturnsMinusOneAtEofUsingBZIP2() throws Exception {
141 multiByteReadConsistentlyReturnsMinusOneAtEof(SevenZMethod.BZIP2);
142 }
143
144 @Test
145 void testMultiByteReadConsistentlyReturnsMinusOneAtEofUsingDeflate() throws Exception {
146 multiByteReadConsistentlyReturnsMinusOneAtEof(SevenZMethod.DEFLATE);
147 }
148
149 @Test
150 void testMultiByteReadConsistentlyReturnsMinusOneAtEofUsingLZMA() throws Exception {
151 multiByteReadConsistentlyReturnsMinusOneAtEof(SevenZMethod.LZMA);
152 }
153
154 @Test
155 void testMultiByteReadConsistentlyReturnsMinusOneAtEofUsingLZMA2() throws Exception {
156 multiByteReadConsistentlyReturnsMinusOneAtEof(SevenZMethod.LZMA2);
157 }
158
159 private void testSevenZArchiveCreation(final SevenZMethod method) throws Exception {
160 createArchive(method);
161 try (SevenZFile archive = SevenZFile.builder().setFile(output).get()) {
162 SevenZArchiveEntry entry;
163
164 entry = archive.getNextEntry();
165 assertNotNull(entry);
166 assertEquals(file1.getName(), entry.getName());
167 BasicFileAttributes attributes = Files.readAttributes(file1.toPath(), BasicFileAttributes.class);
168 assertEquals(TimeUtilsTest.truncateToHundredNanos(attributes.lastModifiedTime()), entry.getLastModifiedTime());
169 assertEquals(TimeUtilsTest.truncateToHundredNanos(attributes.creationTime()), entry.getCreationTime());
170 assertNotNull(entry.getAccessTime());
171
172 entry = archive.getNextEntry();
173 assertNotNull(entry);
174 assertEquals(file2.getName(), entry.getName());
175 attributes = Files.readAttributes(file2.toPath(), BasicFileAttributes.class);
176 assertEquals(TimeUtilsTest.truncateToHundredNanos(attributes.lastModifiedTime()), entry.getLastModifiedTime());
177 assertEquals(TimeUtilsTest.truncateToHundredNanos(attributes.creationTime()), entry.getCreationTime());
178 assertNotNull(entry.getAccessTime());
179
180 assertNull(archive.getNextEntry());
181 }
182 }
183
184 @Test
185 void testSevenZArchiveCreationUsingBZIP2() throws Exception {
186 testSevenZArchiveCreation(SevenZMethod.BZIP2);
187 }
188
189 @Test
190 void testSevenZArchiveCreationUsingCopy() throws Exception {
191 testSevenZArchiveCreation(SevenZMethod.COPY);
192 }
193
194 @Test
195 void testSevenZArchiveCreationUsingDeflate() throws Exception {
196 testSevenZArchiveCreation(SevenZMethod.DEFLATE);
197 }
198
199 @Test
200 void testSevenZArchiveCreationUsingLZMA() throws Exception {
201 testSevenZArchiveCreation(SevenZMethod.LZMA);
202 }
203
204 @Test
205 void testSevenZArchiveCreationUsingLZMA2() throws Exception {
206 testSevenZArchiveCreation(SevenZMethod.LZMA2);
207 }
208
209 @Test
210 void testSingleByteReadConsistentlyReturnsMinusOneAtEofUsingAES() throws Exception {
211 assumeStrongCryptoIsAvailable();
212 try (SevenZFile archive = new SevenZFile(getFile("bla.encrypted.7z"), "foo".toCharArray())) {
213 singleByteReadConsistentlyReturnsMinusOneAtEof(archive);
214 }
215 }
216
217 @Test
218 void testSingleByteReadConsistentlyReturnsMinusOneAtEofUsingBZIP2() throws Exception {
219 singleByteReadConsistentlyReturnsMinusOneAtEof(SevenZMethod.BZIP2);
220 }
221
222 @Test
223 void testSingleByteReadConsistentlyReturnsMinusOneAtEofUsingCopy() throws Exception {
224 singleByteReadConsistentlyReturnsMinusOneAtEof(SevenZMethod.COPY);
225 }
226
227 @Test
228 void testSingleByteReadConsistentlyReturnsMinusOneAtEofUsingDeflate() throws Exception {
229 singleByteReadConsistentlyReturnsMinusOneAtEof(SevenZMethod.DEFLATE);
230 }
231
232 @Test
233 void testSingleByteReadConsistentlyReturnsMinusOneAtEofUsingLZMA() throws Exception {
234 singleByteReadConsistentlyReturnsMinusOneAtEof(SevenZMethod.LZMA);
235 }
236
237 @Test
238 void testSingleByteReadConsistentlyReturnsMinusOneAtEofUsingLZMA2() throws Exception {
239 singleByteReadConsistentlyReturnsMinusOneAtEof(SevenZMethod.LZMA2);
240 }
241 }