Skip to content

Instantly share code, notes, and snippets.

@benelog
Created December 5, 2012 04:32
Show Gist options
  • Save benelog/4212252 to your computer and use it in GitHub Desktop.
Save benelog/4212252 to your computer and use it in GitHub Desktop.
HtmlEscape
package net.benelog.markerboard.presentation;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import net.benelog.markerboard.support.ParamUtils;
public class HtmlEscapeFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest escapedRequest = new HtmlEscapedHttpServletRequest((HttpServletRequest)request);
chain.doFilter(escapedRequest, response);
}
@Override
public void destroy() {
}
static class HtmlEscapedHttpServletRequest extends HttpServletRequestWrapper {
public HtmlEscapedHttpServletRequest(HttpServletRequest request) {
super(request);
}
public String getParameter(String name) {
String original = super.getRequest().getParameter(name);
return ParamUtils.escapeHtml(original);
}
public String[] getParameterValues(String name) {
String[] original = super.getRequest().getParameterValues(name);
String[] escaped = new String[original.length];
for(int i=0, n= original.length; i<n; i ++) {
escaped[i] = ParamUtils.escapeHtml(original[i]);
}
return escaped;
}
}
}
package net.benelog.markerboard.presentation;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.ServletException;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.mock.web.MockFilterChain;
import org.springframework.mock.web.MockFilterConfig;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
public class HtmlEscapeFilterTest {
Filter filter = new HtmlEscapeFilter();
MockFilterChain chain = new MockFilterChain();
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
@Before
public void setUp() throws ServletException {
filter.init(new MockFilterConfig());
}
@Test
public void getParameter() throws IOException, ServletException {
request.addParameter("name", "<script>alert(1);</script>");
filter.doFilter(request, response, chain);
String escaped = chain.getRequest().getParameter("name");
assertThat(escaped,is("&lt;script&gt;alert(1);&lt;/script&gt;"));
}
@Test
public void getParameterValues() throws IOException, ServletException {
request.addParameter("name", "<script>alert(1);</script>");
request.addParameter("name", "<script>alert(2);</script>");
filter.doFilter(request, response, chain);
String[] escaped = chain.getRequest().getParameterValues("name");
assertThat(escaped[0],is("&lt;script&gt;alert(1);&lt;/script&gt;"));
assertThat(escaped[1],is("&lt;script&gt;alert(2);&lt;/script&gt;"));
}
@After
public void tearDown() {
filter.destroy();
}
}
package net.benelog.markerboard.support;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
public abstract class ParamUtils {
static final String[] HTML_CHAR_LIST = new String[]{"<", ">"};
static final String[] HTML_ESCAPE_CHAR_LIST = new String[]{"&lt;", "&gt;"};
public static String escapeHtml(String original) {
// org.apache.commons.lang.StringEscapeUtils를 고려했으나
// <, > 두 문자만 치환하면 충분하다고 판단하여서 StringUtils.replaceEach를 사용.
return StringUtils.replaceEach(original, HTML_CHAR_LIST, HTML_ESCAPE_CHAR_LIST);
}
public static String unescapeHtml(String escaped) {
return StringUtils.replaceEach(escaped, HTML_ESCAPE_CHAR_LIST, HTML_CHAR_LIST);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment