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.tar;
20
21 import static org.apache.commons.compress.AbstractTestCase.getFile;
22 import static org.junit.Assert.assertArrayEquals;
23 import static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.assertTrue;
25 import static org.junit.Assert.fail;
26
27 import java.io.ByteArrayInputStream;
28 import java.io.ByteArrayOutputStream;
29 import java.io.FileInputStream;
30 import java.io.InputStream;
31 import java.io.IOException;
32 import java.util.Calendar;
33 import java.util.Date;
34 import java.util.Map;
35 import java.util.TimeZone;
36
37 import org.apache.commons.compress.utils.CharsetNames;
38 import org.junit.Test;
39
40 public class TarArchiveInputStreamTest {
41
42 @Test
43 public void readSimplePaxHeader() throws Exception {
44 final TarArchiveInputStream tais = new TarArchiveInputStream(null);
45 Map<String, String> headers = tais
46 .parsePaxHeaders(new ByteArrayInputStream("30 atime=1321711775.972059463\n"
47 .getBytes(CharsetNames.UTF_8)));
48 assertEquals(1, headers.size());
49 assertEquals("1321711775.972059463", headers.get("atime"));
50 tais.close();
51 }
52
53 @Test
54 public void readPaxHeaderWithEmbeddedNewline() throws Exception {
55 final TarArchiveInputStream tais = new TarArchiveInputStream(null);
56 Map<String, String> headers = tais
57 .parsePaxHeaders(new ByteArrayInputStream("28 comment=line1\nline2\nand3\n"
58 .getBytes(CharsetNames.UTF_8)));
59 assertEquals(1, headers.size());
60 assertEquals("line1\nline2\nand3", headers.get("comment"));
61 tais.close();
62 }
63
64 @Test
65 public void readNonAsciiPaxHeader() throws Exception {
66 String ae = "\u00e4";
67 String line = "11 path="+ ae + "\n";
68 assertEquals(11, line.getBytes(CharsetNames.UTF_8).length);
69 final TarArchiveInputStream tais = new TarArchiveInputStream(null);
70 Map<String, String> headers = tais
71 .parsePaxHeaders(new ByteArrayInputStream(line.getBytes(CharsetNames.UTF_8)));
72 assertEquals(1, headers.size());
73 assertEquals(ae, headers.get("path"));
74 tais.close();
75 }
76
77 @Test
78 public void workaroundForBrokenTimeHeader() throws Exception {
79 TarArchiveInputStream in = null;
80 try {
81 in = new TarArchiveInputStream(new FileInputStream(getFile("simple-aix-native-tar.tar")));
82 TarArchiveEntry tae = in.getNextTarEntry();
83 tae = in.getNextTarEntry();
84 assertEquals("sample/link-to-txt-file.lnk", tae.getName());
85 assertEquals(new Date(0), tae.getLastModifiedDate());
86 assertTrue(tae.isSymbolicLink());
87 assertTrue(tae.isCheckSumOK());
88 } finally {
89 if (in != null) {
90 in.close();
91 }
92 }
93 }
94
95 @Test
96 public void datePriorToEpochInGNUFormat() throws Exception {
97 datePriorToEpoch("preepoch-star.tar");
98 }
99
100
101 @Test
102 public void datePriorToEpochInPAXFormat() throws Exception {
103 datePriorToEpoch("preepoch-posix.tar");
104 }
105
106 private void datePriorToEpoch(String archive) throws Exception {
107 TarArchiveInputStream in = null;
108 try {
109 in = new TarArchiveInputStream(new FileInputStream(getFile(archive)));
110 TarArchiveEntry tae = in.getNextTarEntry();
111 assertEquals("foo", tae.getName());
112 Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
113 cal.set(1969, 11, 31, 23, 59, 59);
114 cal.set(Calendar.MILLISECOND, 0);
115 assertEquals(cal.getTime(), tae.getLastModifiedDate());
116 assertTrue(tae.isCheckSumOK());
117 } finally {
118 if (in != null) {
119 in.close();
120 }
121 }
122 }
123
124 @Test
125 public void testCompress197() throws Exception {
126 TarArchiveInputStream tar = getTestStream("/COMPRESS-197.tar");
127 try {
128 TarArchiveEntry entry = tar.getNextTarEntry();
129 while (entry != null) {
130 entry = tar.getNextTarEntry();
131 }
132 } catch (IOException e) {
133 fail("COMPRESS-197: " + e.getMessage());
134 } finally {
135 tar.close();
136 }
137 }
138
139 @Test
140 public void shouldUseSpecifiedEncodingWhenReadingGNULongNames()
141 throws Exception {
142 ByteArrayOutputStream bos = new ByteArrayOutputStream();
143 String encoding = CharsetNames.UTF_16;
144 String name = "1234567890123456789012345678901234567890123456789"
145 + "01234567890123456789012345678901234567890123456789"
146 + "01234567890\u00e4";
147 TarArchiveOutputStream tos =
148 new TarArchiveOutputStream(bos, encoding);
149 tos.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
150 TarArchiveEntry t = new TarArchiveEntry(name);
151 t.setSize(1);
152 tos.putArchiveEntry(t);
153 tos.write(30);
154 tos.closeArchiveEntry();
155 tos.close();
156 byte[] data = bos.toByteArray();
157 ByteArrayInputStream bis = new ByteArrayInputStream(data);
158 TarArchiveInputStream tis =
159 new TarArchiveInputStream(bis, encoding);
160 t = tis.getNextTarEntry();
161 assertEquals(name, t.getName());
162 tis.close();
163 }
164
165 @Test
166 public void shouldConsumeArchiveCompletely() throws Exception {
167 InputStream is = TarArchiveInputStreamTest.class
168 .getResourceAsStream("/archive_with_trailer.tar");
169 TarArchiveInputStream tar = new TarArchiveInputStream(is);
170 while (tar.getNextTarEntry() != null) {
171
172 }
173 byte[] expected = new byte[] {
174 'H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!', '\n'
175 };
176 byte[] actual = new byte[expected.length];
177 is.read(actual);
178 assertArrayEquals(expected, actual);
179 tar.close();
180 }
181
182 private TarArchiveInputStream getTestStream(String name) {
183 return new TarArchiveInputStream(
184 TarArchiveInputStreamTest.class.getResourceAsStream(name));
185 }
186
187 }