This is a workaround for Bugzilla Issue 57822 https://bz.apache.org/bugzilla/show_bug.cgi?id=57822master
| @@ -84,6 +84,16 @@ Fixed bugs: | |||||
| * TarEntry's constructor with a File and a String arg didn't | * TarEntry's constructor with a File and a String arg didn't | ||||
| normalize the name. | normalize the name. | ||||
| * Between 1.8.4 and 1.9.5 TarArchiveInputStream started to parse file | |||||
| names using the platform's default encoding rather than as ASCII. | |||||
| This has been a breaking change that has never been marked as such | |||||
| (in fact it went unnoticed). In order to allow <untar> and | |||||
| <tarfileset> to work on platforms who's encoding doesn't match the | |||||
| encoding of file names inside the archive, the both now support | |||||
| encoding attributes. | |||||
| The attribute has also been added to <tar> for symmetry. | |||||
| Bugzilla Report 57822 | |||||
| Other changes: | Other changes: | ||||
| -------------- | -------------- | ||||
| @@ -146,6 +146,15 @@ or "bzip2".</p> | |||||
| "none".</td> | "none".</td> | ||||
| <td valign="top" align="center">No</td> | <td valign="top" align="center">No</td> | ||||
| </tr> | </tr> | ||||
| <tr> | |||||
| <td valign="top">encoding</td> | |||||
| <td valign="top">The character encoding to use for filenames | |||||
| inside the tar file. For a list of possible values see the <a | |||||
| href="http://docs.oracle.com/javase/7/docs/technotes/guides/intl/encoding.doc.html">Supported Encodings</a>.<br/> | |||||
| Defaults to the platform's default character encoding. | |||||
| <em>Since Ant 1.9.4</em> | |||||
| <td align="center" valign="top">No</td> | |||||
| </tr> | |||||
| </table> | </table> | ||||
| <h3>Nested Elements</h3> | <h3>Nested Elements</h3> | ||||
| @@ -100,12 +100,13 @@ archive.</p> | |||||
| </tr> | </tr> | ||||
| <tr> | <tr> | ||||
| <td valign="top">encoding</td> | <td valign="top">encoding</td> | ||||
| <td valign="top"><b>Note:</b> This attribute is not available for | |||||
| the <code>untar</code> task.<br> | |||||
| <td valign="top"> | |||||
| The character encoding that has been used for filenames | The character encoding that has been used for filenames | ||||
| inside the zip file. For a list of possible values see the <a | inside the zip file. For a list of possible values see the <a | ||||
| href="http://docs.oracle.com/javase/7/docs/technotes/guides/intl/encoding.doc.html">Supported Encodings</a>.<br/> | href="http://docs.oracle.com/javase/7/docs/technotes/guides/intl/encoding.doc.html">Supported Encodings</a>.<br/> | ||||
| Defaults to "UTF8", use the magic value | |||||
| Defaults to "UTF8" for the <code>unzip</code> and the | |||||
| platform's default encoding for the <code>untar</code> task. Use | |||||
| the magic value | |||||
| <code>native-encoding</code> for the platform's default character | <code>native-encoding</code> for the platform's default character | ||||
| encoding. | encoding. | ||||
| <br/>See also the <a href="zip.html#encoding">discussion in the | <br/>See also the <a href="zip.html#encoding">discussion in the | ||||
| @@ -130,6 +130,15 @@ directories. Default is 755.</td> | |||||
| </td> | </td> | ||||
| <td valign="top" align="center">No</td> | <td valign="top" align="center">No</td> | ||||
| </tr> | </tr> | ||||
| <tr> | |||||
| <td valign="top">encoding</td> | |||||
| <td valign="top">The character encoding to use for filenames | |||||
| inside the zip file. For a list of possible values see the <a | |||||
| href="http://docs.oracle.com/javase/7/docs/technotes/guides/intl/encoding.doc.html">Supported Encodings</a>. | |||||
| Defaults to the platform's default character encoding. | |||||
| <em>Since Ant 1.9.5</em> | |||||
| <td align="center" valign="top">No</td> | |||||
| </tr> | |||||
| </tbody> | </tbody> | ||||
| </table> | </table> | ||||
| <p>The <i>fullpath</i> attribute can only be set for filesets that | <p>The <i>fullpath</i> attribute can only be set for filesets that | ||||
| @@ -97,7 +97,6 @@ directories. Default is 755. <em>since Ant 1.5.2</em>.</td> | |||||
| inside the zip file. For a list of possible values see the <a | inside the zip file. For a list of possible values see the <a | ||||
| href="http://docs.oracle.com/javase/7/docs/technotes/guides/intl/encoding.doc.html">Supported Encodings</a>. | href="http://docs.oracle.com/javase/7/docs/technotes/guides/intl/encoding.doc.html">Supported Encodings</a>. | ||||
| Defaults to the platform's default character encoding. | Defaults to the platform's default character encoding. | ||||
| <b>Only supported by zipfileset.</b></td> | |||||
| <td align="center" valign="top">No</td> | <td align="center" valign="top">No</td> | ||||
| </tr> | </tr> | ||||
| <tr> | <tr> | ||||
| @@ -57,8 +57,12 @@ | |||||
| <untar src="." dest="${output}/untar" /> | <untar src="." dest="${output}/untar" /> | ||||
| </target> | </target> | ||||
| <target name="encoding"> | |||||
| <untar src="expected/asf-logo.gif.tar" dest="${output}/untar" encoding="foo"/> | |||||
| <target name="encodingTest"> | |||||
| <mkdir dir="${output}/untartestin"/> | |||||
| <touch file="${output}/untartestin/foo"/> | |||||
| <tar tarfile="${output}/untartest.tar" basedir="${output}/untartestin" encoding="UnicodeBig"/> | |||||
| <mkdir dir="${output}/untartestout"/> | |||||
| <untar src="${output}/untartest.tar" dest="${output}/untartestout" encoding="UnicodeBig"/> | |||||
| </target> | </target> | ||||
| <target name="resourceCollection"> | <target name="resourceCollection"> | ||||
| @@ -72,12 +72,28 @@ public class Expand extends Task { | |||||
| public static final String NATIVE_ENCODING = "native-encoding"; | public static final String NATIVE_ENCODING = "native-encoding"; | ||||
| private String encoding = "UTF8"; | |||||
| private String encoding; | |||||
| /** Error message when more that one mapper is defined */ | /** Error message when more that one mapper is defined */ | ||||
| public static final String ERROR_MULTIPLE_MAPPERS = "Cannot define more than one mapper"; | public static final String ERROR_MULTIPLE_MAPPERS = "Cannot define more than one mapper"; | ||||
| private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); | private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); | ||||
| /** | |||||
| * Creates an Expand instance and sets encoding to UTF-8. | |||||
| */ | |||||
| public Expand() { | |||||
| this("UTF8"); | |||||
| } | |||||
| /** | |||||
| * Creates an Expand instance and sets the given encoding. | |||||
| * | |||||
| * @since Ant 1.9.5 | |||||
| */ | |||||
| protected Expand(String encoding) { | |||||
| this.encoding = encoding; | |||||
| } | |||||
| /** | /** | ||||
| * Whether try ing to expand an empty archive would be an error. | * Whether try ing to expand an empty archive would be an error. | ||||
| * | * | ||||
| @@ -123,6 +123,12 @@ public class Tar extends MatchingTask { | |||||
| private TarCompressionMethod compression = new TarCompressionMethod(); | private TarCompressionMethod compression = new TarCompressionMethod(); | ||||
| /** | |||||
| * Encoding to use for filenames, defaults to the platform's | |||||
| * default encoding. | |||||
| */ | |||||
| private String encoding; | |||||
| /** | /** | ||||
| * Add a new fileset with the option to specify permissions | * Add a new fileset with the option to specify permissions | ||||
| * @return the tar fileset to be used as the nested element. | * @return the tar fileset to be used as the nested element. | ||||
| @@ -231,6 +237,20 @@ public class Tar extends MatchingTask { | |||||
| this.compression = mode; | this.compression = mode; | ||||
| } | } | ||||
| /** | |||||
| * Encoding to use for filenames, defaults to the platform's | |||||
| * default encoding. | |||||
| * | |||||
| * <p>For a list of possible values see <a | |||||
| * href="http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html">http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html</a>.</p> | |||||
| * @param encoding the encoding name | |||||
| * | |||||
| * @since Ant 1.9.5 | |||||
| */ | |||||
| public void setEncoding(final String encoding) { | |||||
| this.encoding = encoding; | |||||
| } | |||||
| /** | /** | ||||
| * do the business | * do the business | ||||
| * @throws BuildException on error | * @throws BuildException on error | ||||
| @@ -304,7 +324,8 @@ public class Tar extends MatchingTask { | |||||
| tOut = new TarOutputStream( | tOut = new TarOutputStream( | ||||
| compression.compress( | compression.compress( | ||||
| new BufferedOutputStream( | new BufferedOutputStream( | ||||
| new FileOutputStream(tarFile)))); | |||||
| new FileOutputStream(tarFile))), | |||||
| encoding); | |||||
| tOut.setDebug(true); | tOut.setDebug(true); | ||||
| if (longFileMode.isTruncateMode()) { | if (longFileMode.isTruncateMode()) { | ||||
| tOut.setLongFileMode(TarOutputStream.LONGFILE_TRUNCATE); | tOut.setLongFileMode(TarOutputStream.LONGFILE_TRUNCATE); | ||||
| @@ -58,6 +58,10 @@ public class Untar extends Expand { | |||||
| */ | */ | ||||
| private UntarCompressionMethod compression = new UntarCompressionMethod(); | private UntarCompressionMethod compression = new UntarCompressionMethod(); | ||||
| public Untar() { | |||||
| super(null); | |||||
| } | |||||
| /** | /** | ||||
| * Set decompression algorithm to use; default=none. | * Set decompression algorithm to use; default=none. | ||||
| * | * | ||||
| @@ -74,18 +78,6 @@ public class Untar extends Expand { | |||||
| compression = method; | compression = method; | ||||
| } | } | ||||
| /** | |||||
| * No encoding support in Untar. | |||||
| * @param encoding not used | |||||
| * @throws BuildException always | |||||
| * @since Ant 1.6 | |||||
| */ | |||||
| public void setEncoding(String encoding) { | |||||
| throw new BuildException("The " + getTaskName() | |||||
| + " task doesn't support the encoding" | |||||
| + " attribute", getLocation()); | |||||
| } | |||||
| /** | /** | ||||
| * No unicode extra fields in tar. | * No unicode extra fields in tar. | ||||
| * | * | ||||
| @@ -157,7 +149,8 @@ public class Untar extends Expand { | |||||
| try { | try { | ||||
| tis = | tis = | ||||
| new TarInputStream(compression.decompress(name, | new TarInputStream(compression.decompress(name, | ||||
| new BufferedInputStream(stream))); | |||||
| new BufferedInputStream(stream)), | |||||
| getEncoding()); | |||||
| log("Expanding: " + name + " into " + dir, Project.MSG_INFO); | log("Expanding: " + name + " into " + dir, Project.MSG_INFO); | ||||
| TarEntry te = null; | TarEntry te = null; | ||||
| boolean empty = true; | boolean empty = true; | ||||
| @@ -72,6 +72,8 @@ public abstract class ArchiveFileSet extends FileSet { | |||||
| private boolean errorOnMissingArchive = true; | private boolean errorOnMissingArchive = true; | ||||
| private String encoding = null; | |||||
| /** Constructor for ArchiveFileSet */ | /** Constructor for ArchiveFileSet */ | ||||
| public ArchiveFileSet() { | public ArchiveFileSet() { | ||||
| super(); | super(); | ||||
| @@ -100,6 +102,7 @@ public abstract class ArchiveFileSet extends FileSet { | |||||
| fileModeHasBeenSet = fileset.fileModeHasBeenSet; | fileModeHasBeenSet = fileset.fileModeHasBeenSet; | ||||
| dirModeHasBeenSet = fileset.dirModeHasBeenSet; | dirModeHasBeenSet = fileset.dirModeHasBeenSet; | ||||
| errorOnMissingArchive = fileset.errorOnMissingArchive; | errorOnMissingArchive = fileset.errorOnMissingArchive; | ||||
| encoding = fileset.encoding; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -267,6 +270,33 @@ public abstract class ArchiveFileSet extends FileSet { | |||||
| return fullpath; | return fullpath; | ||||
| } | } | ||||
| /** | |||||
| * Set the encoding used for this ZipFileSet. | |||||
| * @param enc encoding as String. | |||||
| * @since Ant 1.9.5 | |||||
| */ | |||||
| public void setEncoding(String enc) { | |||||
| checkAttributesAllowed(); | |||||
| this.encoding = enc; | |||||
| } | |||||
| /** | |||||
| * Get the encoding used for this ZipFileSet. | |||||
| * @return String encoding. | |||||
| * @since Ant 1.9.5 | |||||
| */ | |||||
| public String getEncoding() { | |||||
| if (isReference()) { | |||||
| AbstractFileSet ref = getRef(getProject()); | |||||
| if (ref instanceof ArchiveFileSet) { | |||||
| return ((ArchiveFileSet) ref).getEncoding(); | |||||
| } else { | |||||
| return null; | |||||
| } | |||||
| } | |||||
| return encoding; | |||||
| } | |||||
| /** | /** | ||||
| * Creates a scanner for this type of archive. | * Creates a scanner for this type of archive. | ||||
| * @return the scanner. | * @return the scanner. | ||||
| @@ -180,6 +180,7 @@ public class TarFileSet extends ArchiveFileSet { | |||||
| */ | */ | ||||
| protected ArchiveScanner newArchiveScanner() { | protected ArchiveScanner newArchiveScanner() { | ||||
| TarScanner zs = new TarScanner(); | TarScanner zs = new TarScanner(); | ||||
| zs.setEncoding(getEncoding()); | |||||
| return zs; | return zs; | ||||
| } | } | ||||
| @@ -58,7 +58,7 @@ public class TarScanner extends ArchiveScanner { | |||||
| try { | try { | ||||
| try { | try { | ||||
| ti = new TarInputStream(src.getInputStream()); | |||||
| ti = new TarInputStream(src.getInputStream(), encoding); | |||||
| } catch (IOException ex) { | } catch (IOException ex) { | ||||
| throw new BuildException("problem opening " + srcFile, ex); | throw new BuildException("problem opening " + srcFile, ex); | ||||
| } | } | ||||
| @@ -84,4 +84,4 @@ public class TarScanner extends ArchiveScanner { | |||||
| FileUtils.close(ti); | FileUtils.close(ti); | ||||
| } | } | ||||
| } | } | ||||
| } | |||||
| } | |||||
| @@ -33,8 +33,6 @@ import org.apache.tools.ant.Project; | |||||
| */ | */ | ||||
| public class ZipFileSet extends ArchiveFileSet { | public class ZipFileSet extends ArchiveFileSet { | ||||
| private String encoding = null; | |||||
| /** Constructor for ZipFileSet */ | /** Constructor for ZipFileSet */ | ||||
| public ZipFileSet() { | public ZipFileSet() { | ||||
| super(); | super(); | ||||
| @@ -54,34 +52,6 @@ public class ZipFileSet extends ArchiveFileSet { | |||||
| */ | */ | ||||
| protected ZipFileSet(ZipFileSet fileset) { | protected ZipFileSet(ZipFileSet fileset) { | ||||
| super(fileset); | super(fileset); | ||||
| encoding = fileset.encoding; | |||||
| } | |||||
| /** | |||||
| * Set the encoding used for this ZipFileSet. | |||||
| * @param enc encoding as String. | |||||
| * @since Ant 1.7 | |||||
| */ | |||||
| public void setEncoding(String enc) { | |||||
| checkZipFileSetAttributesAllowed(); | |||||
| this.encoding = enc; | |||||
| } | |||||
| /** | |||||
| * Get the encoding used for this ZipFileSet. | |||||
| * @return String encoding. | |||||
| * @since Ant 1.7 | |||||
| */ | |||||
| public String getEncoding() { | |||||
| if (isReference()) { | |||||
| AbstractFileSet ref = getRef(getProject()); | |||||
| if (ref instanceof ZipFileSet) { | |||||
| return ((ZipFileSet) ref).getEncoding(); | |||||
| } else { | |||||
| return null; | |||||
| } | |||||
| } | |||||
| return encoding; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -90,7 +60,7 @@ public class ZipFileSet extends ArchiveFileSet { | |||||
| */ | */ | ||||
| protected ArchiveScanner newArchiveScanner() { | protected ArchiveScanner newArchiveScanner() { | ||||
| ZipScanner zs = new ZipScanner(); | ZipScanner zs = new ZipScanner(); | ||||
| zs.setEncoding(encoding); | |||||
| zs.setEncoding(getEncoding()); | |||||
| return zs; | return zs; | ||||
| } | } | ||||
| @@ -34,4 +34,15 @@ | |||||
| </copy> | </copy> | ||||
| </target> | </target> | ||||
| <target name="test-refid-check-encoding"> | |||||
| <tarfileset id="test-refid2" | |||||
| encoding="utf-8" | |||||
| dir="${basedir}"/> | |||||
| <au:expectfailure> | |||||
| <tarfileset id="ref4" | |||||
| encoding="utf-8" | |||||
| refid="test-refid2"/> | |||||
| </au:expectfailure> | |||||
| </target> | |||||
| </project> | </project> | ||||
| @@ -84,12 +84,10 @@ public class UntarTest { | |||||
| @Test | @Test | ||||
| public void testEncoding() { | public void testEncoding() { | ||||
| try { | |||||
| buildRule.executeTarget("encoding"); | |||||
| fail("<untar> overrides setEncoding."); | |||||
| } catch (BuildException ex) { | |||||
| assertEquals("The untar task doesn't support the encoding attribute", ex.getMessage()); | |||||
| } | |||||
| buildRule.executeTarget("encodingTest"); | |||||
| String filename = buildRule.getProject().getProperty("output") + "/untartestout/foo"; | |||||
| assertTrue("foo has been properly named", | |||||
| buildRule.getProject().resolveFile(filename).exists()); | |||||
| } | } | ||||
| @Test | @Test | ||||