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