View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one or more
3    *  contributor license agreements.  See the NOTICE file distributed with
4    *  this work for additional information regarding copyright ownership.
5    *  The ASF licenses this file to You under the Apache License, Version 2.0
6    *  (the "License"); you may not use this file except in compliance with
7    *  the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   *
17   */
18  
19  package org.apache.commons.compress.archivers.tar;
20  
21  import java.io.ByteArrayInputStream;
22  import java.io.ByteArrayOutputStream;
23  import java.io.File;
24  import java.io.FileInputStream;
25  import java.io.FileOutputStream;
26  import java.util.Calendar;
27  import java.util.HashMap;
28  import java.util.Map;
29  import java.util.TimeZone;
30  
31  import org.apache.commons.compress.AbstractTestCase;
32  import org.apache.commons.compress.archivers.ArchiveOutputStream;
33  import org.apache.commons.compress.archivers.ArchiveStreamFactory;
34  import org.apache.commons.compress.utils.CharsetNames;
35  import org.apache.commons.compress.utils.IOUtils;
36  
37  public class TarArchiveOutputStreamTest extends AbstractTestCase {
38  
39      public void testCount() throws Exception {
40          File f = File.createTempFile("commons-compress-tarcount", ".tar");
41          f.deleteOnExit();
42          FileOutputStream fos = new FileOutputStream(f);
43  
44          ArchiveOutputStream tarOut = new ArchiveStreamFactory()
45              .createArchiveOutputStream(ArchiveStreamFactory.TAR, fos);
46  
47          File file1 = getFile("test1.xml");
48          TarArchiveEntry sEntry = new TarArchiveEntry(file1, file1.getName());
49          tarOut.putArchiveEntry(sEntry);
50  
51          FileInputStream in = new FileInputStream(file1);
52          byte[] buf = new byte[8192];
53  
54          int read = 0;
55          while ((read = in.read(buf)) > 0) {
56              tarOut.write(buf, 0, read);
57          }
58  
59          in.close();
60          tarOut.closeArchiveEntry();
61          tarOut.close();
62  
63          assertEquals(f.length(), tarOut.getBytesWritten());
64      }
65  
66      public void testMaxFileSizeError() throws Exception {
67          TarArchiveEntry t = new TarArchiveEntry("foo");
68          t.setSize(077777777777L);
69          TarArchiveOutputStream tos =
70              new TarArchiveOutputStream(new ByteArrayOutputStream());
71          tos.putArchiveEntry(t);
72          t.setSize(0100000000000L);
73          tos = new TarArchiveOutputStream(new ByteArrayOutputStream());
74          try {
75              tos.putArchiveEntry(t);
76              fail("Should have generated RuntimeException");
77          } catch (RuntimeException expected) {
78          }
79      }
80  
81      public void testBigNumberStarMode() throws Exception {
82          TarArchiveEntry t = new TarArchiveEntry("foo");
83          t.setSize(0100000000000L);
84          ByteArrayOutputStream bos = new ByteArrayOutputStream();
85          TarArchiveOutputStream tos = new TarArchiveOutputStream(bos);
86          tos.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_STAR);
87          tos.putArchiveEntry(t);
88          // make sure header is written to byte array
89          tos.write(new byte[10 * 1024]);
90          byte[] data = bos.toByteArray();
91          assertEquals(0x80,
92                       data[TarConstants.NAMELEN
93                          + TarConstants.MODELEN
94                          + TarConstants.UIDLEN
95                          + TarConstants.GIDLEN] & 0x80);
96          TarArchiveInputStream tin =
97              new TarArchiveInputStream(new ByteArrayInputStream(data));
98          TarArchiveEntry e = tin.getNextTarEntry();
99          assertEquals(0100000000000L, e.getSize());
100         tin.close();
101         // generates IOE because of unclosed entries.
102         // However we don't really want to create such large entries.
103         closeQuietly(tos);
104     }
105 
106     public void testBigNumberPosixMode() throws Exception {
107         TarArchiveEntry t = new TarArchiveEntry("foo");
108         t.setSize(0100000000000L);
109         ByteArrayOutputStream bos = new ByteArrayOutputStream();
110         TarArchiveOutputStream tos = new TarArchiveOutputStream(bos);
111         tos.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_POSIX);
112         tos.putArchiveEntry(t);
113         // make sure header is written to byte array
114         tos.write(new byte[10 * 1024]);
115         byte[] data = bos.toByteArray();
116         assertEquals("00000000000 ",
117                      new String(data,
118                                 1024 + TarConstants.NAMELEN
119                                 + TarConstants.MODELEN
120                                 + TarConstants.UIDLEN
121                                 + TarConstants.GIDLEN, 12,
122                                 CharsetNames.UTF_8));
123         TarArchiveInputStream tin =
124             new TarArchiveInputStream(new ByteArrayInputStream(data));
125         TarArchiveEntry e = tin.getNextTarEntry();
126         assertEquals(0100000000000L, e.getSize());
127         tin.close();
128         // generates IOE because of unclosed entries.
129         // However we don't really want to create such large entries.
130         closeQuietly(tos);
131     }
132 
133     public void testWriteSimplePaxHeaders() throws Exception {
134         Map<String, String> m = new HashMap<String, String>();
135         m.put("a", "b");
136         byte[] data = writePaxHeader(m);
137         assertEquals("00000000006 ",
138                      new String(data, TarConstants.NAMELEN
139                                 + TarConstants.MODELEN
140                                 + TarConstants.UIDLEN
141                                 + TarConstants.GIDLEN, 12,
142                                 CharsetNames.UTF_8));
143         assertEquals("6 a=b\n", new String(data, 512, 6, CharsetNames.UTF_8));
144     }
145 
146     public void testPaxHeadersWithLength99() throws Exception {
147         Map<String, String> m = new HashMap<String, String>();
148         m.put("a",
149               "0123456789012345678901234567890123456789"
150               + "01234567890123456789012345678901234567890123456789"
151               + "012");
152         byte[] data = writePaxHeader(m);
153         assertEquals("00000000143 ",
154                      new String(data, TarConstants.NAMELEN
155                                 + TarConstants.MODELEN
156                                 + TarConstants.UIDLEN
157                                 + TarConstants.GIDLEN, 12,
158                                 CharsetNames.UTF_8));
159         assertEquals("99 a=0123456789012345678901234567890123456789"
160               + "01234567890123456789012345678901234567890123456789"
161               + "012\n", new String(data, 512, 99, CharsetNames.UTF_8));
162     }
163 
164     public void testPaxHeadersWithLength101() throws Exception {
165         Map<String, String> m = new HashMap<String, String>();
166         m.put("a",
167               "0123456789012345678901234567890123456789"
168               + "01234567890123456789012345678901234567890123456789"
169               + "0123");
170         byte[] data = writePaxHeader(m);
171         assertEquals("00000000145 ",
172                      new String(data, TarConstants.NAMELEN
173                                 + TarConstants.MODELEN
174                                 + TarConstants.UIDLEN
175                                 + TarConstants.GIDLEN, 12,
176                                 CharsetNames.UTF_8));
177         assertEquals("101 a=0123456789012345678901234567890123456789"
178               + "01234567890123456789012345678901234567890123456789"
179               + "0123\n", new String(data, 512, 101, CharsetNames.UTF_8));
180     }
181 
182     private byte[] writePaxHeader(Map<String, String> m) throws Exception {
183         ByteArrayOutputStream bos = new ByteArrayOutputStream();
184         TarArchiveOutputStream tos = new TarArchiveOutputStream(bos, "ASCII");
185         tos.writePaxHeaders("foo", m);
186 
187         // add a dummy entry so data gets written
188         TarArchiveEntry t = new TarArchiveEntry("foo");
189         t.setSize(10 * 1024);
190         tos.putArchiveEntry(t);
191         tos.write(new byte[10 * 1024]);
192         tos.closeArchiveEntry();
193         tos.close();
194 
195         return bos.toByteArray();
196     }
197 
198     public void testWriteLongFileNamePosixMode() throws Exception {
199         String n = "01234567890123456789012345678901234567890123456789"
200             + "01234567890123456789012345678901234567890123456789"
201             + "01234567890123456789012345678901234567890123456789";
202         TarArchiveEntry t =
203             new TarArchiveEntry(n);
204         t.setSize(10 * 1024);
205         ByteArrayOutputStream bos = new ByteArrayOutputStream();
206         TarArchiveOutputStream tos = new TarArchiveOutputStream(bos, "ASCII");
207         tos.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX);
208         tos.putArchiveEntry(t);
209         tos.write(new byte[10 * 1024]);
210         tos.closeArchiveEntry();
211         byte[] data = bos.toByteArray();
212         assertEquals("160 path=" + n + "\n",
213                      new String(data, 512, 160, CharsetNames.UTF_8));
214         TarArchiveInputStream tin =
215             new TarArchiveInputStream(new ByteArrayInputStream(data));
216         TarArchiveEntry e = tin.getNextTarEntry();
217         assertEquals(n, e.getName());
218         tin.close();
219         tos.close();
220     }
221 
222     public void testOldEntryStarMode() throws Exception {
223         TarArchiveEntry t = new TarArchiveEntry("foo");
224         t.setSize(Integer.MAX_VALUE);
225         t.setModTime(-1000);
226         ByteArrayOutputStream bos = new ByteArrayOutputStream();
227         TarArchiveOutputStream tos = new TarArchiveOutputStream(bos);
228         tos.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_STAR);
229         tos.putArchiveEntry(t);
230         // make sure header is written to byte array
231         tos.write(new byte[10 * 1024]);
232         byte[] data = bos.toByteArray();
233         assertEquals((byte) 0xff,
234                      data[TarConstants.NAMELEN
235                           + TarConstants.MODELEN
236                           + TarConstants.UIDLEN
237                           + TarConstants.GIDLEN
238                           + TarConstants.SIZELEN]);
239         TarArchiveInputStream tin =
240             new TarArchiveInputStream(new ByteArrayInputStream(data));
241         TarArchiveEntry e = tin.getNextTarEntry();
242         Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
243         cal.set(1969, 11, 31, 23, 59, 59);
244         cal.set(Calendar.MILLISECOND, 0);
245         assertEquals(cal.getTime(), e.getLastModifiedDate());
246         tin.close();
247         // generates IOE because of unclosed entries.
248         // However we don't really want to create such large entries.
249         closeQuietly(tos);
250     }
251 
252     public void testOldEntryPosixMode() throws Exception {
253         TarArchiveEntry t = new TarArchiveEntry("foo");
254         t.setSize(Integer.MAX_VALUE);
255         t.setModTime(-1000);
256         ByteArrayOutputStream bos = new ByteArrayOutputStream();
257         TarArchiveOutputStream tos = new TarArchiveOutputStream(bos);
258         tos.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_POSIX);
259         tos.putArchiveEntry(t);
260         // make sure header is written to byte array
261         tos.write(new byte[10 * 1024]);
262         byte[] data = bos.toByteArray();
263         assertEquals("00000000000 ",
264                      new String(data,
265                                 1024 + TarConstants.NAMELEN
266                                 + TarConstants.MODELEN
267                                 + TarConstants.UIDLEN
268                                 + TarConstants.GIDLEN
269                                 + TarConstants.SIZELEN, 12,
270                                 CharsetNames.UTF_8));
271         TarArchiveInputStream tin =
272             new TarArchiveInputStream(new ByteArrayInputStream(data));
273         TarArchiveEntry e = tin.getNextTarEntry();
274         Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
275         cal.set(1969, 11, 31, 23, 59, 59);
276         cal.set(Calendar.MILLISECOND, 0);
277         assertEquals(cal.getTime(), e.getLastModifiedDate());
278         tin.close();
279         // generates IOE because of unclosed entries.
280         // However we don't really want to create such large entries.
281         closeQuietly(tos);
282     }
283 
284     public void testOldEntryError() throws Exception {
285         TarArchiveEntry t = new TarArchiveEntry("foo");
286         t.setSize(Integer.MAX_VALUE);
287         t.setModTime(-1000);
288         TarArchiveOutputStream tos =
289             new TarArchiveOutputStream(new ByteArrayOutputStream());
290         try {
291             tos.putArchiveEntry(t);
292             fail("Should have generated RuntimeException");
293         } catch (RuntimeException expected) {
294         }
295         tos.close();
296     }
297 
298     public void testWriteNonAsciiPathNamePaxHeader() throws Exception {
299         String n = "\u00e4";
300         TarArchiveEntry t = new TarArchiveEntry(n);
301         t.setSize(10 * 1024);
302         ByteArrayOutputStream bos = new ByteArrayOutputStream();
303         TarArchiveOutputStream tos = new TarArchiveOutputStream(bos);
304         tos.setAddPaxHeadersForNonAsciiNames(true);
305         tos.putArchiveEntry(t);
306         tos.write(new byte[10 * 1024]);
307         tos.closeArchiveEntry();
308         tos.close();
309         byte[] data = bos.toByteArray();
310         assertEquals("11 path=" + n + "\n",
311                      new String(data, 512, 11, CharsetNames.UTF_8));
312         TarArchiveInputStream tin =
313             new TarArchiveInputStream(new ByteArrayInputStream(data));
314         TarArchiveEntry e = tin.getNextTarEntry();
315         assertEquals(n, e.getName());
316         tin.close();
317     }
318 
319     public void testWriteNonAsciiLinkPathNamePaxHeader() throws Exception {
320         String n = "\u00e4";
321         TarArchiveEntry t = new TarArchiveEntry("a", TarConstants.LF_LINK);
322         t.setSize(10 * 1024);
323         t.setLinkName(n);
324         ByteArrayOutputStream bos = new ByteArrayOutputStream();
325         TarArchiveOutputStream tos = new TarArchiveOutputStream(bos);
326         tos.setAddPaxHeadersForNonAsciiNames(true);
327         tos.putArchiveEntry(t);
328         tos.write(new byte[10 * 1024]);
329         tos.closeArchiveEntry();
330         tos.close();
331         byte[] data = bos.toByteArray();
332         assertEquals("15 linkpath=" + n + "\n",
333                      new String(data, 512, 15, CharsetNames.UTF_8));
334         TarArchiveInputStream tin =
335             new TarArchiveInputStream(new ByteArrayInputStream(data));
336         TarArchiveEntry e = tin.getNextTarEntry();
337         assertEquals(n, e.getLinkName());
338         tin.close();
339     }
340 
341     /**
342      * @see "https://issues.apache.org/jira/browse/COMPRESS-200"
343      */
344     public void testRoundtripWith67CharFileNameGnu() throws Exception {
345         testRoundtripWith67CharFileName(TarArchiveOutputStream.LONGFILE_GNU);
346     }
347 
348     /**
349      * @see "https://issues.apache.org/jira/browse/COMPRESS-200"
350      */
351     public void testRoundtripWith67CharFileNamePosix() throws Exception {
352         testRoundtripWith67CharFileName(TarArchiveOutputStream.LONGFILE_POSIX);
353     }
354 
355     private void testRoundtripWith67CharFileName(int mode) throws Exception {
356         String n = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
357             + "AAAAAAA";
358         assertEquals(67, n.length());
359         TarArchiveEntry t = new TarArchiveEntry(n);
360         t.setSize(10 * 1024);
361         ByteArrayOutputStream bos = new ByteArrayOutputStream();
362         TarArchiveOutputStream tos = new TarArchiveOutputStream(bos, "ASCII");
363         tos.setLongFileMode(mode);
364         tos.putArchiveEntry(t);
365         tos.write(new byte[10 * 1024]);
366         tos.closeArchiveEntry();
367         tos.close();
368         byte[] data = bos.toByteArray();
369         TarArchiveInputStream tin =
370             new TarArchiveInputStream(new ByteArrayInputStream(data));
371         TarArchiveEntry e = tin.getNextTarEntry();
372         assertEquals(n, e.getName());
373         tin.close();
374     }
375 
376     public void testWriteLongDirectoryNameErrorMode() throws Exception {
377         String n = "01234567890123456789012345678901234567890123456789"
378                 + "01234567890123456789012345678901234567890123456789"
379                 + "01234567890123456789012345678901234567890123456789/";
380 
381         try {
382             TarArchiveEntry t = new TarArchiveEntry(n);
383             ByteArrayOutputStream bos = new ByteArrayOutputStream();
384             TarArchiveOutputStream tos = new TarArchiveOutputStream(bos, "ASCII");
385             tos.setLongFileMode(TarArchiveOutputStream.LONGFILE_ERROR);
386             tos.putArchiveEntry(t);
387             tos.closeArchiveEntry();
388             tos.close();
389             
390             fail("Truncated name didn't throw an exception");
391         } catch (RuntimeException e) {
392             // expected
393         }
394     }
395 
396     public void testWriteLongDirectoryNameTruncateMode() throws Exception {
397         String n = "01234567890123456789012345678901234567890123456789"
398             + "01234567890123456789012345678901234567890123456789"
399             + "01234567890123456789012345678901234567890123456789/";
400         TarArchiveEntry t = new TarArchiveEntry(n);
401         ByteArrayOutputStream bos = new ByteArrayOutputStream();
402         TarArchiveOutputStream tos = new TarArchiveOutputStream(bos, "ASCII");
403         tos.setLongFileMode(TarArchiveOutputStream.LONGFILE_TRUNCATE);
404         tos.putArchiveEntry(t);
405         tos.closeArchiveEntry();
406         tos.close();
407         byte[] data = bos.toByteArray();
408         TarArchiveInputStream tin =
409             new TarArchiveInputStream(new ByteArrayInputStream(data));
410         TarArchiveEntry e = tin.getNextTarEntry();
411         assertEquals("Entry name", n.substring(0, TarConstants.NAMELEN) + "/", e.getName());
412         assertTrue("The entry is not a directory", e.isDirectory());
413         tin.close();
414     }
415 
416     /**
417      * @see "https://issues.apache.org/jira/browse/COMPRESS-203"
418      */
419     public void testWriteLongDirectoryNameGnuMode() throws Exception {
420         testWriteLongDirectoryName(TarArchiveOutputStream.LONGFILE_GNU);
421     }
422 
423     /**
424      * @see "https://issues.apache.org/jira/browse/COMPRESS-203"
425      */
426     public void testWriteLongDirectoryNamePosixMode() throws Exception {
427         testWriteLongDirectoryName(TarArchiveOutputStream.LONGFILE_POSIX);
428     }
429 
430     private void testWriteLongDirectoryName(int mode) throws Exception {
431         String n = "01234567890123456789012345678901234567890123456789"
432             + "01234567890123456789012345678901234567890123456789"
433             + "01234567890123456789012345678901234567890123456789/";
434         TarArchiveEntry t = new TarArchiveEntry(n);
435         ByteArrayOutputStream bos = new ByteArrayOutputStream();
436         TarArchiveOutputStream tos = new TarArchiveOutputStream(bos, "ASCII");
437         tos.setLongFileMode(mode);
438         tos.putArchiveEntry(t);
439         tos.closeArchiveEntry();
440         tos.close();
441         byte[] data = bos.toByteArray();
442         TarArchiveInputStream tin =
443             new TarArchiveInputStream(new ByteArrayInputStream(data));
444         TarArchiveEntry e = tin.getNextTarEntry();
445         assertEquals(n, e.getName());
446         assertTrue(e.isDirectory());
447         tin.close();
448     }
449 
450     /**
451      * @see "https://issues.apache.org/jira/browse/COMPRESS-203"
452      */
453     public void testWriteNonAsciiDirectoryNamePosixMode() throws Exception {
454         String n = "f\u00f6\u00f6/";
455         TarArchiveEntry t = new TarArchiveEntry(n);
456         ByteArrayOutputStream bos = new ByteArrayOutputStream();
457         TarArchiveOutputStream tos = new TarArchiveOutputStream(bos);
458         tos.setAddPaxHeadersForNonAsciiNames(true);
459         tos.putArchiveEntry(t);
460         tos.closeArchiveEntry();
461         tos.close();
462         byte[] data = bos.toByteArray();
463         TarArchiveInputStream tin =
464             new TarArchiveInputStream(new ByteArrayInputStream(data));
465         TarArchiveEntry e = tin.getNextTarEntry();
466         assertEquals(n, e.getName());
467         assertTrue(e.isDirectory());
468         tin.close();
469     }
470 
471     /**
472      * @see "https://issues.apache.org/jira/browse/COMPRESS-265"
473      */
474     public void testWriteNonAsciiNameWithUnfortunateNamePosixMode() throws Exception {
475         String n = "f\u00f6\u00f6\u00dc";
476         TarArchiveEntry t = new TarArchiveEntry(n);
477         ByteArrayOutputStream bos = new ByteArrayOutputStream();
478         TarArchiveOutputStream tos = new TarArchiveOutputStream(bos);
479         tos.setAddPaxHeadersForNonAsciiNames(true);
480         tos.putArchiveEntry(t);
481         tos.closeArchiveEntry();
482         tos.close();
483         byte[] data = bos.toByteArray();
484         TarArchiveInputStream tin =
485             new TarArchiveInputStream(new ByteArrayInputStream(data));
486         TarArchiveEntry e = tin.getNextTarEntry();
487         assertEquals(n, e.getName());
488         assertFalse(e.isDirectory());
489         tin.close();
490     }
491 
492     /**
493      * @see "https://issues.apache.org/jira/browse/COMPRESS-237"
494      */
495     public void testWriteLongLinkNameErrorMode() throws Exception {
496         String linkname = "01234567890123456789012345678901234567890123456789"
497                 + "01234567890123456789012345678901234567890123456789"
498                 + "01234567890123456789012345678901234567890123456789/test";
499         TarArchiveEntry entry = new TarArchiveEntry("test", TarConstants.LF_SYMLINK);
500         entry.setLinkName(linkname);
501         
502         try {
503             ByteArrayOutputStream bos = new ByteArrayOutputStream();
504             TarArchiveOutputStream tos = new TarArchiveOutputStream(bos, "ASCII");
505             tos.setLongFileMode(TarArchiveOutputStream.LONGFILE_ERROR);
506             tos.putArchiveEntry(entry);
507             tos.closeArchiveEntry();
508             tos.close();
509             
510             fail("Truncated link name didn't throw an exception");
511         } catch (RuntimeException e) {
512             // expected
513         }
514     }
515 
516     public void testWriteLongLinkNameTruncateMode() throws Exception {
517         String linkname = "01234567890123456789012345678901234567890123456789"
518             + "01234567890123456789012345678901234567890123456789"
519             + "01234567890123456789012345678901234567890123456789/";
520         TarArchiveEntry entry = new TarArchiveEntry("test" , TarConstants.LF_SYMLINK);
521         entry.setLinkName(linkname);
522         
523         ByteArrayOutputStream bos = new ByteArrayOutputStream();
524         TarArchiveOutputStream tos = new TarArchiveOutputStream(bos, "ASCII");
525         tos.setLongFileMode(TarArchiveOutputStream.LONGFILE_TRUNCATE);
526         tos.putArchiveEntry(entry);
527         tos.closeArchiveEntry();
528         tos.close();
529         
530         byte[] data = bos.toByteArray();
531         TarArchiveInputStream tin = new TarArchiveInputStream(new ByteArrayInputStream(data));
532         TarArchiveEntry e = tin.getNextTarEntry();
533         assertEquals("Link name", linkname.substring(0, TarConstants.NAMELEN), e.getLinkName());
534         tin.close();
535     }
536 
537     /**
538      * @see "https://issues.apache.org/jira/browse/COMPRESS-237"
539      */
540     public void testWriteLongLinkNameGnuMode() throws Exception {
541         testWriteLongLinkName(TarArchiveOutputStream.LONGFILE_GNU);
542     }
543 
544     /**
545      * @see "https://issues.apache.org/jira/browse/COMPRESS-237"
546      */
547     public void testWriteLongLinkNamePosixMode() throws Exception {
548         testWriteLongLinkName(TarArchiveOutputStream.LONGFILE_POSIX);
549     }
550 
551     /**
552      * @see "https://issues.apache.org/jira/browse/COMPRESS-237"
553      */
554     public void testWriteLongLinkName(int mode) throws Exception {
555         String linkname = "01234567890123456789012345678901234567890123456789"
556             + "01234567890123456789012345678901234567890123456789"
557             + "01234567890123456789012345678901234567890123456789/test";
558         TarArchiveEntry entry = new TarArchiveEntry("test", TarConstants.LF_SYMLINK);
559         entry.setLinkName(linkname);
560         
561         ByteArrayOutputStream bos = new ByteArrayOutputStream();
562         TarArchiveOutputStream tos = new TarArchiveOutputStream(bos, "ASCII");
563         tos.setLongFileMode(mode);
564         tos.putArchiveEntry(entry);
565         tos.closeArchiveEntry();
566         tos.close();
567         
568         byte[] data = bos.toByteArray();
569         TarArchiveInputStream tin = new TarArchiveInputStream(new ByteArrayInputStream(data));
570         TarArchiveEntry e = tin.getNextTarEntry();
571         assertEquals("Entry name", "test", e.getName());
572         assertEquals("Link name", linkname, e.getLinkName());
573         assertTrue("The entry is not a symbolic link", e.isSymbolicLink());
574         tin.close();
575     }
576 
577     public void testPadsOutputToFullBlockLength() throws Exception {
578         File f = File.createTempFile("commons-compress-padding", ".tar");
579         f.deleteOnExit();
580         FileOutputStream fos = new FileOutputStream(f);
581         TarArchiveOutputStream tos = new TarArchiveOutputStream(fos);
582         File file1 = getFile("test1.xml");
583         TarArchiveEntry sEntry = new TarArchiveEntry(file1, file1.getName());
584         tos.putArchiveEntry(sEntry);
585         FileInputStream in = new FileInputStream(file1);
586         IOUtils.copy(in, tos);
587         in.close();
588         tos.closeArchiveEntry();
589         tos.close();
590         // test1.xml is small enough to fit into the default block size
591         assertEquals(TarConstants.DEFAULT_BLKSIZE, f.length());
592     }
593 
594 }