Browse Source

properly convert URIs back to file paths when non ascii characters are percent-encoded

matches with the change in FileUtils.toURI recently done


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@349552 13f79535-47bb-0310-9956-ffa450edef68
master
Antoine Levy-Lambert 19 years ago
parent
commit
6a71283099
5 changed files with 59 additions and 16 deletions
  1. +16
    -1
      src/etc/testcases/core/antclassloader.xml
  2. +2
    -8
      src/main/org/apache/tools/ant/AntClassLoader.java
  3. +25
    -6
      src/main/org/apache/tools/ant/launch/Locator.java
  4. +6
    -1
      src/main/org/apache/tools/ant/util/FileUtils.java
  5. +10
    -0
      src/testcases/org/apache/tools/ant/AntClassLoaderTest.java

+ 16
- 1
src/etc/testcases/core/antclassloader.xml View File

@@ -1,13 +1,18 @@
<project name="antclassloader-test" basedir="."> <project name="antclassloader-test" basedir=".">
<property name="tmp.dir" location="tmp space"/> <property name="tmp.dir" location="tmp space"/>
<!-- ant for germans -->
<property name="tmp.dir.nonascii" value="&#0227;nt"/>
<property name="ext.dir.relative" value="ext"/> <property name="ext.dir.relative" value="ext"/>
<property name="main.jar" location="${tmp.dir}/main.jar"/> <property name="main.jar" location="${tmp.dir}/main.jar"/>
<property name="ext.jar.relative" value="${ext.dir.relative}/ext.jar"/> <property name="ext.jar.relative" value="${ext.dir.relative}/ext.jar"/>
<property name="ext.jar" location="${tmp.dir}/${ext.jar.relative}"/> <property name="ext.jar" location="${tmp.dir}/${ext.jar.relative}"/>
<property name="build.sysclasspath" value="first"/> <property name="build.sysclasspath" value="first"/>
<property name="main.jar.nonascii" location="${tmp.dir.nonascii}/main.jar"/>
<property name="ext.jar.nonascii" location="${tmp.dir.nonascii}/${ext.jar.relative}"/>
<target name="setup" depends="setup.withspace,setup.nonascii"/>
<target name="setup">
<target name="setup.withspace">
<mkdir dir="${tmp.dir}/${ext.dir.relative}"/> <mkdir dir="${tmp.dir}/${ext.dir.relative}"/>
<jar destfile="${main.jar}" whenempty="create"> <jar destfile="${main.jar}" whenempty="create">
<manifest> <manifest>
@@ -16,10 +21,20 @@
</jar> </jar>
<jar destfile="${ext.jar}"/> <jar destfile="${ext.jar}"/>
</target> </target>
<target name="setup.nonascii">
<mkdir dir="${tmp.dir.nonascii}/${ext.dir.relative}"/>
<jar destfile="${main.jar.nonascii}" whenempty="create">
<manifest>
<attribute name="Class-Path" value="${ext.jar.relative}"/>
</manifest>
</jar>
<jar destfile="${ext.jar.nonascii}"/>
</target>
<target name="cleanup"> <target name="cleanup">
<delete dir="${tmp.dir}" quiet="true"/> <delete dir="${tmp.dir}" quiet="true"/>
<delete dir="${tmp.dir.nonascii}" quiet="true"/>
</target> </target>


+ 2
- 8
src/main/org/apache/tools/ant/AntClassLoader.java View File

@@ -46,6 +46,7 @@ import org.apache.tools.ant.util.CollectionUtils;
import org.apache.tools.ant.util.FileUtils; import org.apache.tools.ant.util.FileUtils;
import org.apache.tools.ant.util.JavaEnvUtils; import org.apache.tools.ant.util.JavaEnvUtils;
import org.apache.tools.ant.util.LoaderUtils; import org.apache.tools.ant.util.LoaderUtils;
import org.apache.tools.ant.launch.Locator;


/** /**
* Used to load classes within ant with a different classpath from * Used to load classes within ant with a different classpath from
@@ -500,14 +501,7 @@ public class AntClassLoader extends ClassLoader implements SubBuildListener {
+ " loader", Project.MSG_VERBOSE); + " loader", Project.MSG_VERBOSE);
continue; continue;
} }
String decodedPath = null;
// try catch block required because URLDecoder.decode throws
// exception on JDK 1.2
try {
decodedPath = URLDecoder.decode(libraryURL.getFile());
} catch (Exception exc) {
throw new BuildException(exc);
}
String decodedPath = Locator.decodeUri(libraryURL.getFile());
File libraryFile = new File(decodedPath); File libraryFile = new File(decodedPath);
if (libraryFile.exists() && !isInPath(libraryFile)) { if (libraryFile.exists() && !isInPath(libraryFile)) {
addPathFile(libraryFile); addPathFile(libraryFile);


+ 25
- 6
src/main/org/apache/tools/ant/launch/Locator.java View File

@@ -21,6 +21,8 @@ import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.io.File; import java.io.File;
import java.io.FilenameFilter; import java.io.FilenameFilter;
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.text.CharacterIterator; import java.text.CharacterIterator;
import java.text.StringCharacterIterator; import java.text.StringCharacterIterator;
import java.util.Locale; import java.util.Locale;
@@ -32,6 +34,10 @@ import java.util.Locale;
* @since Ant 1.6 * @since Ant 1.6
*/ */
public final class Locator { public final class Locator {
/**
* encoding used to represent URIs
*/
public static String URI_ENCODING = "UTF-8";
/** /**
* Not instantiable * Not instantiable
*/ */
@@ -96,6 +102,10 @@ public final class Locator {
* <p>Swallows '%' that are not followed by two characters, * <p>Swallows '%' that are not followed by two characters,
* doesn't deal with non-ASCII characters.</p> * doesn't deal with non-ASCII characters.</p>
* *
* @see <a href="http://www.w3.org/TR/xml11/#dt-sysid">dt-sysid</a>
* which makes some mention of how
* characters not supported by URI Reference syntax should be escaped.
*
* @param uri the URI designating a file in the local filesystem. * @param uri the URI designating a file in the local filesystem.
* @return the local file system path for the file. * @return the local file system path for the file.
* @since Ant 1.6 * @since Ant 1.6
@@ -124,21 +134,30 @@ public final class Locator {
&& Character.isLetter(uri.charAt(1)) && uri.lastIndexOf(':') > -1) { && Character.isLetter(uri.charAt(1)) && uri.lastIndexOf(':') > -1) {
uri = uri.substring(1); uri = uri.substring(1);
} }
String path = decodeUri(uri);
String path = null;
try {
path = decodeUri(uri);
} catch (UnsupportedEncodingException exc) {
// not sure whether this is clean, but this method is declared not to throw exceptions.
throw new IllegalStateException("Could not convert URI to path", exc);
}
return path; return path;
} }


