Author: julius Date: Tue Jan 8 21:46:10 2013 New Revision: 1430557 URL: http://svn.apache.org/viewvc?rev=1430557&view=rev Log: COMPRESS-211 - handle zip extra field 0x7875. I improved code coverage a little for the unit tests.
Modified: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/X7875_NewUnix.java commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/X7875_NewUnixTest.java Modified: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/X7875_NewUnix.java URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/X7875_NewUnix.java?rev=1430557&r1=1430556&r2=1430557&view=diff ============================================================================== --- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/X7875_NewUnix.java (original) +++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/X7875_NewUnix.java Tue Jan 8 21:46:10 2013 @@ -53,6 +53,8 @@ public class X7875_NewUnix implements Zi // BigInteger helps us with little-endian / big-endian conversions. // (thanks to BigInteger.toByteArray() and a reverse() method we created). // Also, the spec theoretically allows UID/GID up to 255 bytes long! + // + // NOTE: equals() and hashCode() currently assume these can never be null. private BigInteger uid; private BigInteger gid; @@ -247,12 +249,8 @@ public class X7875_NewUnix implements Zi public boolean equals(Object o) { if (o instanceof X7875_NewUnix) { X7875_NewUnix xf = (X7875_NewUnix) o; - if (version == xf.version) { - // The BigInteger==BigInteger clause handles the case where both are null. - if (uid == xf.uid || (uid != null && uid.equals(xf.uid))) { - return gid == xf.gid || (gid != null && gid.equals(xf.gid)); - } - } + // We assume uid and gid can never be null. + return version == xf.version && uid.equals(xf.uid) && gid.equals(xf.gid); } return false; } @@ -260,12 +258,11 @@ public class X7875_NewUnix implements Zi @Override public int hashCode() { int hc = (-1234567 * version); - if (uid != null) { - hc ^= uid.hashCode(); - } - if (gid != null) { - hc ^= gid.hashCode(); - } + // Since most UID's and GID's are below 65,536, this is (hopefully!) + // a nice way to make sure typical UID and GID values impact the hash + // as much as possible. + hc ^= Integer.rotateLeft(uid.hashCode(), 16); + hc ^= gid.hashCode(); return hc; } Modified: commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/X7875_NewUnixTest.java URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/X7875_NewUnixTest.java?rev=1430557&r1=1430556&r2=1430557&view=diff ============================================================================== --- commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/X7875_NewUnixTest.java (original) +++ commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/X7875_NewUnixTest.java Tue Jan 8 21:46:10 2013 @@ -29,6 +29,7 @@ import java.util.Enumeration; import java.util.zip.ZipException; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; public class X7875_NewUnixTest { @@ -95,10 +96,13 @@ public class X7875_NewUnixTest { @Test public void testMisc() throws Exception { + assertFalse(xf.equals(new Object())); assertTrue(xf.toString().startsWith("0x7875 Zip Extra Field")); Object o = xf.clone(); assertEquals(o.hashCode(), xf.hashCode()); assertTrue(xf.equals(o)); + xf.setUID(12345); + assertFalse(xf.equals(o)); } @Test @@ -135,6 +139,9 @@ public class X7875_NewUnixTest { @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}; @@ -159,6 +166,7 @@ public class X7875_NewUnixTest { 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); @@ -193,11 +201,38 @@ public class X7875_NewUnixTest { 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()); + + // Initial central parse (init with garbage to avoid defaults causing test to pass). + xf.setUID(54321); + xf.setGID(12345); + xf.parseFromCentralDirectoryData(expected, 0, expected.length); + assertEquals(expectedUID, xf.getUID()); + assertEquals(expectedGID, xf.getGID()); + xf.setUID(uid); xf.setGID(gid); - assertEquals(expected.length, xf.getLocalFileDataLength().getValue()); + 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(); - assertTrue(Arrays.equals(expected, result)); + 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); @@ -209,9 +244,19 @@ public class X7875_NewUnixTest { // Do the same as above, but with Central Directory data: xf.setUID(uid); xf.setGID(gid); - assertEquals(expected.length, xf.getCentralDirectoryLength().getValue()); + if (expected.length < 5) { + // We never emit zero-length entries. + assertEquals(5, xf.getCentralDirectoryLength().getValue()); + } else { + assertEquals(expected.length, xf.getCentralDirectoryLength().getValue()); + } result = xf.getCentralDirectoryData(); - assertTrue(Arrays.equals(expected, result)); + 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.parseFromCentralDirectoryData(result, 0, result.length);