git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@350061 13f79535-47bb-0310-9956-ffa450edef68master
@@ -38,6 +38,37 @@ public final class Locator { | |||||
* encoding used to represent URIs | * encoding used to represent URIs | ||||
*/ | */ | ||||
public static String URI_ENCODING = "UTF-8"; | public static String URI_ENCODING = "UTF-8"; | ||||
// stolen from org.apache.xerces.impl.XMLEntityManager#getUserDir() | |||||
// of the Xerces-J team | |||||
// which ASCII characters need to be escaped | |||||
private static boolean gNeedEscaping[] = new boolean[128]; | |||||
// the first hex character if a character needs to be escaped | |||||
private static char gAfterEscaping1[] = new char[128]; | |||||
// the second hex character if a character needs to be escaped | |||||
private static char gAfterEscaping2[] = new char[128]; | |||||
private static char[] gHexChs = {'0', '1', '2', '3', '4', '5', '6', '7', | |||||
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; | |||||
// initialize the above 3 arrays | |||||
static { | |||||
for (int i = 0; i <= 0x1f; i++) { | |||||
gNeedEscaping[i] = true; | |||||
gAfterEscaping1[i] = gHexChs[i >> 4]; | |||||
gAfterEscaping2[i] = gHexChs[i & 0xf]; | |||||
} | |||||
gNeedEscaping[0x7f] = true; | |||||
gAfterEscaping1[0x7f] = '7'; | |||||
gAfterEscaping2[0x7f] = 'F'; | |||||
char[] escChs = {' ', '<', '>', '#', '%', '"', '{', '}', | |||||
'|', '\\', '^', '~', '[', ']', '`'}; | |||||
int len = escChs.length; | |||||
char ch; | |||||
for (int i = 0; i < len; i++) { | |||||
ch = escChs[i]; | |||||
gNeedEscaping[ch] = true; | |||||
gAfterEscaping1[ch] = gHexChs[ch >> 4]; | |||||
gAfterEscaping2[ch] = gHexChs[ch & 0xf]; | |||||
} | |||||
} | |||||
/** | /** | ||||
* Not instantiable | * Not instantiable | ||||
*/ | */ | ||||
@@ -176,7 +207,66 @@ public final class Locator { | |||||
sb.write(c); | sb.write(c); | ||||
} | } | ||||
} | } | ||||
return sb.toString("UTF-8"); | |||||
return sb.toString(URI_ENCODING); | |||||
} | |||||
/** | |||||
* Encodes an Uri with % characters. | |||||
* The URI is escaped | |||||
* @param path String to encode. | |||||
* @return The encoded string, according to URI norms | |||||
* @throws UnsupportedEncodingException if UTF-8 is not available | |||||
* @since Ant 1.7 | |||||
*/ | |||||
public static String encodeUri(String path) throws UnsupportedEncodingException { | |||||
int i = 0; | |||||
int len = path.length(); | |||||
int ch = 0; | |||||
StringBuffer sb = new StringBuffer(len); | |||||
for (; i < len; i++) { | |||||
ch = path.charAt(i); | |||||
// if it's not an ASCII character, break here, and use UTF-8 encoding | |||||
if (ch >= 128) | |||||
break; | |||||
if (gNeedEscaping[ch]) { | |||||
sb.append('%'); | |||||
sb.append(gAfterEscaping1[ch]); | |||||
sb.append(gAfterEscaping2[ch]); | |||||
// record the fact that it's escaped | |||||
} | |||||
else { | |||||
sb.append((char)ch); | |||||
} | |||||
} | |||||
// we saw some non-ascii character | |||||
if (i < len) { | |||||
// get UTF-8 bytes for the remaining sub-string | |||||
byte[] bytes = null; | |||||
byte b; | |||||
bytes = path.substring(i).getBytes(URI_ENCODING); | |||||
len = bytes.length; | |||||
// for each byte | |||||
for (i = 0; i < len; i++) { | |||||
b = bytes[i]; | |||||
// for non-ascii character: make it positive, then escape | |||||
if (b < 0) { | |||||
ch = b + 256; | |||||
sb.append('%'); | |||||
sb.append(gHexChs[ch >> 4]); | |||||
sb.append(gHexChs[ch & 0xf]); | |||||
} | |||||
else if (gNeedEscaping[b]) { | |||||
sb.append('%'); | |||||
sb.append(gAfterEscaping1[b]); | |||||
sb.append(gAfterEscaping2[b]); | |||||
} | |||||
else { | |||||
sb.append((char)b); | |||||
} | |||||
} | |||||
} | |||||
return sb.toString(); | |||||
} | } | ||||
/** | /** | ||||
@@ -17,10 +17,12 @@ | |||||
package org.apache.tools.ant.taskdefs; | package org.apache.tools.ant.taskdefs; | ||||
import java.io.File; | import java.io.File; | ||||
import java.io.UnsupportedEncodingException; | |||||
import org.apache.tools.ant.Task; | import org.apache.tools.ant.Task; | ||||
import org.apache.tools.ant.types.Path; | import org.apache.tools.ant.types.Path; | ||||
import org.apache.tools.ant.BuildException; | import org.apache.tools.ant.BuildException; | ||||
import org.apache.tools.ant.launch.Locator; | |||||
import org.apache.tools.ant.util.FileUtils; | import org.apache.tools.ant.util.FileUtils; | ||||
/** | /** | ||||
@@ -123,10 +125,15 @@ public class ManifestClassPath | |||||
if (File.separatorChar != '/') { | if (File.separatorChar != '/') { | ||||
relPath = relPath.replace(File.separatorChar, '/'); | relPath = relPath.replace(File.separatorChar, '/'); | ||||
} | } | ||||
buffer.append(relPath); | |||||
if (pathEntry.isDirectory()) { | if (pathEntry.isDirectory()) { | ||||
buffer.append('/'); | |||||
relPath = relPath + '/'; | |||||
} | |||||
try { | |||||
relPath = Locator.encodeUri(relPath); | |||||
} catch (UnsupportedEncodingException exc) { | |||||
throw new BuildException(exc); | |||||
} | } | ||||
buffer.append(relPath); | |||||
buffer.append(' '); | buffer.append(' '); | ||||
} | } | ||||
@@ -59,37 +59,6 @@ public class FileUtils { | |||||
static final int BUF_SIZE = 8192; | static final int BUF_SIZE = 8192; | ||||
// stolen from org.apache.xerces.impl.XMLEntityManager#getUserDir() | |||||
// of the Xerces-J team | |||||
// which ASCII characters need to be escaped | |||||
private static boolean gNeedEscaping[] = new boolean[128]; | |||||
// the first hex character if a character needs to be escaped | |||||
private static char gAfterEscaping1[] = new char[128]; | |||||
// the second hex character if a character needs to be escaped | |||||
private static char gAfterEscaping2[] = new char[128]; | |||||
private static char[] gHexChs = {'0', '1', '2', '3', '4', '5', '6', '7', | |||||
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; | |||||
// initialize the above 3 arrays | |||||
static { | |||||
for (int i = 0; i <= 0x1f; i++) { | |||||
gNeedEscaping[i] = true; | |||||
gAfterEscaping1[i] = gHexChs[i >> 4]; | |||||
gAfterEscaping2[i] = gHexChs[i & 0xf]; | |||||
} | |||||
gNeedEscaping[0x7f] = true; | |||||
gAfterEscaping1[0x7f] = '7'; | |||||
gAfterEscaping2[0x7f] = 'F'; | |||||
char[] escChs = {' ', '<', '>', '#', '%', '"', '{', '}', | |||||
'|', '\\', '^', '~', '[', ']', '`'}; | |||||
int len = escChs.length; | |||||
char ch; | |||||
for (int i = 0; i < len; i++) { | |||||
ch = escChs[i]; | |||||
gNeedEscaping[ch] = true; | |||||
gAfterEscaping1[ch] = gHexChs[ch >> 4]; | |||||
gAfterEscaping2[ch] = gHexChs[ch & 0xf]; | |||||
} | |||||
} | |||||
/** | /** | ||||
* The granularity of timestamps under FAT. | * The granularity of timestamps under FAT. | ||||
@@ -1048,58 +1017,11 @@ public class FileUtils { | |||||
sb.append("/"); | sb.append("/"); | ||||
} | } | ||||
path = path.replace('\\', '/'); | path = path.replace('\\', '/'); | ||||
int i = 0; | |||||
for (; i < len; i++) { | |||||
ch = path.charAt(i); | |||||
// if it's not an ASCII character, break here, and use UTF-8 encoding | |||||
if (ch >= 128) | |||||
break; | |||||
if (gNeedEscaping[ch]) { | |||||
sb.append('%'); | |||||
sb.append(gAfterEscaping1[ch]); | |||||
sb.append(gAfterEscaping2[ch]); | |||||
// record the fact that it's escaped | |||||
} | |||||
else { | |||||
sb.append((char)ch); | |||||
} | |||||
} | |||||
// we saw some non-ascii character | |||||
if (i < len) { | |||||
// get UTF-8 bytes for the remaining sub-string | |||||
byte[] bytes = null; | |||||
byte b; | |||||
try { | |||||
bytes = path.substring(i).getBytes(Locator.URI_ENCODING); | |||||
} catch (java.io.UnsupportedEncodingException e) { | |||||
// should never happen | |||||
throw new BuildException(e); | |||||
} | |||||
len = bytes.length; | |||||
// for each byte | |||||
for (i = 0; i < len; i++) { | |||||
b = bytes[i]; | |||||
// for non-ascii character: make it positive, then escape | |||||
if (b < 0) { | |||||
ch = b + 256; | |||||
sb.append('%'); | |||||
sb.append(gHexChs[ch >> 4]); | |||||
sb.append(gHexChs[ch & 0xf]); | |||||
} | |||||
else if (gNeedEscaping[b]) { | |||||
sb.append('%'); | |||||
sb.append(gAfterEscaping1[b]); | |||||
sb.append(gAfterEscaping2[b]); | |||||
} | |||||
else { | |||||
sb.append((char)b); | |||||
} | |||||
} | |||||
try { | |||||
sb.append(Locator.encodeUri(path)); | |||||
} catch (UnsupportedEncodingException exc) { | |||||
throw new BuildException(exc); | |||||
} | } | ||||
if (isDir && !path.endsWith("/")) { | if (isDir && !path.endsWith("/")) { | ||||
sb.append('/'); | sb.append('/'); | ||||
} | } | ||||