Author: bodewig
Date: Thu Feb 19 17:19:23 2009
New Revision: 745930
URL: http://svn.apache.org/viewvc?rev=745930&view=rev
Log:
Support more modern encoding flag where archives signal filenames as UTF-8.
Based on submissions by Wolfgang Glas to commons-compress and TAMURA Kent to
Ant. PR 45548.
Modified:
ant/core/trunk/CONTRIBUTORS
ant/core/trunk/WHATSNEW
ant/core/trunk/contributors.xml
ant/core/trunk/src/main/org/apache/tools/zip/ZipFile.java (contents,
props changed)
ant/core/trunk/src/main/org/apache/tools/zip/ZipOutputStream.java
(contents, props changed)
Modified: ant/core/trunk/CONTRIBUTORS
URL:
http://svn.apache.org/viewvc/ant/core/trunk/CONTRIBUTORS?rev=745930&r1=745929&r2=745930&view=diff
==============================================================================
Binary files - no diff available.
Modified: ant/core/trunk/WHATSNEW
URL:
http://svn.apache.org/viewvc/ant/core/trunk/WHATSNEW?rev=745930&r1=745929&r2=745930&view=diff
==============================================================================
--- ant/core/trunk/WHATSNEW (original)
+++ ant/core/trunk/WHATSNEW Thu Feb 19 17:19:23 2009
@@ -351,6 +351,11 @@
* The zip package now supports the extra fields invented by InfoZIP
in order to store Unicode file names and comments.
+ * The zip package detects the encoding bit set by more modern
+ archivers when they write UTF-8 filenames and optionally sets it
+ when writing zips or jars.
+ Bugzilla Report 45548
+
Other changes:
--------------
* A HostInfo task was added performing information on hosts, including info
on
Modified: ant/core/trunk/contributors.xml
URL:
http://svn.apache.org/viewvc/ant/core/trunk/contributors.xml?rev=745930&r1=745929&r2=745930&view=diff
==============================================================================
--- ant/core/trunk/contributors.xml (original)
+++ ant/core/trunk/contributors.xml Thu Feb 19 17:19:23 2009
@@ -1147,6 +1147,10 @@
<last>Okamoto</last>
</name>
<name>
+ <first>TAMURA</first>
+ <last>Kent</last>
+ </name>
+ <name>
<first>Taoufik</first>
<last>Romdhane</last>
</name>
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=745930&r1=745929&r2=745930&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 Thu Feb 19
17:19:23 2009
@@ -294,7 +294,15 @@
off += SHORT;
ze.setPlatform((versionMadeBy >> BYTE_SHIFT) & NIBLET_MASK);
- off += WORD; // skip version info and general purpose byte
+ off += SHORT; // skip version info
+
+ final int generalPurposeFlag = ZipShort.getValue(cfh, off);
+ final String entryEncoding =
+ (generalPurposeFlag & ZipOutputStream.EFS_FLAG) != 0
+ ? ZipOutputStream.UTF8
+ : encoding;
+
+ off += SHORT;
ze.setMethod(ZipShort.getValue(cfh, off));
off += SHORT;
@@ -334,8 +342,7 @@
byte[] fileName = new byte[fileNameLen];
archive.readFully(fileName);
- ze.setName(getString(fileName));
-
+ ze.setName(getString(fileName, entryEncoding));
// LFH offset,
OffsetEntry offset = new OffsetEntry();
@@ -357,7 +364,7 @@
byte[] comment = new byte[commentLen];
archive.readFully(comment);
- ze.setComment(getString(comment));
+ ze.setComment(getString(comment, entryEncoding));
archive.readFully(signatureBytes);
sig = ZipLong.getValue(signatureBytes);
@@ -527,11 +534,24 @@
* @throws ZipException if the encoding cannot be recognized.
*/
protected String getString(byte[] bytes) throws ZipException {
- if (encoding == null) {
+ return getString(bytes, encoding);
+ }
+
+ /**
+ * Retrieve a String from the given bytes using the encoding set
+ * for this ZipFile.
+ *
+ * @param bytes the byte array to transform
+ * @return String obtained by using the given encoding
+ * @throws ZipException if the encoding cannot be recognized.
+ */
+ protected String getString(byte[] bytes, String enc)
+ throws ZipException {
+ if (enc == null) {
return new String(bytes);
} else {
try {
- return new String(bytes, encoding);
+ return new String(bytes, enc);
} catch (UnsupportedEncodingException uee) {
throw new ZipException(uee.getMessage());
}
Propchange: ant/core/trunk/src/main/org/apache/tools/zip/ZipFile.java
------------------------------------------------------------------------------
--- svn:mergeinfo (added)
+++ svn:mergeinfo Thu Feb 19 17:19:23 2009
@@ -0,0 +1 @@
+/commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java:745920
Modified: ant/core/trunk/src/main/org/apache/tools/zip/ZipOutputStream.java
URL:
http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/zip/ZipOutputStream.java?rev=745930&r1=745929&r2=745930&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/zip/ZipOutputStream.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/zip/ZipOutputStream.java Thu Feb
19 17:19:23 2009
@@ -92,6 +92,17 @@
public static final int STORED = java.util.zip.ZipEntry.STORED;
/**
+ * name of the encoding UTF-8
+ */
+ static final String UTF8 = "UTF8";
+
+ /**
+ * General purpose flag, which indicates that filenames are
+ * written in utf-8.
+ */
+ public static final int EFS_FLAG = 1 << 11;
+
+ /**
* Current entry.
*
* @since 1.1
@@ -245,6 +256,11 @@
private RandomAccessFile raf = null;
/**
+ * whether to use the EFS flag when writing UTF-8 filenames or not.
+ */
+ private boolean useEFS = true;
+
+ /**
* Creates a new ZIP OutputStream filtering the underlying stream.
* @param out the outputstream to zip
* @since 1.1
@@ -302,8 +318,9 @@
* @param encoding the encoding value
* @since 1.3
*/
- public void setEncoding(String encoding) {
+ public void setEncoding(final String encoding) {
this.encoding = encoding;
+ useEFS &= isUTF8(encoding);
}
/**
@@ -318,6 +335,15 @@
}
/**
+ * Whether to set the EFS flag if the file name encoding is UTF-8.
+ *
+ * <p>Defaults to true.</p>
+ */
+ public void setUseEFS(boolean b) {
+ useEFS = b && isUTF8(encoding);
+ }
+
+ /**
* Finishs writing the contents and closes this as well as the
* underlying stream.
*
@@ -620,21 +646,7 @@
//store method in local variable to prevent multiple method calls
final int zipMethod = ze.getMethod();
- // version needed to extract
- // general purpose bit flag
- // CheckStyle:MagicNumber OFF
- if (zipMethod == DEFLATED && raf == null) {
- // requires version 2 as we are going to store length info
- // in the data descriptor
- writeOut(ZipShort.getBytes(20));
-
- // bit3 set to signal, we use a data descriptor
- writeOut(ZipShort.getBytes(8));
- } else {
- writeOut(ZipShort.getBytes(10));
- writeOut(ZERO);
- }
- // CheckStyle:MagicNumber ON
+ writeVersionNeededToExtractAndGeneralPurposeBits(zipMethod);
written += WORD;
// compression method
@@ -719,24 +731,12 @@
writeOut(ZipShort.getBytes((ze.getPlatform() << 8) | 20));
written += SHORT;
- // version needed to extract
- // general purpose bit flag
- if (ze.getMethod() == DEFLATED && raf == null) {
- // requires version 2 as we are going to store length info
- // in the data descriptor
- writeOut(ZipShort.getBytes(20));
-
- // bit3 set to signal, we use a data descriptor
- writeOut(ZipShort.getBytes(8));
- } else {
- writeOut(ZipShort.getBytes(10));
- writeOut(ZERO);
- }
- // CheckStyle:MagicNumber ON
+ final int zipMethod = ze.getMethod();
+ writeVersionNeededToExtractAndGeneralPurposeBits(zipMethod);
written += WORD;
// compression method
- writeOut(ZipShort.getBytes(ze.getMethod()));
+ writeOut(ZipShort.getBytes(zipMethod));
written += SHORT;
// last mod. time and date
@@ -887,10 +887,16 @@
return name.getBytes();
} else {
try {
+ return ZipEncodingHelper.encodeName(name, encoding);
+ } catch (java.nio.charset.UnsupportedCharsetException ex) {
+ // Java 1.4's NIO doesn't recognize a few names that
+ // String.getBytes does
+ try {
return name.getBytes(encoding);
} catch (UnsupportedEncodingException uee) {
throw new ZipException(uee.getMessage());
}
+ }
}
}
@@ -944,4 +950,38 @@
}
}
+ /**
+ * Whether a given encoding - or the platform's default encoding
+ * if the parameter is null - is UTF-8.
+ */
+ static boolean isUTF8(String encoding) {
+ if (encoding == null) {
+ // check platform's default encoding
+ encoding = System.getProperty("file.encoding");
+ }
+ return UTF8.equalsIgnoreCase(encoding)
+ || "utf-8".equalsIgnoreCase(encoding);
+ }
+
+ private void writeVersionNeededToExtractAndGeneralPurposeBits(final int
+ zipMethod)
+ throws IOException {
+
+ // CheckStyle:MagicNumber OFF
+ int versionNeededToExtract = 10;
+ int generalPurposeFlag = useEFS ? EFS_FLAG : 0;
+ if (zipMethod == DEFLATED && raf == null) {
+ // requires version 2 as we are going to store length info
+ // in the data descriptor
+ versionNeededToExtract = 20;
+ // bit3 set to signal, we use a data descriptor
+ generalPurposeFlag |= 8;
+ }
+ // CheckStyle:MagicNumber ON
+
+ // version needed to extract
+ writeOut(ZipShort.getBytes(versionNeededToExtract));
+ // general purpose bit flag
+ writeOut(ZipShort.getBytes(generalPurposeFlag));
+ }
}
Propchange: ant/core/trunk/src/main/org/apache/tools/zip/ZipOutputStream.java
------------------------------------------------------------------------------
--- svn:mergeinfo (added)
+++ svn:mergeinfo Thu Feb 19 17:19:23 2009
@@ -0,0 +1 @@
+/commons/sandbox/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java:745920