• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements.  See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership.  The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License.  You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied.  See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 package org.apache.commons.compress.archivers.zip;
20 
21 import org.junit.Before;
22 import org.junit.Test;
23 
24 import java.io.File;
25 import java.util.Arrays;
26 import java.util.Enumeration;
27 import java.util.zip.ZipException;
28 
29 import static org.apache.commons.compress.AbstractTestCase.getFile;
30 import static org.junit.Assert.assertArrayEquals;
31 import static org.junit.Assert.assertEquals;
32 import static org.junit.Assert.assertFalse;
33 import static org.junit.Assert.assertTrue;
34 
35 public class X7875_NewUnixTest {
36 
37     private final static ZipShort X7875 = new ZipShort(0x7875);
38 
39     private X7875_NewUnix xf;
40 
41     @Before
before()42     public void before() {
43         xf = new X7875_NewUnix();
44     }
45 
46 
47     @Test
testSampleFile()48     public void testSampleFile() throws Exception {
49         final File archive = getFile("COMPRESS-211_uid_gid_zip_test.zip");
50         ZipFile zf = null;
51 
52         try {
53             zf = new ZipFile(archive);
54             final Enumeration<ZipArchiveEntry> en = zf.getEntries();
55 
56             // We expect EVERY entry of this zip file (dir & file) to
57             // contain extra field 0x7875.
58             while (en.hasMoreElements()) {
59 
60                 final ZipArchiveEntry zae = en.nextElement();
61                 final String name = zae.getName();
62                 final X7875_NewUnix xf = (X7875_NewUnix) zae.getExtraField(X7875);
63 
64                 // The directory entry in the test zip file is uid/gid 1000.
65                 long expected = 1000;
66                 if (name.contains("uid555_gid555")) {
67                     expected = 555;
68                 } else if (name.contains("uid5555_gid5555")) {
69                     expected = 5555;
70                 } else if (name.contains("uid55555_gid55555")) {
71                     expected = 55555;
72                 } else if (name.contains("uid555555_gid555555")) {
73                     expected = 555555;
74                 } else if (name.contains("min_unix")) {
75                     expected = 0;
76                 } else if (name.contains("max_unix")) {
77                     // 2^32-2 was the biggest UID/GID I could create on my linux!
78                     // (December 2012, linux kernel 3.4)
79                     expected = 0x100000000L - 2;
80                 }
81                 assertEquals(expected, xf.getUID());
82                 assertEquals(expected, xf.getGID());
83             }
84         } finally {
85             if (zf != null) {
86                 zf.close();
87             }
88         }
89     }
90 
91     @Test
testGetHeaderId()92     public void testGetHeaderId() {
93         assertEquals(X7875, xf.getHeaderId());
94     }
95 
96     @Test
testMisc()97     public void testMisc() throws Exception {
98         assertFalse(xf.equals(new Object()));
99         assertTrue(xf.toString().startsWith("0x7875 Zip Extra Field"));
100         final Object o = xf.clone();
101         assertEquals(o.hashCode(), xf.hashCode());
102         assertTrue(xf.equals(o));
103         xf.setUID(12345);
104         assertFalse(xf.equals(o));
105     }
106 
107     @Test
testTrimLeadingZeroesForceMinLength4()108     public void testTrimLeadingZeroesForceMinLength4() {
109         final byte[] NULL = null;
110         final byte[] EMPTY = new byte[0];
111         final byte[] ONE_ZERO = {0};
112         final byte[] TWO_ZEROES = {0, 0};
113         final byte[] FOUR_ZEROES = {0, 0, 0, 0};
114         final byte[] SEQUENCE = {1, 2, 3};
115         final byte[] SEQUENCE_LEADING_ZERO = {0, 1, 2, 3};
116         final byte[] SEQUENCE_LEADING_ZEROES = {0, 0, 0, 0, 0, 0, 0, 1, 2, 3};
117         final byte[] TRAILING_ZERO = {1, 2, 3, 0};
118         final byte[] PADDING_ZERO = {0, 1, 2, 3, 0};
119         final byte[] SEQUENCE6 = {1, 2, 3, 4, 5, 6};
120         final byte[] SEQUENCE6_LEADING_ZERO = {0, 1, 2, 3, 4, 5, 6};
121 
122         assertTrue(NULL == trimTest(NULL));
123         assertTrue(Arrays.equals(ONE_ZERO, trimTest(EMPTY)));
124         assertTrue(Arrays.equals(ONE_ZERO, trimTest(ONE_ZERO)));
125         assertTrue(Arrays.equals(ONE_ZERO, trimTest(TWO_ZEROES)));
126         assertTrue(Arrays.equals(ONE_ZERO, trimTest(FOUR_ZEROES)));
127         assertTrue(Arrays.equals(SEQUENCE, trimTest(SEQUENCE)));
128         assertTrue(Arrays.equals(SEQUENCE, trimTest(SEQUENCE_LEADING_ZERO)));
129         assertTrue(Arrays.equals(SEQUENCE, trimTest(SEQUENCE_LEADING_ZEROES)));
130         assertTrue(Arrays.equals(TRAILING_ZERO, trimTest(TRAILING_ZERO)));
131         assertTrue(Arrays.equals(TRAILING_ZERO, trimTest(PADDING_ZERO)));
132         assertTrue(Arrays.equals(SEQUENCE6, trimTest(SEQUENCE6)));
133         assertTrue(Arrays.equals(SEQUENCE6, trimTest(SEQUENCE6_LEADING_ZERO)));
134     }
135 
trimTest(final byte[] b)136     private static byte[] trimTest(final byte[] b) { return X7875_NewUnix.trimLeadingZeroesForceMinLength(b); }
137 
138     @Test
testParseReparse()139     public void testParseReparse() throws ZipException {
140 
141         // Version=1, Len=0, Len=0.
142         final byte[] ZERO_LEN = {1, 0, 0};
143 
144         // Version=1, Len=1, zero, Len=1, zero.
145         final byte[] ZERO_UID_GID = {1, 1, 0, 1, 0};
146 
147         // Version=1, Len=1, one, Len=1, one
148         final byte[] ONE_UID_GID = {1, 1, 1, 1, 1};
149 
150         // Version=1, Len=2, one thousand, Len=2, one thousand
151         final byte[] ONE_THOUSAND_UID_GID = {1, 2, -24, 3, 2, -24, 3};
152 
153         // (2^32 - 2).   I guess they avoid (2^32 - 1) since it's identical to -1 in
154         // two's complement, and -1 often has a special meaning.
155         final byte[] UNIX_MAX_UID_GID = {1, 4, -2, -1, -1, -1, 4, -2, -1, -1, -1};
156 
157         // Version=1, Len=5, 2^32, Len=5, 2^32 + 1
158         // Esoteric test:  can we handle 40 bit numbers?
159         final byte[] LENGTH_5 = {1, 5, 0, 0, 0, 0, 1, 5, 1, 0, 0, 0, 1};
160 
161         // Version=1, Len=8, 2^63 - 2, Len=8, 2^63 - 1
162         // Esoteric test:  can we handle 64 bit numbers?
163         final byte[] LENGTH_8 = {1, 8, -2, -1, -1, -1, -1, -1, -1, 127, 8, -1, -1, -1, -1, -1, -1, -1, 127};
164 
165         final long TWO_TO_32 = 0x100000000L;
166         final long MAX = TWO_TO_32 - 2;
167 
168         parseReparse(0, 0, ZERO_LEN, 0, 0);
169         parseReparse(0, 0, ZERO_UID_GID, 0, 0);
170         parseReparse(1, 1, ONE_UID_GID, 1, 1);
171         parseReparse(1000, 1000, ONE_THOUSAND_UID_GID, 1000, 1000);
172         parseReparse(MAX, MAX, UNIX_MAX_UID_GID, MAX, MAX);
173         parseReparse(-2, -2, UNIX_MAX_UID_GID, MAX, MAX);
174         parseReparse(TWO_TO_32, TWO_TO_32 + 1, LENGTH_5, TWO_TO_32, TWO_TO_32 + 1);
175         parseReparse(Long.MAX_VALUE - 1, Long.MAX_VALUE, LENGTH_8, Long.MAX_VALUE - 1, Long.MAX_VALUE);
176 
177         // We never emit this, but we should be able to parse it:
178         final byte[] SPURIOUS_ZEROES_1 = {1, 4, -1, 0, 0, 0, 4, -128, 0, 0, 0};
179         final byte[] EXPECTED_1 = {1, 1, -1, 1, -128};
180         xf.parseFromLocalFileData(SPURIOUS_ZEROES_1, 0, SPURIOUS_ZEROES_1.length);
181 
182         assertEquals(255, xf.getUID());
183         assertEquals(128, xf.getGID());
184         assertTrue(Arrays.equals(EXPECTED_1, xf.getLocalFileDataData()));
185 
186         final byte[] SPURIOUS_ZEROES_2 = {1, 4, -1, -1, 0, 0, 4, 1, 2, 0, 0};
187         final byte[] EXPECTED_2 = {1, 2, -1, -1, 2, 1, 2};
188         xf.parseFromLocalFileData(SPURIOUS_ZEROES_2, 0, SPURIOUS_ZEROES_2.length);
189 
190         assertEquals(65535, xf.getUID());
191         assertEquals(513, xf.getGID());
192         assertTrue(Arrays.equals(EXPECTED_2, xf.getLocalFileDataData()));
193     }
194 
195 
parseReparse( final long uid, final long gid, final byte[] expected, final long expectedUID, final long expectedGID )196     private void parseReparse(
197             final long uid,
198             final long gid,
199             final byte[] expected,
200             final long expectedUID,
201             final long expectedGID
202     ) throws ZipException {
203 
204         // Initial local parse (init with garbage to avoid defaults causing test to pass).
205         xf.setUID(54321);
206         xf.setGID(12345);
207         xf.parseFromLocalFileData(expected, 0, expected.length);
208         assertEquals(expectedUID, xf.getUID());
209         assertEquals(expectedGID, xf.getGID());
210 
211         xf.setUID(uid);
212         xf.setGID(gid);
213         if (expected.length < 5) {
214             // We never emit zero-length entries.
215             assertEquals(5, xf.getLocalFileDataLength().getValue());
216         } else {
217             assertEquals(expected.length, xf.getLocalFileDataLength().getValue());
218         }
219         byte[] result = xf.getLocalFileDataData();
220         if (expected.length < 5) {
221             // We never emit zero-length entries.
222             assertTrue(Arrays.equals(new byte[]{1,1,0,1,0}, result));
223         } else {
224             assertTrue(Arrays.equals(expected, result));
225         }
226 
227 
228 
229         // And now we re-parse:
230         xf.parseFromLocalFileData(result, 0, result.length);
231 
232         // Did uid/gid change from re-parse?  They shouldn't!
233         assertEquals(expectedUID, xf.getUID());
234         assertEquals(expectedGID, xf.getGID());
235 
236         assertEquals(0, xf.getCentralDirectoryLength().getValue());
237         result = xf.getCentralDirectoryData();
238         assertArrayEquals(new byte[0], result);
239 
240         // And now we re-parse:
241         xf.parseFromCentralDirectoryData(result, 0, result.length);
242 
243         // Did uid/gid change from 2nd re-parse?  They shouldn't!
244         assertEquals(expectedUID, xf.getUID());
245         assertEquals(expectedGID, xf.getGID());
246     }
247 }
248