COMPRESS-321 X7875_NewUnix doesn't handle centra directory correctly git-svn-id: https://svn.apache.org/repos/asf/commons/proper/compress/trunk@1697106 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 55a9dc1..18c6cf8 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml
@@ -44,6 +44,10 @@ <body> <release version="1.11" date="not released, yet" description="Release 1.11"> + <action issue="COMPRESS-321" type="fix" date="2015-08-22"> + ArrayIndexOutOfBoundsException when InfoZIP type 7875 extra + fields are read from the central directory. + </action> </release> <release version="1.10" date="2015-08-18"
diff --git a/src/main/java/org/apache/commons/compress/archivers/zip/X7875_NewUnix.java b/src/main/java/org/apache/commons/compress/archivers/zip/X7875_NewUnix.java index 87d1e1d..e325b56 100644 --- a/src/main/java/org/apache/commons/compress/archivers/zip/X7875_NewUnix.java +++ b/src/main/java/org/apache/commons/compress/archivers/zip/X7875_NewUnix.java
@@ -32,6 +32,8 @@ * zip-3.0.tar.gz/proginfo/extrafld.txt * * <pre> + * Local-header version: + * * Value Size Description * ----- ---- ----------- * 0x7875 Short tag for this extra block type ("ux") @@ -41,11 +43,19 @@ * UID Variable UID for this entry (little endian) * GIDSize 1 byte Size of GID field * GID Variable GID for this entry (little endian) + * + * Central-header version: + * + * Value Size Description + * ----- ---- ----------- + * 0x7855 Short tag for this extra block type ("Ux") + * TSize Short total data size for this block (0) * </pre> * @since 1.5 */ public class X7875_NewUnix implements ZipExtraField, Cloneable, Serializable { private static final ZipShort HEADER_ID = new ZipShort(0x7875); + private static final ZipShort ZERO = new ZipShort(0); private static final BigInteger ONE_THOUSAND = BigInteger.valueOf(1000); private static final long serialVersionUID = 1L; @@ -134,7 +144,7 @@ * @return a <code>ZipShort</code> for the length of the data of this extra field */ public ZipShort getCentralDirectoryLength() { - return getLocalFileDataLength(); // No different than local version. + return ZERO; } /** @@ -181,7 +191,7 @@ * @return get the data */ public byte[] getCentralDirectoryData() { - return getLocalFileDataData(); + return new byte[0]; } /** @@ -210,14 +220,12 @@ } /** - * Doesn't do anything special since this class always uses the - * same data in central directory and local file data. + * Doesn't do anything since this class doesn't store anything + * inside the central directory. */ public void parseFromCentralDirectoryData( byte[] buffer, int offset, int length ) throws ZipException { - reset(); - parseFromLocalFileData(buffer, offset, length); } /**
diff --git a/src/test/java/org/apache/commons/compress/archivers/zip/X7875_NewUnixTest.java b/src/test/java/org/apache/commons/compress/archivers/zip/X7875_NewUnixTest.java index 97b87e4..03326f1 100644 --- a/src/test/java/org/apache/commons/compress/archivers/zip/X7875_NewUnixTest.java +++ b/src/test/java/org/apache/commons/compress/archivers/zip/X7875_NewUnixTest.java
@@ -27,6 +27,7 @@ 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; @@ -207,13 +208,6 @@ 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); if (expected.length < 5) { @@ -239,22 +233,9 @@ assertEquals(expectedUID, xf.getUID()); assertEquals(expectedGID, xf.getGID()); - // Do the same as above, but with Central Directory data: - xf.setUID(uid); - xf.setGID(gid); - if (expected.length < 5) { - // We never emit zero-length entries. - assertEquals(5, xf.getCentralDirectoryLength().getValue()); - } else { - assertEquals(expected.length, xf.getCentralDirectoryLength().getValue()); - } + assertEquals(0, xf.getCentralDirectoryLength().getValue()); result = xf.getCentralDirectoryData(); - 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)); - } + assertArrayEquals(new byte[0], result); // And now we re-parse: xf.parseFromCentralDirectoryData(result, 0, result.length);