diff options
author | Jeremias Maerki <jeremias@apache.org> | 2008-01-14 11:01:11 +0000 |
---|---|---|
committer | Jeremias Maerki <jeremias@apache.org> | 2008-01-14 11:01:11 +0000 |
commit | e77d6863bbe2671af4a34d250417867264631238 (patch) | |
tree | f8c3208cfbe365c53c00328ec8c55624ff0943f5 /src/java/org/apache | |
parent | 6101c1c37f5f2f5be2cfccc91f55112084ce6882 (diff) | |
download | xmlgraphics-fop-e77d6863bbe2671af4a34d250417867264631238.tar.gz xmlgraphics-fop-e77d6863bbe2671af4a34d250417867264631238.zip |
java.net.URI doesn't eat non-escaped URIs so I added an escaping method to URISpecification that should cover most cases. Usually, it's just about a space in a filename.
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@611766 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache')
-rw-r--r-- | src/java/org/apache/fop/datatypes/URISpecification.java | 85 | ||||
-rw-r--r-- | src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java | 3 |
2 files changed, 87 insertions, 1 deletions
diff --git a/src/java/org/apache/fop/datatypes/URISpecification.java b/src/java/org/apache/fop/datatypes/URISpecification.java index 2a3a3cba9..99d445b4d 100644 --- a/src/java/org/apache/fop/datatypes/URISpecification.java +++ b/src/java/org/apache/fop/datatypes/URISpecification.java @@ -19,6 +19,9 @@ package org.apache.fop.datatypes; +import java.io.UnsupportedEncodingException; + + /** * This class contains method to deal with the <uri-specification> datatype from XSL-FO. */ @@ -52,5 +55,87 @@ public class URISpecification { return href; } + private static final String PUNCT = ",;:$&+="; + private static final String RESERVED = PUNCT + "?/[]@"; + + private static boolean isValidURIChar(char ch) { + return true; + } + + private static boolean isDigit(char ch) { + return (ch >= '0' && ch <= '9'); + } + + private static boolean isAlpha(char ch) { + return (ch >= 'A' && ch <= 'Z') || (ch >= 'A' && ch <= 'z'); + } + + private static boolean isHexDigit(char ch) { + return (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f'); + } + + private static boolean isReserved(char ch) { + if (RESERVED.indexOf(ch) >= 0) { + return true; + } else if ('#' == ch) { + //# is not a reserved character but is used for the fragment + return true; + } + return false; + } + + private static boolean isUnreserved(char ch) { + if (isDigit(ch) || isAlpha(ch)) { + return true; + } else if ("_-!.~\'()*".indexOf(ch) >= 0) { + //remaining unreserved characters + return true; + } + return false; + } + + private final static char[] HEX_DIGITS = { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' + }; + + private static void appendEscape(StringBuffer sb, byte b) { + sb.append('%').append(HEX_DIGITS[(b >> 4) & 0x0f]).append(HEX_DIGITS[(b >> 0) & 0x0f]); + } + + /** + * Escapes any illegal URI character in a given URI, for example, it escapes a space to "%20". + * Note: This method does not "parse" the URI and therefore does not treat the individual + * components (user-info, path, query etc.) individually. + * @param uri the URI to inspect + * @return the escaped URI + */ + public static String escapeURI(String uri) { + uri = getURL(uri); + StringBuffer sb = new StringBuffer(); + for (int i = 0, c = uri.length(); i < c; i++) { + char ch = uri.charAt(i); + if (ch == '%') { + if (i < c - 3 && isHexDigit(uri.charAt(i + 1)) && isHexDigit(uri.charAt(i + 2))) { + sb.append(ch); + continue; + } + } + if (isReserved(ch) || isUnreserved(ch)) { + //Note: this may not be accurate for some very special cases. + sb.append(ch); + } else { + try { + byte[] utf8 = Character.toString(ch).getBytes("UTF-8"); + for (int j = 0, cj = utf8.length; j < cj; j++) { + appendEscape(sb, utf8[j]); + } + } catch (UnsupportedEncodingException e) { + throw new Error("Incompatible JVM. UTF-8 not supported."); + } + } + } + return sb.toString(); + } } diff --git a/src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java index 0e51517f2..89065185b 100644 --- a/src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java @@ -44,6 +44,7 @@ import org.apache.fop.area.RegionViewport; import org.apache.fop.area.inline.Image; import org.apache.fop.area.inline.Viewport; import org.apache.fop.datatypes.FODimension; +import org.apache.fop.datatypes.URISpecification; import org.apache.fop.fo.Constants; import org.apache.fop.fo.extensions.ExternalDocument; import org.apache.fop.layoutmgr.inline.ImageLayout; @@ -114,7 +115,7 @@ public class ExternalDocumentLayoutManager extends AbstractPageSequenceLayoutMan } URI originalURI; try { - originalURI = new URI(uri); + originalURI = new URI(URISpecification.escapeURI(uri)); int pageIndex = 1; while (hasMoreImages) { URI tempURI = new URI(originalURI.getScheme(), |