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 static org.junit.Assert.assertEquals;
22  import static org.junit.Assert.assertNotEquals;
23  import static org.junit.Assert.assertNotNull;
24  import static org.junit.Assert.assertNull;
25  import static org.junit.Assert.assertTrue;
26  import static org.junit.Assert.fail;
27  
28  import java.io.ByteArrayInputStream;
29  import java.io.ByteArrayOutputStream;
30  import java.io.File;
31  import java.io.FileInputStream;
32  import java.io.FileOutputStream;
33  import java.io.IOException;
34  import java.io.InputStreamReader;
35  import java.io.Reader;
36  import java.util.Locale;
37  import org.apache.commons.compress.AbstractTestCase;
38  import org.junit.Test;
39  
40  public class TarArchiveEntryTest implements TarConstants {
41  
42      private static final String OS =
43          System.getProperty("os.name").toLowerCase(Locale.ENGLISH);
44      private static final String ROOT =
45          OS.startsWith("windows") || OS.startsWith("netware") ? "C:\\" : "/";
46  
47      /**
48       * JIRA issue SANDBOX-284
49       *
50       * @see "https://issues.apache.org/jira/browse/SANDBOX-284"
51       */
52      @Test
53      public void testFileSystemRoot() {
54          final TarArchiveEntry t = new TarArchiveEntry(new File(ROOT));
55          assertEquals("/", t.getName());
56      }
57  
58      @Test
59      public void testTarFileWithFSRoot() throws IOException {
60          final File f = File.createTempFile("taetest", ".tar");
61          f.deleteOnExit();
62          TarArchiveOutputStream tout = null;
63          TarArchiveInputStream tin = null;
64          try {
65              tout = new TarArchiveOutputStream(new FileOutputStream(f));
66              TarArchiveEntry t = new TarArchiveEntry(new File(ROOT));
67              tout.putArchiveEntry(t);
68              tout.closeArchiveEntry();
69              t = new TarArchiveEntry(new File(new File(ROOT), "foo.txt"));
70              t.setSize(6);
71              tout.putArchiveEntry(t);
72              tout.write(new byte[] {'h', 'e', 'l', 'l', 'o', ' '});
73              tout.closeArchiveEntry();
74              t = new TarArchiveEntry(new File(new File(ROOT), "bar.txt")
75                                      .getAbsolutePath());
76              t.setSize(5);
77              tout.putArchiveEntry(t);
78              tout.write(new byte[] {'w', 'o', 'r', 'l', 'd'});
79              tout.closeArchiveEntry();
80              t = new TarArchiveEntry("dummy");
81              t.setName(new File(new File(ROOT), "baz.txt").getAbsolutePath());
82              t.setSize(1);
83              tout.putArchiveEntry(t);
84              tout.write(new byte[] {'!'});
85              tout.closeArchiveEntry();
86              tout.close();
87              tout = null;
88  
89              tin = new TarArchiveInputStream(new FileInputStream(f));
90              //tin.setDebug(true);
91              t = tin.getNextTarEntry();
92              assertNotNull(t);
93              assertEquals("/", t.getName());
94              assertTrue(t.isCheckSumOK());
95              t = tin.getNextTarEntry();
96              assertNotNull(t);
97              assertEquals("foo.txt", t.getName());
98              assertTrue(t.isCheckSumOK());
99              t = tin.getNextTarEntry();
100             assertNotNull(t);
101             assertEquals("bar.txt", t.getName());
102             assertTrue(t.isCheckSumOK());
103             t = tin.getNextTarEntry();
104             assertNotNull(t);
105             assertEquals("baz.txt", t.getName());
106             assertTrue(t.isCheckSumOK());
107         } finally {
108             if (tin != null) {
109                 tin.close();
110             }
111             if (tout != null) {
112                 tout.close();
113             }
114             AbstractTestCase.tryHardToDelete(f);
115         }
116     }
117 
118     @Test
119     public void testMaxFileSize(){
120         final TarArchiveEntry t = new TarArchiveEntry("");
121         t.setSize(0);
122         t.setSize(1);
123         try {
124             t.setSize(-1);
125             fail("Should have generated IllegalArgumentException");
126         } catch (final IllegalArgumentException expected) {
127         }
128         t.setSize(077777777777L);
129         t.setSize(0100000000000L);
130     }
131 
132     @Test public void testExtraPaxHeaders() throws IOException {
133         ByteArrayOutputStream bos = new ByteArrayOutputStream();
134         TarArchiveOutputStream tos = new TarArchiveOutputStream(bos);
135         
136         TarArchiveEntry entry = new TarArchiveEntry("./weasels");
137         entry.addPaxHeader("APACHE.mustelida","true");
138         entry.addPaxHeader("SCHILY.xattr.user.org.apache.weasels","maximum weasels");
139         entry.addPaxHeader("size","1");
140         assertEquals("extra header count",2,entry.getExtraPaxHeaders().size());
141         assertEquals("APACHE.mustelida","true",
142             entry.getExtraPaxHeader("APACHE.mustelida"));
143         assertEquals("SCHILY.xattr.user.org.apache.weasels","maximum weasels",
144             entry.getExtraPaxHeader("SCHILY.xattr.user.org.apache.weasels"));
145         assertEquals("size",entry.getSize(),1);
146 
147         tos.putArchiveEntry(entry);
148         tos.write('W');
149         tos.closeArchiveEntry();
150         tos.close();
151         assertNotEquals("should have extra headers before clear",0,entry.getExtraPaxHeaders().size());  
152         entry.clearExtraPaxHeaders();
153         assertEquals("extra headers should be empty after clear",0,entry.getExtraPaxHeaders().size());
154         TarArchiveInputStream tis = new TarArchiveInputStream(new ByteArrayInputStream(bos.toByteArray()));
155         entry = tis.getNextTarEntry();
156         assertNotNull("couldn't get entry",entry);
157 
158         assertEquals("extra header count",2,entry.getExtraPaxHeaders().size());
159         assertEquals("APACHE.mustelida","true",
160             entry.getExtraPaxHeader("APACHE.mustelida"));
161         assertEquals("user.org.apache.weasels","maximum weasels",
162             entry.getExtraPaxHeader("SCHILY.xattr.user.org.apache.weasels"));
163 
164         assertEquals('W',tis.read());
165         assertTrue("should be at end of entry",tis.read() <0);
166 
167         assertNull("should be at end of file",tis.getNextTarEntry());
168         tis.close();
169     }
170 
171     @Test
172     public void testLinkFlagConstructor() {
173         final TarArchiveEntry t = new TarArchiveEntry("/foo", LF_GNUTYPE_LONGNAME);
174         assertGnuMagic(t);
175         assertEquals("foo", t.getName());
176     }
177 
178     @Test
179     public void testLinkFlagConstructorWithFileFlag() {
180         final TarArchiveEntry t = new TarArchiveEntry("/foo", LF_NORMAL);
181         assertPosixMagic(t);
182         assertEquals("foo", t.getName());
183     }
184 
185     @Test
186     public void testLinkFlagConstructorWithPreserve() {
187         final TarArchiveEntry t = new TarArchiveEntry("/foo", LF_GNUTYPE_LONGNAME,
188                                                 true);
189         assertGnuMagic(t);
190         assertEquals("/foo", t.getName());
191     }
192 
193     private void assertGnuMagic(final TarArchiveEntry t) {
194         assertEquals(MAGIC_GNU + VERSION_GNU_SPACE, readMagic(t));
195     }
196 
197     private void assertPosixMagic(final TarArchiveEntry t) {
198         assertEquals(MAGIC_POSIX + VERSION_POSIX, readMagic(t));
199     }
200 
201     private String readMagic(final TarArchiveEntry t) {
202         final byte[] buf = new byte[512];
203         t.writeEntryHeader(buf);
204         return new String(buf, MAGIC_OFFSET, MAGICLEN + VERSIONLEN);
205     }
206 }