Use response encoding when escaping HTML
With SPR-9293, it is now possible to HTML escape text while taking into
account the current response encoding. When using UTF-* encodings, only
XML markup significant characters are escaped, since UTF-* natively
support those characters.
This commit adds a new servlet context parameter to enable this fix by
default in a Spring MVC application:
<context-param>
<param-name>responseEncodedHtmlEscape</param-name>
<param-value>true</param-value>
</context-param>
Issue: SPR-12350, SPR-12132
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -115,6 +115,8 @@ public class RequestContext {
|
||||
|
||||
private Boolean defaultHtmlEscape;
|
||||
|
||||
private Boolean responseEncodedHtmlEscape;
|
||||
|
||||
private UrlPathHelper urlPathHelper;
|
||||
|
||||
private RequestDataValueProcessor requestDataValueProcessor;
|
||||
@@ -263,6 +265,8 @@ public class RequestContext {
|
||||
// context-param in web.xml, if any.
|
||||
this.defaultHtmlEscape = WebUtils.getDefaultHtmlEscape(this.webApplicationContext.getServletContext());
|
||||
|
||||
this.responseEncodedHtmlEscape = WebUtils.getResponseEncodedHtmlEscape(this.webApplicationContext.getServletContext());
|
||||
|
||||
this.urlPathHelper = new UrlPathHelper();
|
||||
|
||||
if (this.webApplicationContext.containsBean(REQUEST_DATA_VALUE_PROCESSOR_BEAN_NAME)) {
|
||||
@@ -484,6 +488,27 @@ public class RequestContext {
|
||||
return this.defaultHtmlEscape;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is HTML escaping using the response encoding by default?
|
||||
* If enabled, only XML markup significant characters will be escaped with UTF-* encodings.
|
||||
* <p>Falls back to {@code false} in case of no explicit default given.
|
||||
* @since 4.1.2
|
||||
*/
|
||||
public boolean isResponseEncodedHtmlEscape() {
|
||||
return (this.responseEncodedHtmlEscape != null && this.responseEncodedHtmlEscape.booleanValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default setting about use of response encoding for HTML escape setting,
|
||||
* differentiating between no default specified and an explicit value.
|
||||
* @return whether default use of response encoding HTML escaping is enabled (null = no explicit default)
|
||||
* @since 4.1.2
|
||||
*/
|
||||
public Boolean getResponseEncodedHtmlEscape() {
|
||||
return this.responseEncodedHtmlEscape;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the UrlPathHelper to use for context path and request URI decoding.
|
||||
* Can be used to pass a shared UrlPathHelper instance in.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,7 +21,6 @@ import javax.servlet.jsp.JspException;
|
||||
import javax.servlet.jsp.tagext.BodyContent;
|
||||
import javax.servlet.jsp.tagext.BodyTag;
|
||||
|
||||
import org.springframework.web.util.HtmlUtils;
|
||||
import org.springframework.web.util.JavaScriptUtils;
|
||||
|
||||
/**
|
||||
@@ -79,7 +78,7 @@ public class EscapeBodyTag extends HtmlEscapingAwareTag implements BodyTag {
|
||||
try {
|
||||
String content = readBodyContent();
|
||||
// HTML and/or JavaScript escape, if demanded
|
||||
content = isHtmlEscape() ? HtmlUtils.htmlEscape(content) : content;
|
||||
content = htmlEscape(content);
|
||||
content = this.javaScriptEscape ? JavaScriptUtils.javaScriptEscape(content) : content;
|
||||
writeBodyContent(content);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -34,7 +34,6 @@ import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.expression.spel.support.StandardTypeConverter;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.web.util.HtmlUtils;
|
||||
import org.springframework.web.util.JavaScriptUtils;
|
||||
import org.springframework.web.util.TagUtils;
|
||||
|
||||
@@ -121,7 +120,7 @@ public class EvalTag extends HtmlEscapingAwareTag {
|
||||
try {
|
||||
String result = this.expression.getValue(evaluationContext, String.class);
|
||||
result = ObjectUtils.getDisplayString(result);
|
||||
result = (isHtmlEscape() ? HtmlUtils.htmlEscape(result) : result);
|
||||
result = htmlEscape(result);
|
||||
result = (this.javaScriptEscape ? JavaScriptUtils.javaScriptEscape(result) : result);
|
||||
this.pageContext.getOut().print(result);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,6 +18,8 @@ package org.springframework.web.servlet.tags;
|
||||
|
||||
import javax.servlet.jsp.JspException;
|
||||
|
||||
import org.springframework.web.util.HtmlUtils;
|
||||
|
||||
/**
|
||||
* Superclass for tags that output content that might get HTML-escaped.
|
||||
*
|
||||
@@ -31,7 +33,8 @@ import javax.servlet.jsp.JspException;
|
||||
* @see #setHtmlEscape
|
||||
* @see HtmlEscapeTag
|
||||
* @see org.springframework.web.servlet.support.RequestContext#isDefaultHtmlEscape
|
||||
* @see org.springframework.web.util.WebUtils#isDefaultHtmlEscape
|
||||
* @see org.springframework.web.util.WebUtils#getDefaultHtmlEscape
|
||||
* @see org.springframework.web.util.WebUtils#getResponseEncodedHtmlEscape
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public abstract class HtmlEscapingAwareTag extends RequestContextAwareTag {
|
||||
@@ -72,4 +75,37 @@ public abstract class HtmlEscapingAwareTag extends RequestContextAwareTag {
|
||||
return getRequestContext().isDefaultHtmlEscape();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the applicable default for the use of response encoding with HTML escape for this tag.
|
||||
* <p>The default implementation checks the RequestContext's setting,
|
||||
* falling back to {@code false} in case of no explicit default given.
|
||||
* @see #getRequestContext()
|
||||
* @since 4.1.2
|
||||
*/
|
||||
protected boolean isResponseEncodedHtmlEscape() {
|
||||
return getRequestContext().isResponseEncodedHtmlEscape();
|
||||
}
|
||||
|
||||
/**
|
||||
* HTML encodes the given string, only if the htmlEscape setting is enabled.
|
||||
* The response encoding will be taken into account if the responseEncodedHtmlEscape setting is enabled.
|
||||
* @param content
|
||||
* @return
|
||||
* @see #isHtmlEscape()
|
||||
* @see #isResponseEncodedHtmlEscape()
|
||||
* @since 4.1.2
|
||||
*/
|
||||
protected String htmlEscape(String content) {
|
||||
String out = content;
|
||||
if(isHtmlEscape()) {
|
||||
if(isResponseEncodedHtmlEscape()) {
|
||||
out = HtmlUtils.htmlEscape(content, this.pageContext.getResponse().getCharacterEncoding());
|
||||
}
|
||||
else {
|
||||
out = HtmlUtils.htmlEscape(content);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -28,7 +28,6 @@ import org.springframework.context.MessageSourceResolvable;
|
||||
import org.springframework.context.NoSuchMessageException;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.util.HtmlUtils;
|
||||
import org.springframework.web.util.JavaScriptUtils;
|
||||
import org.springframework.web.util.TagUtils;
|
||||
|
||||
@@ -181,7 +180,7 @@ public class MessageTag extends HtmlEscapingAwareTag implements ArgumentAware {
|
||||
String msg = resolveMessage();
|
||||
|
||||
// HTML and/or JavaScript escape, if demanded.
|
||||
msg = isHtmlEscape() ? HtmlUtils.htmlEscape(msg) : msg;
|
||||
msg = htmlEscape(msg);
|
||||
msg = this.javaScriptEscape ? JavaScriptUtils.javaScriptEscape(msg) : msg;
|
||||
|
||||
// Expose as variable, if demanded, else write to the page.
|
||||
|
||||
@@ -105,7 +105,7 @@ public class TransformTag extends HtmlEscapingAwareTag {
|
||||
// Else, just do a toString.
|
||||
result = this.value.toString();
|
||||
}
|
||||
result = isHtmlEscape() ? HtmlUtils.htmlEscape(result) : result;
|
||||
result = htmlEscape(result);
|
||||
if (this.var != null) {
|
||||
pageContext.setAttribute(this.var, result, TagUtils.getScope(this.scope));
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ public class UrlTag extends HtmlEscapingAwareTag implements ParamAware {
|
||||
}
|
||||
|
||||
// HTML and/or JavaScript escape, if demanded.
|
||||
urlStr = isHtmlEscape() ? HtmlUtils.htmlEscape(urlStr) : urlStr;
|
||||
urlStr = htmlEscape(urlStr);
|
||||
urlStr = this.javaScriptEscape ? JavaScriptUtils.javaScriptEscape(urlStr) : urlStr;
|
||||
|
||||
return urlStr;
|
||||
|
||||
Reference in New Issue
Block a user