Browse Source

percent encode the relative paths in ManifestClassPath

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@350061 13f79535-47bb-0310-9956-ffa450edef68
master
Antoine Levy-Lambert 19 years ago
parent
commit
551b204c24
3 changed files with 104 additions and 85 deletions
  1. +91
    -1
      src/main/org/apache/tools/ant/launch/Locator.java
  2. +9
    -2
      src/main/org/apache/tools/ant/taskdefs/ManifestClassPath.java
  3. +4
    -82
      src/main/org/apache/tools/ant/util/FileUtils.java

+ 91
- 1
src/main/org/apache/tools/ant/launch/Locator.java View File

@@ -38,6 +38,37 @@ public final class Locator {
* encoding used to represent URIs
*/
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
*/
@@ -176,7 +207,66 @@ public final class Locator {
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();
}

/**


+ 9
- 2
src/main/org/apache/tools/ant/taskdefs/ManifestClassPath.java View File

@@ -17,10 +17,12 @@
package org.apache.tools.ant.taskdefs;

import java.io.File;
import java.io.UnsupportedEncodingException;

import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.launch.Locator;
import org.apache.tools.ant.util.FileUtils;

/**
@@ -123,10 +125,15 @@ public class ManifestClassPath
if (File.separatorChar != '/') {
relPath = relPath.replace(File.separatorChar, '/');
}
buffer.append(relPath);
if (pathEntry.isDirectory()) {
buffer.append('/');
relPath = relPath + '/';
}
try {
relPath = Locator.encodeUri(relPath);
} catch (UnsupportedEncodingException exc) {
throw new BuildException(exc);
}
buffer.append(relPath);
buffer.append(' ');
}


+ 4
- 82
src/main/org/apache/tools/ant/util/FileUtils.java View File

@@ -59,37 +59,6 @@ public class FileUtils {

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.
@@ -1048,58 +1017,11 @@ public class FileUtils {
sb.append("/");
}
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("/")) {
sb.append('/');
}


Loading…
Cancel
Save