You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@ant.apache.org by bo...@apache.org on 2009/03/03 14:18:46 UTC
svn commit: r749610 - in /ant/core/trunk/src: main/org/apache/tools/zip/
tests/junit/org/apache/tools/zip/
Author: bodewig
Date: Tue Mar 3 13:18:45 2009
New Revision: 749610
URL: http://svn.apache.org/viewvc?rev=749610&view=rev
Log:
Parse central directory part of ZIP extra fields. PR 46637
Added:
ant/core/trunk/src/main/org/apache/tools/zip/CentralDirectoryParsingZipExtraField.java (with props)
Modified:
ant/core/trunk/src/main/org/apache/tools/zip/ExtraFieldUtils.java (contents, props changed)
ant/core/trunk/src/main/org/apache/tools/zip/UnrecognizedExtraField.java (contents, props changed)
ant/core/trunk/src/main/org/apache/tools/zip/ZipEntry.java (contents, props changed)
ant/core/trunk/src/main/org/apache/tools/zip/ZipFile.java (contents, props changed)
ant/core/trunk/src/tests/junit/org/apache/tools/zip/ZipEntryTest.java (contents, props changed)
Added: ant/core/trunk/src/main/org/apache/tools/zip/CentralDirectoryParsingZipExtraField.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/zip/CentralDirectoryParsingZipExtraField.java?rev=749610&view=auto
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/zip/CentralDirectoryParsingZipExtraField.java (added)
+++ ant/core/trunk/src/main/org/apache/tools/zip/CentralDirectoryParsingZipExtraField.java Tue Mar 3 13:18:45 2009
@@ -0,0 +1,40 @@
+/*
+ * 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.tools.zip;
+
+import java.util.zip.ZipException;
+
+/**
+ * {@link ZipExtraField ZipExtraField} that knows how to parse central
+ * directory data.
+ *
+ * @since Ant 1.8.0
+ */
+public interface CentralDirectoryParsingZipExtraField extends ZipExtraField {
+ /**
+ * Populate data from this array as if it was in central directory data.
+ * @param data an array of bytes
+ * @param offset the start offset
+ * @param length the number of bytes in the array from offset
+ *
+ * @throws ZipException on error
+ */
+ void parseFromCentralDirectoryData(byte[] data, int offset, int length)
+ throws ZipException;
+}
Propchange: ant/core/trunk/src/main/org/apache/tools/zip/CentralDirectoryParsingZipExtraField.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: ant/core/trunk/src/main/org/apache/tools/zip/ExtraFieldUtils.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/zip/ExtraFieldUtils.java?rev=749610&r1=749609&r2=749610&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/zip/ExtraFieldUtils.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/zip/ExtraFieldUtils.java Tue Mar 3 13:18:45 2009
@@ -92,13 +92,27 @@
/**
* Split the array into ExtraFields and populate them with the
- * give data.
+ * given data as local file data.
+ * @param data an array of bytes as it appears in local file data
+ * @return an array of ExtraFields
+ * @throws ZipException on error
+ */
+ public static ZipExtraField[] parse(byte[] data) throws ZipException {
+ return parse(data, true);
+ }
+
+ /**
+ * Split the array into ExtraFields and populate them with the
+ * given data.
* @param data an array of bytes
+ * @param local whether data originates from the local file data
+ * or the central directory
* @return an array of ExtraFields
* @since 1.1
* @throws ZipException on error
*/
- public static ZipExtraField[] parse(byte[] data) throws ZipException {
+ public static ZipExtraField[] parse(byte[] data, boolean local)
+ throws ZipException {
List v = new ArrayList();
int start = 0;
while (start <= data.length - WORD) {
@@ -110,7 +124,14 @@
}
try {
ZipExtraField ze = createExtraField(headerId);
- ze.parseFromLocalFileData(data, start + WORD, length);
+ if (local
+ || !(ze instanceof CentralDirectoryParsingZipExtraField)) {
+ ze.parseFromLocalFileData(data, start + WORD, length);
+ } else {
+ ((CentralDirectoryParsingZipExtraField) ze)
+ .parseFromCentralDirectoryData(data, start + WORD,
+ length);
+ }
v.add(ze);
} catch (InstantiationException ie) {
throw new ZipException(ie.getMessage());
Propchange: ant/core/trunk/src/main/org/apache/tools/zip/ExtraFieldUtils.java
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Mar 3 13:18:45 2009
@@ -1 +1 @@
-/commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ExtraFieldUtils.java:745528,746933,748133,749524
+/commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ExtraFieldUtils.java:745528,746933,748133,749524,749603
Modified: ant/core/trunk/src/main/org/apache/tools/zip/UnrecognizedExtraField.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/zip/UnrecognizedExtraField.java?rev=749610&r1=749609&r2=749610&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/zip/UnrecognizedExtraField.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/zip/UnrecognizedExtraField.java Tue Mar 3 13:18:45 2009
@@ -26,7 +26,8 @@
* identical - unless told the opposite.</p>
*
*/
-public class UnrecognizedExtraField implements ZipExtraField {
+public class UnrecognizedExtraField
+ implements CentralDirectoryParsingZipExtraField {
/**
* The Header-ID.
@@ -135,6 +136,22 @@
setLocalFileDataData(tmp);
}
+ /**
+ * @param data the array of bytes.
+ * @param offset the source location in the data array.
+ * @param length the number of bytes to use in the data array.
+ * @see ZipExtraField#parseFromCentralDirectoryData(byte[], int, int)
+ */
+ public void parseFromCentralDirectoryData(byte[] data, int offset,
+ int length) {
+ byte[] tmp = new byte[length];
+ System.arraycopy(data, offset, tmp, 0, length);
+ setCentralDirectoryData(tmp);
+ if (localData == null) {
+ setLocalFileDataData(tmp);
+ }
+ }
+
private static byte[] copy(byte[] from) {
if (from != null) {
byte[] to = new byte[from.length];
Propchange: ant/core/trunk/src/main/org/apache/tools/zip/UnrecognizedExtraField.java
------------------------------------------------------------------------------
--- svn:mergeinfo (added)
+++ svn:mergeinfo Tue Mar 3 13:18:45 2009
@@ -0,0 +1 @@
+/commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/UnrecognizedExtraField.java:746933,748133,749603
Modified: ant/core/trunk/src/main/org/apache/tools/zip/ZipEntry.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/zip/ZipEntry.java?rev=749610&r1=749609&r2=749610&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/zip/ZipEntry.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/zip/ZipEntry.java Tue Mar 3 13:18:45 2009
@@ -284,7 +284,8 @@
*/
public void setExtra(byte[] extra) throws RuntimeException {
try {
- setExtraFields(ExtraFieldUtils.parse(extra));
+ ZipExtraField[] local = ExtraFieldUtils.parse(extra, true);
+ mergeExtraFields(local, true);
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
@@ -303,6 +304,18 @@
}
/**
+ * Sets the central directory part of extra fields.
+ */
+ public void setCentralDirectoryExtra(byte[] b) {
+ try {
+ ZipExtraField[] central = ExtraFieldUtils.parse(b, false);
+ mergeExtraFields(central, false);
+ } catch (Exception e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ }
+
+ /**
* Retrieves the extra data for the local file data.
* @return the extra data for local file
* @since 1.1
@@ -386,4 +399,37 @@
return (this == o);
}
+ /**
+ * If there are no extra fields, use the given fields as new extra
+ * data - otherwise merge the fields assuming the existing fields
+ * and the new fields stem from different locations inside the
+ * archive.
+ * @param f the extra fields to merge
+ * @param local whether the new fields originate from local data
+ */
+ private void mergeExtraFields(ZipExtraField[] f, boolean local)
+ throws ZipException {
+ if (extraFields == null) {
+ setExtraFields(f);
+ } else {
+ for (int i = 0; i < f.length; i++) {
+ ZipExtraField existing = getExtraField(f[i].getHeaderId());
+ if (existing == null) {
+ addExtraField(f[i]);
+ } else {
+ if (local
+ || !(existing
+ instanceof CentralDirectoryParsingZipExtraField)) {
+ byte[] b = f[i].getLocalFileDataData();
+ existing.parseFromLocalFileData(b, 0, b.length);
+ } else {
+ byte[] b = f[i].getCentralDirectoryData();
+ ((CentralDirectoryParsingZipExtraField) existing)
+ .parseFromCentralDirectoryData(b, 0, b.length);
+ }
+ }
+ }
+ setExtra();
+ }
+ }
}
Propchange: ant/core/trunk/src/main/org/apache/tools/zip/ZipEntry.java
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Mar 3 13:18:45 2009
@@ -1,2 +1,2 @@
-/commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntry.java:747850
+/commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntry.java:747850,749603
/commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipEntry.java:746933,748133,749524
Modified: ant/core/trunk/src/main/org/apache/tools/zip/ZipFile.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/zip/ZipFile.java?rev=749610&r1=749609&r2=749610&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/zip/ZipFile.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/zip/ZipFile.java Tue Mar 3 13:18:45 2009
@@ -389,15 +389,9 @@
nameMap.put(ze.getName(), ze);
- int lenToSkip = extraLen;
- while (lenToSkip > 0) {
- int skipped = archive.skipBytes(lenToSkip);
- if (skipped <= 0) {
- throw new RuntimeException("failed to skip extra data in"
- + " central directory");
- }
- lenToSkip -= skipped;
- }
+ byte[] cdExtraData = new byte[extraLen];
+ archive.readFully(cdExtraData);
+ ze.setCentralDirectoryExtra(cdExtraData);
byte[] comment = new byte[commentLen];
archive.readFully(comment);
Propchange: ant/core/trunk/src/main/org/apache/tools/zip/ZipFile.java
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Mar 3 13:18:45 2009
@@ -1 +1 @@
-/commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java:745920,746933,748133,748556,749342-749344,749524
+/commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java:745920,746933,748133,748556,749342-749344,749524,749603
Modified: ant/core/trunk/src/tests/junit/org/apache/tools/zip/ZipEntryTest.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/tests/junit/org/apache/tools/zip/ZipEntryTest.java?rev=749610&r1=749609&r2=749610&view=diff
==============================================================================
--- ant/core/trunk/src/tests/junit/org/apache/tools/zip/ZipEntryTest.java (original)
+++ ant/core/trunk/src/tests/junit/org/apache/tools/zip/ZipEntryTest.java Tue Mar 3 13:18:45 2009
@@ -32,8 +32,6 @@
/**
* test handling of extra fields
- *
- * @since 1.1
*/
public void testExtraFields() {
AsiExtraField a = new AsiExtraField();
@@ -86,9 +84,51 @@
}
/**
+ * test handling of extra fields via central directory
+ */
+ public void testExtraFieldMerging() {
+ AsiExtraField a = new AsiExtraField();
+ a.setDirectory(true);
+ a.setMode(0755);
+ UnrecognizedExtraField u = new UnrecognizedExtraField();
+ u.setHeaderId(new ZipShort(1));
+ u.setLocalFileDataData(new byte[0]);
+
+ ZipEntry ze = new ZipEntry("test/");
+ ze.setExtraFields(new ZipExtraField[] {a, u});
+
+ // merge
+ // Header-ID 1 + length 1 + one byte of data
+ ze.setCentralDirectoryExtra(new byte[] {1, 0, 1, 0, 127});
+
+ ZipExtraField[] result = ze.getExtraFields();
+ assertEquals("first pass", 2, result.length);
+ assertSame(a, result[0]);
+ assertEquals(new ZipShort(1), result[1].getHeaderId());
+ assertEquals(new ZipShort(0), result[1].getLocalFileDataLength());
+ assertEquals(new ZipShort(1), result[1].getCentralDirectoryLength());
+
+ // add new
+ // Header-ID 2 + length 0
+ ze.setCentralDirectoryExtra(new byte[] {2, 0, 0, 0});
+
+ result = ze.getExtraFields();
+ assertEquals("second pass", 3, result.length);
+
+ // merge
+ // Header-ID 2 + length 1 + one byte of data
+ ze.setExtra(new byte[] {2, 0, 1, 0, 127});
+
+ result = ze.getExtraFields();
+ assertEquals("third pass", 3, result.length);
+ assertSame(a, result[0]);
+ assertEquals(new ZipShort(2), result[2].getHeaderId());
+ assertEquals(new ZipShort(1), result[2].getLocalFileDataLength());
+ assertEquals(new ZipShort(0), result[2].getCentralDirectoryLength());
+ }
+
+ /**
* test handling of extra fields
- *
- * @since 1.1
*/
public void testAddAsFirstExtraField() {
AsiExtraField a = new AsiExtraField();
Propchange: ant/core/trunk/src/tests/junit/org/apache/tools/zip/ZipEntryTest.java
------------------------------------------------------------------------------
--- svn:mergeinfo (added)
+++ svn:mergeinfo Tue Mar 3 13:18:45 2009
@@ -0,0 +1 @@
+/commons/sandbox/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntryTest.java:749603