| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.commons.compress.archivers.zip; |
| |
| import org.junit.Before; |
| import org.junit.Test; |
| |
| import java.io.File; |
| import java.util.Arrays; |
| import java.util.Enumeration; |
| import java.util.zip.ZipException; |
| |
| import static org.apache.commons.compress.AbstractTestCase.getFile; |
| import static org.junit.Assert.assertArrayEquals; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertTrue; |
| |
| public class X7875_NewUnixTest { |
| |
| private final static ZipShort X7875 = new ZipShort(0x7875); |
| |
| private X7875_NewUnix xf; |
| |
| @Before |
| public void before() { |
| xf = new X7875_NewUnix(); |
| } |
| |
| |
| @Test |
| public void testSampleFile() throws Exception { |
| final File archive = getFile("COMPRESS-211_uid_gid_zip_test.zip"); |
| ZipFile zf = null; |
| |
| try { |
| zf = new ZipFile(archive); |
| final Enumeration<ZipArchiveEntry> en = zf.getEntries(); |
| |
| // We expect EVERY entry of this zip file (dir & file) to |
| // contain extra field 0x7875. |
| while (en.hasMoreElements()) { |
| |
| final ZipArchiveEntry zae = en.nextElement(); |
| final String name = zae.getName(); |
| final X7875_NewUnix xf = (X7875_NewUnix) zae.getExtraField(X7875); |
| |
| // The directory entry in the test zip file is uid/gid 1000. |
| long expected = 1000; |
| if (name.contains("uid555_gid555")) { |
| expected = 555; |
| } else if (name.contains("uid5555_gid5555")) { |
| expected = 5555; |
| } else if (name.contains("uid55555_gid55555")) { |
| expected = 55555; |
| } else if (name.contains("uid555555_gid555555")) { |
| expected = 555555; |
| } else if (name.contains("min_unix")) { |
| expected = 0; |
| } else if (name.contains("max_unix")) { |
| // 2^32-2 was the biggest UID/GID I could create on my linux! |
| // (December 2012, linux kernel 3.4) |
| expected = 0x100000000L - 2; |
| } |
| assertEquals(expected, xf.getUID()); |
| assertEquals(expected, xf.getGID()); |
| } |
| } finally { |
| if (zf != null) { |
| zf.close(); |
| } |
| } |
| } |
| |
| @Test |
| public void testGetHeaderId() { |
| assertEquals(X7875, xf.getHeaderId()); |
| } |
| |
| @Test |
| public void testMisc() throws Exception { |
| assertFalse(xf.equals(new Object())); |
| assertTrue(xf.toString().startsWith("0x7875 Zip Extra Field")); |
| final Object o = xf.clone(); |
| assertEquals(o.hashCode(), xf.hashCode()); |
| assertTrue(xf.equals(o)); |
| xf.setUID(12345); |
| assertFalse(xf.equals(o)); |
| } |
| |
| @Test |
| public void testTrimLeadingZeroesForceMinLength4() { |
| final byte[] NULL = null; |
| final byte[] EMPTY = new byte[0]; |
| final byte[] ONE_ZERO = {0}; |
| final byte[] TWO_ZEROES = {0, 0}; |
| final byte[] FOUR_ZEROES = {0, 0, 0, 0}; |
| final byte[] SEQUENCE = {1, 2, 3}; |
| final byte[] SEQUENCE_LEADING_ZERO = {0, 1, 2, 3}; |
| final byte[] SEQUENCE_LEADING_ZEROES = {0, 0, 0, 0, 0, 0, 0, 1, 2, 3}; |
| final byte[] TRAILING_ZERO = {1, 2, 3, 0}; |
| final byte[] PADDING_ZERO = {0, 1, 2, 3, 0}; |
| final byte[] SEQUENCE6 = {1, 2, 3, 4, 5, 6}; |
| final byte[] SEQUENCE6_LEADING_ZERO = {0, 1, 2, 3, 4, 5, 6}; |
| |
| assertTrue(NULL == trimTest(NULL)); |
| assertTrue(Arrays.equals(ONE_ZERO, trimTest(EMPTY))); |
| assertTrue(Arrays.equals(ONE_ZERO, trimTest(ONE_ZERO))); |
| assertTrue(Arrays.equals(ONE_ZERO, trimTest(TWO_ZEROES))); |
| assertTrue(Arrays.equals(ONE_ZERO, trimTest(FOUR_ZEROES))); |
| assertTrue(Arrays.equals(SEQUENCE, trimTest(SEQUENCE))); |
| assertTrue(Arrays.equals(SEQUENCE, trimTest(SEQUENCE_LEADING_ZERO))); |
| assertTrue(Arrays.equals(SEQUENCE, trimTest(SEQUENCE_LEADING_ZEROES))); |
| assertTrue(Arrays.equals(TRAILING_ZERO, trimTest(TRAILING_ZERO))); |
| assertTrue(Arrays.equals(TRAILING_ZERO, trimTest(PADDING_ZERO))); |
| assertTrue(Arrays.equals(SEQUENCE6, trimTest(SEQUENCE6))); |
| assertTrue(Arrays.equals(SEQUENCE6, trimTest(SEQUENCE6_LEADING_ZERO))); |
| } |
| |
| private static byte[] trimTest(final byte[] b) { return X7875_NewUnix.trimLeadingZeroesForceMinLength(b); } |
| |
| @Test |
| public void testParseReparse() throws ZipException { |
| |
| // Version=1, Len=0, Len=0. |
| final byte[] ZERO_LEN = {1, 0, 0}; |
| |
| // Version=1, Len=1, zero, Len=1, zero. |
| final byte[] ZERO_UID_GID = {1, 1, 0, 1, 0}; |
| |
| // Version=1, Len=1, one, Len=1, one |
| final byte[] ONE_UID_GID = {1, 1, 1, 1, 1}; |
| |
| // Version=1, Len=2, one thousand, Len=2, one thousand |
| final byte[] ONE_THOUSAND_UID_GID = {1, 2, -24, 3, 2, -24, 3}; |
| |
| // (2^32 - 2). I guess they avoid (2^32 - 1) since it's identical to -1 in |
| // two's complement, and -1 often has a special meaning. |
| final byte[] UNIX_MAX_UID_GID = {1, 4, -2, -1, -1, -1, 4, -2, -1, -1, -1}; |
| |
| // Version=1, Len=5, 2^32, Len=5, 2^32 + 1 |
| // Esoteric test: can we handle 40 bit numbers? |
| final byte[] LENGTH_5 = {1, 5, 0, 0, 0, 0, 1, 5, 1, 0, 0, 0, 1}; |
| |
| // Version=1, Len=8, 2^63 - 2, Len=8, 2^63 - 1 |
| // Esoteric test: can we handle 64 bit numbers? |
| final byte[] LENGTH_8 = {1, 8, -2, -1, -1, -1, -1, -1, -1, 127, 8, -1, -1, -1, -1, -1, -1, -1, 127}; |
| |
| final long TWO_TO_32 = 0x100000000L; |
| final long MAX = TWO_TO_32 - 2; |
| |
| parseReparse(0, 0, ZERO_LEN, 0, 0); |
| parseReparse(0, 0, ZERO_UID_GID, 0, 0); |
| parseReparse(1, 1, ONE_UID_GID, 1, 1); |
| parseReparse(1000, 1000, ONE_THOUSAND_UID_GID, 1000, 1000); |
| parseReparse(MAX, MAX, UNIX_MAX_UID_GID, MAX, MAX); |
| parseReparse(-2, -2, UNIX_MAX_UID_GID, MAX, MAX); |
| parseReparse(TWO_TO_32, TWO_TO_32 + 1, LENGTH_5, TWO_TO_32, TWO_TO_32 + 1); |
| parseReparse(Long.MAX_VALUE - 1, Long.MAX_VALUE, LENGTH_8, Long.MAX_VALUE - 1, Long.MAX_VALUE); |
| |
| // We never emit this, but we should be able to parse it: |
| final byte[] SPURIOUS_ZEROES_1 = {1, 4, -1, 0, 0, 0, 4, -128, 0, 0, 0}; |
| final byte[] EXPECTED_1 = {1, 1, -1, 1, -128}; |
| xf.parseFromLocalFileData(SPURIOUS_ZEROES_1, 0, SPURIOUS_ZEROES_1.length); |
| |
| assertEquals(255, xf.getUID()); |
| assertEquals(128, xf.getGID()); |
| assertTrue(Arrays.equals(EXPECTED_1, xf.getLocalFileDataData())); |
| |
| final byte[] SPURIOUS_ZEROES_2 = {1, 4, -1, -1, 0, 0, 4, 1, 2, 0, 0}; |
| final byte[] EXPECTED_2 = {1, 2, -1, -1, 2, 1, 2}; |
| xf.parseFromLocalFileData(SPURIOUS_ZEROES_2, 0, SPURIOUS_ZEROES_2.length); |
| |
| assertEquals(65535, xf.getUID()); |
| assertEquals(513, xf.getGID()); |
| assertTrue(Arrays.equals(EXPECTED_2, xf.getLocalFileDataData())); |
| } |
| |
| |
| private void parseReparse( |
| final long uid, |
| final long gid, |
| final byte[] expected, |
| final long expectedUID, |
| final long expectedGID |
| ) throws ZipException { |
| |
| // Initial local parse (init with garbage to avoid defaults causing test to pass). |
| xf.setUID(54321); |
| xf.setGID(12345); |
| xf.parseFromLocalFileData(expected, 0, expected.length); |
| assertEquals(expectedUID, xf.getUID()); |
| assertEquals(expectedGID, xf.getGID()); |
| |
| xf.setUID(uid); |
| xf.setGID(gid); |
| if (expected.length < 5) { |
| // We never emit zero-length entries. |
| assertEquals(5, xf.getLocalFileDataLength().getValue()); |
| } else { |
| assertEquals(expected.length, xf.getLocalFileDataLength().getValue()); |
| } |
| byte[] result = xf.getLocalFileDataData(); |
| if (expected.length < 5) { |
| // We never emit zero-length entries. |
| assertTrue(Arrays.equals(new byte[]{1,1,0,1,0}, result)); |
| } else { |
| assertTrue(Arrays.equals(expected, result)); |
| } |
| |
| |
| |
| // And now we re-parse: |
| xf.parseFromLocalFileData(result, 0, result.length); |
| |
| // Did uid/gid change from re-parse? They shouldn't! |
| assertEquals(expectedUID, xf.getUID()); |
| assertEquals(expectedGID, xf.getGID()); |
| |
| assertEquals(0, xf.getCentralDirectoryLength().getValue()); |
| result = xf.getCentralDirectoryData(); |
| assertArrayEquals(new byte[0], result); |
| |
| // And now we re-parse: |
| xf.parseFromCentralDirectoryData(result, 0, result.length); |
| |
| // Did uid/gid change from 2nd re-parse? They shouldn't! |
| assertEquals(expectedUID, xf.getUID()); |
| assertEquals(expectedGID, xf.getGID()); |
| } |
| } |