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