/** /**
* Decodes an Uri with % characters. * Decodes an Uri with % characters.
* The URI is escaped
* @param uri String with the uri possibly containing % characters. * @param uri String with the uri possibly containing % characters.
* @return The decoded Uri * @return The decoded Uri
* @throws UnsupportedEncodingException if UTF-8 is not available
* @since Ant 1.7
*/ */
private static String decodeUri(String uri) {
public static String decodeUri(String uri) throws UnsupportedEncodingException{
if (uri.indexOf('%') == -1) if (uri.indexOf('%') == -1)
{ {
return uri; return uri;
} }
StringBuffer sb = new StringBuffer();
ByteArrayOutputStream sb = new ByteArrayOutputStream(uri.length());
CharacterIterator iter = new StringCharacterIterator(uri); CharacterIterator iter = new StringCharacterIterator(uri);
for (char c = iter.first(); c != CharacterIterator.DONE; for (char c = iter.first(); c != CharacterIterator.DONE;
c = iter.next()) { c = iter.next()) {
@@ -149,14 +168,14 @@ public final class Locator {
char c2 = iter.next(); char c2 = iter.next();
if (c2 != CharacterIterator.DONE) { if (c2 != CharacterIterator.DONE) {
int i2 = Character.digit(c2, 16); int i2 = Character.digit(c2, 16);
sb.append((char) ((i1 << 4) + i2));
sb.write((char) ((i1 << 4) + i2));
} }
} }
} else { } else {
sb.append(c);
sb.write(c);
} }
} }
String path = sb.toString();
String path = sb.toString("UTF-8");
return path; return path;
} }




+ 6
- 1
src/main/org/apache/tools/ant/util/FileUtils.java View File

@@ -1026,6 +1026,11 @@ public class FileUtils {
* <p>This code encodes non ASCII characters too.</p> * <p>This code encodes non ASCII characters too.</p>
* *
* <p>The coding of the output is the same as what File.toURI().toASCIIString() produces</p> * <p>The coding of the output is the same as what File.toURI().toASCIIString() produces</p>
*
* @see <a href="http://www.w3.org/TR/xml11/#dt-sysid">dt-sysid</a>
* which makes some mention of how
* characters not supported by URI Reference syntax should be escaped.
*
* @param path the path in the local file system. * @param path the path in the local file system.
* @return the URI version of the local path. * @return the URI version of the local path.
* @since Ant 1.6 * @since Ant 1.6
@@ -1067,7 +1072,7 @@ public class FileUtils {
byte[] bytes = null; byte[] bytes = null;
byte b; byte b;
try { try {
bytes = path.substring(i).getBytes("UTF-8");
bytes = path.substring(i).getBytes(Locator.URI_ENCODING);
} catch (java.io.UnsupportedEncodingException e) { } catch (java.io.UnsupportedEncodingException e) {
// should never happen // should never happen
throw new BuildException(e); throw new BuildException(e);


+ 10
- 0
src/testcases/org/apache/tools/ant/AntClassLoaderTest.java View File

@@ -53,6 +53,16 @@ public class AntClassLoaderTest extends BuildFileTest {
String path = myLoader.getClasspath(); String path = myLoader.getClasspath();
assertEquals(mainjarstring + File.pathSeparator + extjarstring, path); assertEquals(mainjarstring + File.pathSeparator + extjarstring, path);
} }
public void testJarWithManifestInNonAsciiDir() {
String mainjarstring = getProject().getProperty("main.jar.nonascii");
String extjarstring = getProject().getProperty("ext.jar.nonascii");
Path myPath = new Path(getProject());
myPath.setLocation(new File(mainjarstring));
getProject().setUserProperty("build.sysclasspath","ignore");
AntClassLoader myLoader = getProject().createClassLoader(myPath);
String path = myLoader.getClasspath();
assertEquals(mainjarstring + File.pathSeparator + extjarstring, path);
}
public void testCleanup() throws BuildException { public void testCleanup() throws BuildException {
Path path = new Path(p, "."); Path path = new Path(p, ".");
AntClassLoader loader = new AntClassLoader(p, path); AntClassLoader loader = new AntClassLoader(p, path);


Loading…
Cancel
Save