Author: bodewig Date: Mon Dec 5 15:39:52 2011 New Revision: 1210501 URL: http://svn.apache.org/viewvc?rev=1210501&view=rev Log: ZipFile doesn't work properly for unicode extra fields. Based on patch by Volker Leidl. COMPRESS-164
Modified: commons/proper/compress/trunk/src/changes/changes.xml commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/UTF8ZipFilesTest.java Modified: commons/proper/compress/trunk/src/changes/changes.xml URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/changes/changes.xml?rev=1210501&r1=1210500&r2=1210501&view=diff ============================================================================== --- commons/proper/compress/trunk/src/changes/changes.xml (original) +++ commons/proper/compress/trunk/src/changes/changes.xml Mon Dec 5 15:39:52 2011 @@ -61,6 +61,10 @@ The <action> type attribute can be add,u The tar package can now read archives that use GNU extensions for files that are longer than 8 GByte. </action> + <action issue="COMPRESS-164" type="fix" date="2011-12-05"> + ZipFile didn't work properly for archives using unicode extra + fields rather than UTF-8 filenames and the EFS-Flag. + </action> </release> <release version="1.3" date="2011-11-01" description="Release 1.3 - API compatible to 1.2 but requires Java5 at runtime"> Modified: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java?rev=1210501&r1=1210500&r2=1210501&view=diff ============================================================================== --- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java (original) +++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java Mon Dec 5 15:39:52 2011 @@ -801,8 +801,15 @@ public class ZipFile { private void resolveLocalFileHeaderData(Map<ZipArchiveEntry, NameAndComment> entriesWithoutUTF8Flag) throws IOException { - for (ZipArchiveEntry ze : entries.keySet()) { - OffsetEntry offsetEntry = entries.get(ze); + // changing the name of a ZipArchiveEntry is going to change + // the hashcode - see COMPRESS-164 + // Map needs to be reconstructed in order to keep central + // directory order + Map<ZipArchiveEntry, OffsetEntry> origMap = + new LinkedHashMap<ZipArchiveEntry, OffsetEntry>(entries); + entries.clear(); + for (ZipArchiveEntry ze : origMap.keySet()) { + OffsetEntry offsetEntry = origMap.get(ze); long offset = offsetEntry.headerOffset; archive.seek(offset + LFH_OFFSET_FOR_FILENAME_LENGTH); byte[] b = new byte[SHORT]; @@ -835,6 +842,7 @@ public class ZipFile { nameMap.put(ze.getName(), ze); } } + entries.put(ze, offsetEntry); } } Modified: commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/UTF8ZipFilesTest.java URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/UTF8ZipFilesTest.java?rev=1210501&r1=1210500&r2=1210501&view=diff ============================================================================== --- commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/UTF8ZipFilesTest.java (original) +++ commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/UTF8ZipFilesTest.java Mon Dec 5 15:39:52 2011 @@ -21,6 +21,7 @@ package org.apache.commons.compress.arch import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; @@ -128,14 +129,26 @@ public class UTF8ZipFilesTest extends Ab ZipFile zf = null; try { zf = new ZipFile(archive, null, true); - assertNotNull(zf.getEntry(ASCII_TXT)); - assertNotNull(zf.getEntry(EURO_FOR_DOLLAR_TXT)); - assertNotNull(zf.getEntry(OIL_BARREL_TXT)); + assertCanRead(zf, ASCII_TXT); + assertCanRead(zf, EURO_FOR_DOLLAR_TXT); + assertCanRead(zf, OIL_BARREL_TXT); } finally { ZipFile.closeQuietly(zf); } } + private void assertCanRead(ZipFile zf, String fileName) throws IOException { + ZipArchiveEntry entry = zf.getEntry(fileName); + assertNotNull("Entry doesn't exist", entry); + InputStream is = zf.getInputStream(entry); + assertNotNull("InputStream is null", is); + try { + is.read(); + } finally { + is.close(); + } + } + public void testReadWinZipArchiveForStream() throws IOException, URISyntaxException { URL zip = getClass().getResource("/utf8-winzip-test.zip");