1 43 package net.jforum.util; 44 45 import java.util.HashSet ; 46 import java.util.Iterator ; 47 import java.util.Set ; 48 import java.util.Vector ; 49 50 import net.jforum.exceptions.ForumException; 51 import net.jforum.util.preferences.ConfigKeys; 52 import net.jforum.util.preferences.SystemGlobals; 53 54 import org.apache.log4j.Logger; 55 import org.htmlparser.Attribute; 56 import org.htmlparser.Node; 57 import org.htmlparser.Tag; 58 import org.htmlparser.lexer.Lexer; 59 import org.htmlparser.nodes.TextNode; 60 61 68 public class SafeHtml 69 { 70 private static final Logger logger = Logger.getLogger(SafeHtml.class); 71 private static Set welcomeTags; 72 73 static { 74 welcomeTags = new HashSet (); 75 String [] tags = SystemGlobals.getValue(ConfigKeys.HTML_TAGS_WELCOME).toUpperCase().split(","); 76 77 for (int i = 0; i < tags.length; i++) { 78 welcomeTags.add(tags[i].trim()); 79 } 80 } 81 82 public SafeHtml() {} 83 84 private String processAllNodes(String contents, boolean onlyEvaluateJs) throws Exception 85 { 86 StringBuffer sb = new StringBuffer (512); 87 88 Lexer lexer = new Lexer(contents); 89 Node node; 90 91 while ((node = lexer.nextNode()) != null) { 92 boolean isTextNode = node instanceof TextNode; 93 94 if (isTextNode) { 95 String text = node.toHtml(); 96 97 if (text.indexOf('>') > -1 || text.indexOf('<') > -1) { 98 text = text.replaceAll("<", "<") 99 .replaceAll(">", ">") 100 .replaceAll("\"", """); 101 node.setText(text); 102 } 103 } 104 else if (onlyEvaluateJs) { 105 this.checkAndValidateAttributes((Tag)node); 106 } 107 108 if (isTextNode || onlyEvaluateJs || this.isTagWelcome(node)) { 109 sb.append(node.toHtml()); 110 } 111 else { 112 sb.append(node.toHtml().replaceAll("<", "<").replaceAll(">", ">")); 113 } 114 } 115 116 return sb.toString(); 117 } 118 119 private boolean isTagWelcome(Node node) 120 { 121 Tag tag = (Tag)node; 122 123 if (!welcomeTags.contains(tag.getTagName())) { 124 return false; 125 } 126 127 this.checkAndValidateAttributes(tag); 128 129 return true; 130 } 131 132 private void checkAndValidateAttributes(Tag tag) 133 { 134 Vector newAttributes = new Vector (); 135 136 for (Iterator iter = tag.getAttributesEx().iterator(); iter.hasNext(); ) { 137 Attribute a = (Attribute)iter.next(); 138 139 String name = a.getName(); 140 if (name != null) { 141 name = name.toLowerCase(); 142 if (("href".equals(name) || "src".equals(name)) && a.getValue() != null) { 143 if (a.getValue().toLowerCase().indexOf("javascript:") > -1) { 144 a.setValue("#"); 145 } 146 else if (a.getValue().indexOf("&#") > -1) { 147 a.setValue(a.getValue().replaceAll("&#", "&#")); 148 } 149 150 newAttributes.add(a); 151 } 152 else if (!name.startsWith("on") && !name.startsWith("style")) { 153 newAttributes.add(a); 154 } 155 } 156 else { 157 newAttributes.add(a); 158 } 159 } 160 161 tag.setAttributesEx(newAttributes); 162 } 163 164 169 public static String avoidJavascript(String contents) 170 { 171 try { 172 return new SafeHtml().processAllNodes(contents, true); 173 } 174 catch (Exception e) { 175 throw new ForumException("Problems while parsing HTML: " + e, e); 176 } 177 } 178 179 184 public static String makeSafe(String contents) 185 { 186 if (contents == null || contents.trim().length() == 0) { 187 return contents; 188 } 189 190 try { 191 contents = new SafeHtml().processAllNodes(contents, false); 192 } 193 catch (Exception e) { 194 throw new ForumException("Problems while parsing HTML: " + e, e); 195 } 196 197 return contents; 198 } 199 } 200 | Popular Tags |