All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.imunity.vaadin.endpoint.common.safe_html.HtmlEscapers Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2013 ICM Uniwersytet Warszawski All rights reserved.
 * See LICENCE.txt file for licensing information.
 */
package io.imunity.vaadin.endpoint.common.safe_html;

import com.google.common.collect.Sets;
import com.google.common.collect.Sets.SetView;

import java.util.*;

/**
 * HTML escpers commonly used in front-end to parse user input before
 * displaying.
 *
 * @author Roman Krysinski ([email protected])
 */
public final class HtmlEscapers
{
	public static final Set ALLOWED;
	public static final Map ESCAPES;
	private static int MAX_TOKEN_LEN;
	
	static
	{
		Set vals = new HashSet<>();
		addTag(vals, "b");
		addTag(vals, "i");
		addTag(vals, "h1");
		addTag(vals, "h2");
		addTag(vals, "h3");
		addTag(vals, "small");
		addTag(vals, "code");

		addTagS(vals, "br");
		addTagS(vals, "hr");
		ALLOWED = Collections.unmodifiableSet(vals);
		
		Map escapeV = new HashMap<>();
		escapeV.put('"', """);
		escapeV.put('\'', "'");
		escapeV.put('&', "&");
		escapeV.put('<', "<");
		escapeV.put('>', ">");
		ESCAPES = Collections.unmodifiableMap(escapeV);
	}
	
	public static String escape(String html)
	{
		return com.google.common.html.HtmlEscapers.htmlEscaper().escape(html);
	}

	/**
	 * Escape the HTML string including several simple HTML tags. It is allowed
	 * to use: <br>, <b>, <i>, <h1>, <h2>,
	 * <h3>, <small> <hr> <code> tags and their
	 * corresponding closing tags (where appropriate). The tags must be entered
	 * literally, no additional spaces nor tag arguments are allowed. However
	 * upper case version are also permitted. 
	 * All other suspicious characters escaped.
	 */
	public static String simpleEscape(String semiSafeHtml)
	{
		StringBuilder escaped = new StringBuilder();
		if (semiSafeHtml == null)
			return "";
		char[] input = semiSafeHtml.toCharArray();
		for (int i=0; i aheadTokens = new HashSet<>();
				for (int j=3; j<=readAheadMax; j++)
				{
					aheadTokens.add(new String(input, i, j));
				}
				
				SetView intersection = Sets.intersection(ALLOWED, aheadTokens);
				if (intersection.size() == 1)
				{
					String allowedToken = intersection.iterator().next();
					escaped.append(allowedToken);
					i += allowedToken.length() - 1;
				} else
				{
					escaped.append(ESCAPES.get(input[i]));
				}
			} else
			{
				escaped.append(input[i]);
			}
		}
		
		return escaped.toString();
	}
	
	private static void addTag(Set whereto, String tag)
	{
		Collections.addAll(whereto, "<"+ tag + ">", "<"+ tag.toUpperCase() + ">", 
				"", "");
		if (tag.length() + 3 > MAX_TOKEN_LEN)
			MAX_TOKEN_LEN = tag.length() + 3;
	}

	private static void addTagS(Set whereto, String tag)
	{
		Collections.addAll(whereto, "<"+ tag + ">", "<"+ tag.toUpperCase() + ">");
		if (tag.length() + 2 > MAX_TOKEN_LEN)
			MAX_TOKEN_LEN = tag.length() + 2;
	}
	
	private HtmlEscapers() {}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy