1 package net.sf.saxon.event; 2 import net.sf.saxon.charcode.UnicodeCharacterSet; 3 import net.sf.saxon.om.FastStringBuffer; 4 import net.sf.saxon.om.NamePool; 5 import net.sf.saxon.trans.XPathException; 6 7 12 13 public class HTMLURIEscaper extends ProxyReceiver { 14 15 18 19 21 private static HTMLTagHashSet urlAttributes = new HTMLTagHashSet(47); 22 private static HTMLTagHashSet urlCombinations = new HTMLTagHashSet(101); 23 24 static { 25 setUrlAttribute("form", "action"); 26 setUrlAttribute("body", "background"); 27 setUrlAttribute("q", "cite"); 28 setUrlAttribute("blockquote", "cite"); 29 setUrlAttribute("del", "cite"); 30 setUrlAttribute("ins", "cite"); 31 setUrlAttribute("object", "classid"); 32 setUrlAttribute("object", "codebase"); 33 setUrlAttribute("applet", "codebase"); 34 setUrlAttribute("object", "data"); 35 setUrlAttribute("a", "href"); 36 setUrlAttribute("a", "name"); setUrlAttribute("area", "href"); 38 setUrlAttribute("link", "href"); 39 setUrlAttribute("base", "href"); 40 setUrlAttribute("img", "longdesc"); 41 setUrlAttribute("frame", "longdesc"); 42 setUrlAttribute("iframe", "longdesc"); 43 setUrlAttribute("head", "profile"); 44 setUrlAttribute("script", "src"); 45 setUrlAttribute("input", "src"); 46 setUrlAttribute("frame", "src"); 47 setUrlAttribute("iframe", "src"); 48 setUrlAttribute("img", "src"); 49 setUrlAttribute("img", "usemap"); 50 setUrlAttribute("input", "usemap"); 51 setUrlAttribute("object", "usemap"); 52 } 53 54 private static void setUrlAttribute(String element, String attribute) { 55 urlAttributes.add(attribute); 56 urlCombinations.add(element + '+' + attribute); 57 } 58 59 public boolean isUrlAttribute(int element, int attribute) { 60 String attributeName = pool.getDisplayName(attribute); 61 if (!urlAttributes.contains(attributeName)) { 62 return false; 63 } 64 String elementName = pool.getDisplayName(element); 65 return urlCombinations.contains(elementName + '+' + attributeName); 66 } 67 68 protected int currentElement; 69 protected boolean escapeURIAttributes = true; 70 protected NamePool pool; 71 72 75 76 public void open() throws XPathException { 77 super.open(); 78 } 79 80 83 84 public void startDocument(int properties) throws XPathException { 85 super.startDocument(properties); 86 pool = getPipelineConfiguration().getConfiguration().getNamePool(); 87 } 88 89 96 97 public void startElement(int nameCode, int typeCode, int locationId, int properties) throws XPathException { 98 currentElement = nameCode; 99 getUnderlyingReceiver().startElement(nameCode, typeCode, locationId, properties); 100 } 101 102 114 115 public void attribute(int nameCode, int typeCode, CharSequence value, int locationId, int properties) throws XPathException { 116 if (escapeURIAttributes && 117 isUrlAttribute(currentElement, nameCode) && 118 (properties & ReceiverOptions.DISABLE_ESCAPING) == 0) { 119 getUnderlyingReceiver().attribute(nameCode, typeCode, escapeURL(value), locationId, 120 properties | ReceiverOptions.DISABLE_CHARACTER_MAPS); 121 } else { 122 getUnderlyingReceiver().attribute(nameCode, typeCode, value, locationId, properties); 123 } 124 } 125 126 127 public static CharSequence escapeURL(CharSequence url) { 128 FastStringBuffer sb = new FastStringBuffer(url.length() + 20); 129 final String hex = "0123456789ABCDEF"; 130 131 for (int i=0; i<url.length(); i++) { 132 char ch = url.charAt(i); 133 if (ch<32 || ch>126) { 134 byte[] array = new byte[4]; 135 int used = UnicodeCharacterSet.getUTF8Encoding(ch, 136 (i+1 < url.length() ? url.charAt(i+1): ' '), array); 137 for (int b=0; b<used; b++) { 138 int v = (array[b]>=0 ? array[b] : 256 + array[b]); 139 sb.append('%'); 140 sb.append(hex.charAt(v/16)); 141 sb.append(hex.charAt(v%16)); 142 } 143 144 } else { 145 sb.append(ch); 146 } 147 } 148 return sb; 149 } 150 } 151 152 | Popular Tags |