mirror of
https://github.com/apache/struts.git
synced 2026-08-05 14:47:09 +00:00
Merge pull request #523 from apache/WW-5022-escape-false
[WW-5022] Sets escapeHtmlBody to false by default and defines a new flag
This commit is contained in:
@@ -113,7 +113,7 @@
|
||||
|
||||
<div id="navbar" class="navbar-collapse collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
<li><s:a value="%{home}" escapeHtmlBody="false"><i class="glyphicon glyphicon-home"></i> Home</s:a></li>
|
||||
<li><s:a value="%{home}"><i class="glyphicon glyphicon-home"></i> Home</s:a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
<i class="glyphicon glyphicon-cog"></i> Configuration
|
||||
@@ -239,7 +239,7 @@
|
||||
</li>
|
||||
<li><s:a value="/person/index.html">Person Manager</s:a></li>
|
||||
<li><s:a value="/skill/index.html">CRUD</s:a></li>
|
||||
<li><s:a value="/wait/index.html" escapeHtmlBody="false">Execute & Wait</s:a></li>
|
||||
<li><s:a value="/wait/index.html">Execute & Wait</s:a></li>
|
||||
<li><s:a value="/token/index.html">Token</s:a></li>
|
||||
<li><s:url var="url" namespace="/modelDriven" action="modelDriven"/><s:a
|
||||
href="%{url}">Model Driven</s:a></li>
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
</div>
|
||||
|
||||
<s:url var="url" action="download"/>
|
||||
<s:a href="%{url}" cssClass="btn btn-large btn-info" escapeHtmlBody="false"><i class="icon-picture"></i> Download image file.</s:a>
|
||||
<s:a href="%{url}" cssClass="btn btn-large btn-info"><i class="icon-picture"></i> Download image file.</s:a>
|
||||
</div>
|
||||
<div class="col-md-6" style="text-align: center;">
|
||||
<div class="alert alert-info">
|
||||
@@ -47,7 +47,7 @@
|
||||
</div>
|
||||
|
||||
<s:url var="url" action="download2"/>
|
||||
<s:a href="%{url}" cssClass="btn btn-large btn-info" escapeHtmlBody="false"><i class="icon-download-alt"></i> Download ZIP file.</s:a>
|
||||
<s:a href="%{url}" cssClass="btn btn-large btn-info"><i class="icon-download-alt"></i> Download ZIP file.</s:a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -125,7 +125,7 @@
|
||||
<#else>
|
||||
<img src="<@s.property value="%{#looseImageUrl}" />" width="381" height="44" />
|
||||
</#if>
|
||||
<@s.a href="%{#startHref}" escapeHtmlBody="false">
|
||||
<@s.a href="%{#startHref}">
|
||||
<img src="<@s.property value="%{#startImageUrl}" />" width="250" height="43" />
|
||||
</@s.a>
|
||||
<#else>
|
||||
@@ -139,7 +139,7 @@
|
||||
|
||||
<@s.a href="%{#url}"
|
||||
id="%{#currentCharacter}"
|
||||
escapeHtmlBody="false"
|
||||
|
||||
>
|
||||
<img height="36" alt="" src="<@s.property value="%{#chalkboardImageUrl}" />" width="36" border="0" />
|
||||
</@s.a>
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<@s.submit value="Create person" cssClass="btn btn-primary" escapeHtmlBody="false"/>
|
||||
<@s.submit value="Create person" cssClass="btn btn-primary"/>
|
||||
</div>
|
||||
</@s.form>
|
||||
</div>
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
<p>The text you've entered is ${text!''}<p/>
|
||||
|
||||
<@s.a href="javascript:history.back();" cssClass="btn btn-info" escapeHtmlBody="false"><i class="icon icon-arrow-left"></i> Back</@s.a>
|
||||
<@s.a href="javascript:history.back();" cssClass="btn btn-info"><i class="icon icon-arrow-left"></i> Back</@s.a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+4
-4
@@ -57,13 +57,13 @@
|
||||
|
||||
<@s.textfield label="Enter Some Text" name="text" />
|
||||
|
||||
<@s.submit action="actionPrefix" value="%{'action prefix'}" cssClass="btn" escapeHtmlBody="false" />
|
||||
<@s.submit action="actionPrefix" value="%{'action prefix'}" cssClass="btn" />
|
||||
|
||||
<@s.submit method="alternateMethod" value="%{'method prefix'}" cssClass="btn" escapeHtmlBody="false" />
|
||||
<@s.submit method="alternateMethod" value="%{'method prefix'}" cssClass="btn" />
|
||||
|
||||
<@s.submit value="Normal Submit" cssClass="btn" escapeHtmlBody="false" />
|
||||
<@s.submit value="Normal Submit" cssClass="btn" />
|
||||
|
||||
<@s.submit action="redirectActionPrefixAction" value="%{'redirectAction without prefix'}" cssClass="btn" escapeHtmlBody="false" />
|
||||
<@s.submit action="redirectActionPrefixAction" value="%{'redirectAction without prefix'}" cssClass="btn" />
|
||||
|
||||
</@s.form>
|
||||
</div>
|
||||
|
||||
@@ -32,10 +32,10 @@
|
||||
<div class="col-md-12">
|
||||
|
||||
<p>You have come to this page because you used an <strong>method</strong> prefix.<p/>
|
||||
|
||||
|
||||
<p>The text you've enter is ${text!''}<p/>
|
||||
|
||||
<@s.a href="javascript:history.back();" cssClass="btn btn-info" escapeHtmlBody="false"><i class="icon icon-arrow-left"></i> Back</@s.a>
|
||||
<@s.a href="javascript:history.back();" cssClass="btn btn-info"><i class="icon icon-arrow-left"></i> Back</@s.a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -32,10 +32,10 @@
|
||||
<div class="col-md-12">
|
||||
|
||||
<p>You have come to this page because you did a normal submit.<p/>
|
||||
|
||||
|
||||
<p>The text you've enter is %{text}<p/>
|
||||
|
||||
<@s.a href="javascript:history.back();" cssClass="btn btn-info" escapeHtmlBody="false"><i class="icon icon-arrow-left"></i> Back</@s.a>
|
||||
<@s.a href="javascript:history.back();" cssClass="btn btn-info"><i class="icon icon-arrow-left"></i> Back</@s.a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+2
-2
@@ -32,13 +32,13 @@
|
||||
<div class="col-md-12">
|
||||
|
||||
<p>You have come to this page because you used an 'redirect-action' prefix.<p/>
|
||||
|
||||
|
||||
<p>Because this is a <strong>redirect-action</strong>, the text will be lost, due to a redirection
|
||||
implies a new request being issued from the client.<p/>
|
||||
|
||||
The text you've enter is ${text!''}<p/>
|
||||
|
||||
<@s.a href="javascript:history.back();" cssClass="btn btn-info" escapeHtmlBody="false"><i class="icon icon-arrow-left"></i> Back</@s.a>
|
||||
<@s.a href="javascript:history.back();" cssClass="btn btn-info"><i class="icon icon-arrow-left"></i> Back</@s.a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@
|
||||
</s:iterator>
|
||||
|
||||
<s:url var="url" action="showAppendTagDemo" namespace="/tags/non-ui/appendIteratorTag" />
|
||||
<s:a href="%{#url}" cssClass="btn btn-info" escapeHtmlBody="false"><i class="icon icon-arrow-left"></i> Back To Input</s:a>
|
||||
<s:a href="%{#url}" cssClass="btn btn-info"><i class="icon icon-arrow-left"></i> Back To Input</s:a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@
|
||||
|
||||
|
||||
<s:url var="url" action="showGeneratorTagDemo" namespace="/tags/non-ui/iteratorGeneratorTag" />
|
||||
<s:a href="%{#url}" cssClass="btn btn-info" escapeHtmlBody="false"><i class="icon icon-arrow-left"></i> Back To Input</s:a>
|
||||
<s:a href="%{#url}" cssClass="btn btn-info"><i class="icon icon-arrow-left"></i> Back To Input</s:a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@
|
||||
</s:iterator>
|
||||
|
||||
<s:url var="url" action="showMergeTagDemo" namespace="/tags/non-ui/mergeIteratorTag" />
|
||||
<s:a href="%{#url}" cssClass="btn btn-info" escapeHtmlBody="false"><i class="icon icon-arrow-left"></i> Back To Input</s:a>
|
||||
<s:a href="%{#url}" cssClass="btn btn-info"><i class="icon icon-arrow-left"></i> Back To Input</s:a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@
|
||||
</s:subset>
|
||||
|
||||
<s:url var="url" action="showSubsetTagDemo" namespace="/tags/non-ui/subsetIteratorTag" />
|
||||
<s:a href="%{#url}" cssClass="btn btn-info" escapeHtmlBody="false"><i class="icon icon-arrow-left"></i> Back To Input</s:a>
|
||||
<s:a href="%{#url}" cssClass="btn btn-info"><i class="icon icon-arrow-left"></i> Back To Input</s:a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
<@s.form action="transfer4">
|
||||
<@s.token/>
|
||||
<@s.textfield label="Amount" name="amount" required=true value="400"/>
|
||||
<@s.submit value="Transfer money" cssClass="btn btn-primary" escapeHtmlBody="false"/>
|
||||
<@s.submit value="Transfer money" cssClass="btn btn-primary"/>
|
||||
</@s.form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+1
-1
@@ -342,7 +342,7 @@
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<optional>true</optional>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- The Servlet API mocks in Spring Framework 4.x only supports Servlet 3.0 and higher.
|
||||
|
||||
@@ -132,6 +132,9 @@ public final class StrutsConstants {
|
||||
/** A path to static content, by default and from historical point of view it's /static. */
|
||||
public static final String STRUTS_UI_STATIC_CONTENT_PATH = "struts.ui.staticContentPath";
|
||||
|
||||
/** A global flag to enable/disable html body escaping in tags, can be overwritten per tag */
|
||||
public static final String STRUTS_UI_ESCAPE_HTML_BODY = "struts.ui.escapeHtmlBody";
|
||||
|
||||
/** The maximize size of a multipart request (file upload) */
|
||||
public static final String STRUTS_MULTIPART_MAXSIZE = "struts.multipart.maxSize";
|
||||
|
||||
@@ -380,4 +383,5 @@ public final class StrutsConstants {
|
||||
public static final String STRUTS_CHAINING_COPY_FIELD_ERRORS = "struts.chaining.copyFieldErrors";
|
||||
public static final String STRUTS_CHAINING_COPY_MESSAGES = "struts.chaining.copyMessages";
|
||||
public static final String STRUTS_OBJECT_FACTORY_CLASSLOADER = "struts.objectFactory.classloader";
|
||||
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ package org.apache.struts2.components;
|
||||
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
@@ -69,8 +70,7 @@ public class Anchor extends ClosingUIBean {
|
||||
protected UrlProvider urlProvider;
|
||||
protected UrlRenderer urlRenderer;
|
||||
protected boolean processingTagBody = false;
|
||||
protected boolean escapeHtmlBody = true;
|
||||
|
||||
|
||||
//these params are passed by the Param tag
|
||||
protected Map urlParameters = new LinkedHashMap();
|
||||
|
||||
@@ -96,18 +96,6 @@ public class Anchor extends ClosingUIBean {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override to set if body content should be HTML-escaped.
|
||||
*
|
||||
* @return true if body should be HTML-escaped, false otherwise.
|
||||
*
|
||||
* @since 2.6
|
||||
*/
|
||||
@Override
|
||||
public boolean escapeHtmlBody() {
|
||||
return escapeHtmlBody;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void evaluateExtraParams() {
|
||||
super.evaluateExtraParams();
|
||||
@@ -124,6 +112,8 @@ public class Anchor extends ClosingUIBean {
|
||||
addParameter("href", ensureAttributeSafelyNotEscaped(builtHref));
|
||||
}
|
||||
}
|
||||
|
||||
addParameter("escapeHtmlBody", escapeHtmlBody);
|
||||
}
|
||||
|
||||
@Inject(StrutsConstants.STRUTS_URL_INCLUDEPARAMS)
|
||||
@@ -276,7 +266,7 @@ public class Anchor extends ClosingUIBean {
|
||||
urlProvider.setForceAddSchemeHostAndPort(forceAddSchemeHostAndPort);
|
||||
}
|
||||
|
||||
@StrutsTagAttribute(required = false, description = "Specifies whether to HTML-escape the tag body or not", type = "Boolean", defaultValue = "true")
|
||||
@StrutsTagAttribute(description = "Specifies whether to HTML-escape the tag body or not", type = "Boolean", defaultValue = "false")
|
||||
public void setEscapeHtmlBody(boolean escapeHtmlBody) {
|
||||
this.escapeHtmlBody = escapeHtmlBody;
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@ public class Component {
|
||||
protected static ConcurrentMap<Class<?>, Collection<String>> standardAttributesMap = new ConcurrentHashMap<>();
|
||||
|
||||
protected boolean devMode = false;
|
||||
protected boolean escapeHtmlBody = false;
|
||||
protected ValueStack stack;
|
||||
protected Map<String, Object> parameters;
|
||||
protected ActionMapper actionMapper;
|
||||
@@ -116,6 +117,11 @@ public class Component {
|
||||
this.throwExceptionOnELFailure = BooleanUtils.toBoolean(throwException);
|
||||
}
|
||||
|
||||
@Inject(value = StrutsConstants.STRUTS_UI_ESCAPE_HTML_BODY, required = false)
|
||||
public void setEscapeHtmlBody(String escapeHtmlBody) {
|
||||
this.escapeHtmlBody = BooleanUtils.toBoolean(escapeHtmlBody);
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setUrlHelper(UrlHelper urlHelper) {
|
||||
this.urlHelper = urlHelper;
|
||||
@@ -213,13 +219,13 @@ public class Component {
|
||||
* @return the component if found, <tt>null</tt> if not.
|
||||
*/
|
||||
protected Component findAncestor(Class<?> clazz) {
|
||||
Stack componentStack = getComponentStack();
|
||||
Stack<Component> componentStack = getComponentStack();
|
||||
int currPosition = componentStack.search(this);
|
||||
if (currPosition >= 0) {
|
||||
int start = componentStack.size() - currPosition - 1;
|
||||
|
||||
for (int i = start; i >= 0; i--) {
|
||||
Component component = (Component) componentStack.get(i);
|
||||
Component component = componentStack.get(i);
|
||||
if (clazz.isAssignableFrom(component.getClass()) && component != this) {
|
||||
return component;
|
||||
}
|
||||
@@ -536,7 +542,7 @@ public class Component {
|
||||
* @since 2.6
|
||||
*/
|
||||
public boolean escapeHtmlBody() {
|
||||
return true;
|
||||
return escapeHtmlBody;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -572,16 +578,16 @@ public class Component {
|
||||
/**
|
||||
* Request that the tag state be cleared during {@link org.apache.struts2.views.jsp.StrutsBodyTagSupport#doEndTag()} processing,
|
||||
* which may help with certain edge cases with tag logic running on servers that implement JSP Tag Pooling.
|
||||
*
|
||||
* <em>Note:</em> All Tag classes that extend {@link org.apache.struts2.views.jsp.StrutsBodyTagSupport} must implement a setter for
|
||||
*
|
||||
* <em>Note:</em> All Tag classes that extend {@link org.apache.struts2.views.jsp.StrutsBodyTagSupport} must implement a setter for
|
||||
* this attribute (same name), and it must be defined at the Tag class level.
|
||||
* Defining a setter in the superclass alone is insufficient (results in "Cannot find a setter method for the attribute").
|
||||
*
|
||||
*
|
||||
* See {@link org.apache.struts2.views.jsp.StrutsBodyTagSupport#clearTagStateForTagPoolingServers() for additional details.
|
||||
*
|
||||
*
|
||||
* @param performClearTagStateForTagPoolingServers true if tag state should be cleared, false otherwise.
|
||||
*/
|
||||
@StrutsTagAttribute(description="Whether to clear all tag state during doEndTag() processing (if applicable)", type="Boolean", defaultValue="false", required = false)
|
||||
@StrutsTagAttribute(description="Whether to clear all tag state during doEndTag() processing (if applicable)", type="Boolean", defaultValue="false")
|
||||
public void setPerformClearTagStateForTagPoolingServers(boolean performClearTagStateForTagPoolingServers) {
|
||||
this.performClearTagStateForTagPoolingServers = performClearTagStateForTagPoolingServers;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,9 @@ import java.io.Writer;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.views.annotations.StrutsTag;
|
||||
import org.apache.struts2.views.annotations.StrutsTagAttribute;
|
||||
|
||||
@@ -54,7 +57,6 @@ public class Submit extends FormButton {
|
||||
final public static String OPEN_TEMPLATE = "submit";
|
||||
final public static String TEMPLATE = "submit-close";
|
||||
protected String src;
|
||||
protected boolean escapeHtmlBody = true;
|
||||
|
||||
public Submit(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
|
||||
super(stack, request, response);
|
||||
@@ -73,7 +75,7 @@ public class Submit extends FormButton {
|
||||
value = "Submit";
|
||||
}
|
||||
|
||||
if (((key != null)) && (value == null)) {
|
||||
if ((key != null) && (value == null)) {
|
||||
this.value = "%{getText('"+key +"')}";
|
||||
}
|
||||
|
||||
@@ -83,8 +85,11 @@ public class Submit extends FormButton {
|
||||
public void evaluateExtraParams() {
|
||||
super.evaluateExtraParams();
|
||||
|
||||
if (src != null)
|
||||
if (src != null) {
|
||||
addParameter("src", findString(src));
|
||||
}
|
||||
|
||||
addParameter("escapeHtmlBody", escapeHtmlBody);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -101,7 +106,7 @@ public class Submit extends FormButton {
|
||||
this.src = src;
|
||||
}
|
||||
|
||||
@StrutsTagAttribute(required = false, description = "Specifies whether to HTML-escape the tag body or not", type = "Boolean", defaultValue = "true")
|
||||
@StrutsTagAttribute(description = "Specifies whether to HTML-escape the tag body or not", type = "Boolean", defaultValue = "false")
|
||||
public void setEscapeHtmlBody(boolean escapeHtmlBody) {
|
||||
this.escapeHtmlBody = escapeHtmlBody;
|
||||
}
|
||||
@@ -111,18 +116,6 @@ public class Submit extends FormButton {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override to set if body content should be HTML-escaped.
|
||||
*
|
||||
* @return true if body should be HTML-escaped, false otherwise.
|
||||
*
|
||||
* @since 2.6
|
||||
*/
|
||||
@Override
|
||||
public boolean escapeHtmlBody() {
|
||||
return escapeHtmlBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides to be able to render body in a template rather than always before the template
|
||||
*/
|
||||
|
||||
@@ -47,13 +47,13 @@ public class AnchorTag extends AbstractClosingTag {
|
||||
protected String portletUrlType;
|
||||
protected String anchor;
|
||||
protected String forceAddSchemeHostAndPort;
|
||||
protected boolean escapeHtmlBody = true; // Default - escape HTML body
|
||||
protected String escapeHtmlBody;
|
||||
|
||||
@Override
|
||||
public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
|
||||
return new Anchor(stack, req, res);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void populateParams() {
|
||||
super.populateParams();
|
||||
@@ -80,10 +80,12 @@ public class AnchorTag extends AbstractClosingTag {
|
||||
if (escapeAmp != null) {
|
||||
tag.setEscapeAmp(BooleanUtils.toBoolean(escapeAmp));
|
||||
}
|
||||
if (forceAddSchemeHostAndPort != null) {
|
||||
if (forceAddSchemeHostAndPort != null) {
|
||||
tag.setForceAddSchemeHostAndPort(BooleanUtils.toBoolean(forceAddSchemeHostAndPort));
|
||||
}
|
||||
tag.setEscapeHtmlBody(escapeHtmlBody);
|
||||
if (escapeHtmlBody != null) {
|
||||
tag.setEscapeHtmlBody(escapeHtmlBody);
|
||||
}
|
||||
}
|
||||
|
||||
public void setHref(String href) {
|
||||
@@ -149,12 +151,12 @@ public class AnchorTag extends AbstractClosingTag {
|
||||
|
||||
/**
|
||||
* Set via parameter to control if body content should be HTML-escaped.
|
||||
*
|
||||
* @param escapeHtmlBody
|
||||
*
|
||||
*
|
||||
* @param escapeHtmlBody
|
||||
*
|
||||
* @since 2.6
|
||||
*/
|
||||
public void setEscapeHtmlBody(boolean escapeHtmlBody) {
|
||||
public void setEscapeHtmlBody(String escapeHtmlBody) {
|
||||
this.escapeHtmlBody = escapeHtmlBody;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ public class SubmitTag extends AbstractClosingTag {
|
||||
protected String method;
|
||||
protected String type;
|
||||
protected String src;
|
||||
protected boolean escapeHtmlBody = true; // Default - escape HTML body
|
||||
protected boolean escapeHtmlBody = false;
|
||||
|
||||
@Override
|
||||
public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
|
||||
@@ -78,9 +78,9 @@ public class SubmitTag extends AbstractClosingTag {
|
||||
|
||||
/**
|
||||
* Set via parameter to control if body content should be HTML-escaped.
|
||||
*
|
||||
* @param escapeHtmlBody
|
||||
*
|
||||
*
|
||||
* @param escapeHtmlBody
|
||||
*
|
||||
* @since 2.6
|
||||
*/
|
||||
public void setEscapeHtmlBody(boolean escapeHtmlBody) {
|
||||
|
||||
@@ -151,6 +151,11 @@ struts.ui.theme.expansion.token=~~~
|
||||
### Sets the default template type. Either ftl, vm, or jsp
|
||||
struts.ui.templateSuffix=ftl
|
||||
|
||||
### Sets a global flag which will escape html body of Anchor, Submit and Component tag
|
||||
### You can control this flag per tag, e.g.: <s:a ... escapeHtmlTag="true">...</s:a>
|
||||
### and this take precedence over the global flag
|
||||
# struts.ui.escapeHtmlBody=true
|
||||
|
||||
### Configuration reloading
|
||||
### This will cause the configuration to reload struts.xml when it is changed
|
||||
# struts.configuration.xml.reload=false
|
||||
@@ -230,7 +235,7 @@ struts.handle.exception=true
|
||||
|
||||
### Applies maximum length allowed on OGNL expressions for security enhancement (optional)
|
||||
###
|
||||
### **WARNING**: If developers enable this option (by configuration) they should make sure that they understand the implications of setting
|
||||
### **WARNING**: If developers enable this option (by configuration) they should make sure that they understand the implications of setting
|
||||
### struts.ognl.expressionMaxLength. They must choose a value large enough to permit ALL valid OGNL expressions used within the application.
|
||||
### Values larger than the 200-400 range have diminishing security value (at which point it is really only a "style guard" for long OGNL
|
||||
### expressions in an application. Setting a value of null or "" will also disable the feature.
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
<tr>
|
||||
<td align="left" valign="top">escapeHtmlBody</td>
|
||||
<td align="left" valign="top">false</td>
|
||||
<td align="left" valign="top">true</td>
|
||||
<td align="left" valign="top">false</td>
|
||||
<td align="left" valign="top">false</td>
|
||||
<td align="left" valign="top">Boolean</td>
|
||||
<td align="left" valign="top">Specifies whether to HTML-escape the tag body or not</td>
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
<tr>
|
||||
<td align="left" valign="top">escapeHtmlBody</td>
|
||||
<td align="left" valign="top">false</td>
|
||||
<td align="left" valign="top">true</td>
|
||||
<td align="left" valign="top">false</td>
|
||||
<td align="left" valign="top">false</td>
|
||||
<td align="left" valign="top">Boolean</td>
|
||||
<td align="left" valign="top">Specifies whether to HTML-escape the tag body or not</td>
|
||||
|
||||
@@ -18,14 +18,11 @@
|
||||
*/
|
||||
package org.apache.struts2.components;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
import java.util.Stack;
|
||||
|
||||
import javax.servlet.jsp.tagext.TagSupport;
|
||||
|
||||
import com.opensymphony.xwork2.LocalizedTextProvider;
|
||||
import org.apache.struts2.StrutsException;
|
||||
import org.apache.struts2.TestConfigurationProvider;
|
||||
import org.apache.struts2.views.jsp.AbstractTagTest;
|
||||
import org.apache.struts2.views.jsp.ActionTag;
|
||||
import org.apache.struts2.views.jsp.BeanTag;
|
||||
import org.apache.struts2.views.jsp.ElseIfTag;
|
||||
import org.apache.struts2.views.jsp.ElseTag;
|
||||
@@ -42,17 +39,19 @@ import org.apache.struts2.views.jsp.iterator.MergeIteratorTag;
|
||||
import org.apache.struts2.views.jsp.ui.TextFieldTag;
|
||||
import org.apache.struts2.views.jsp.ui.UpDownSelectTag;
|
||||
|
||||
import javax.servlet.jsp.tagext.TagSupport;
|
||||
import java.util.HashMap;
|
||||
import org.apache.struts2.StrutsException;
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
import java.util.Stack;
|
||||
|
||||
/**
|
||||
* Test case for method findAncestor(Class) in Component and some commons
|
||||
* test cases for Component in general.
|
||||
*
|
||||
*/
|
||||
public class ComponentTest extends AbstractTagTest {
|
||||
|
||||
public void testFindAncestorTest() throws Exception {
|
||||
public void testFindAncestorTest() {
|
||||
Property property = new Property(stack);
|
||||
Form form = new Form(stack, request, response);
|
||||
ActionComponent actionComponent = new ActionComponent(stack, request, response);
|
||||
@@ -61,8 +60,8 @@ public class ComponentTest extends AbstractTagTest {
|
||||
TextField textField = new TextField(stack, request, response);
|
||||
|
||||
|
||||
Stack stack = property.getComponentStack();
|
||||
Iterator i = stack.iterator();
|
||||
Stack<Component> stack = property.getComponentStack();
|
||||
Iterator<Component> i = stack.iterator();
|
||||
|
||||
|
||||
try {
|
||||
@@ -107,8 +106,7 @@ public class ComponentTest extends AbstractTagTest {
|
||||
assertEquals(textField.findAncestor(Anchor.class), anchor);
|
||||
assertEquals(textField.findAncestor(ActionComponent.class), actionComponent);
|
||||
assertEquals(textField.findAncestor(Property.class), property);
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
property.getComponentStack().pop();
|
||||
property.getComponentStack().pop();
|
||||
property.getComponentStack().pop();
|
||||
@@ -118,16 +116,7 @@ public class ComponentTest extends AbstractTagTest {
|
||||
}
|
||||
|
||||
// Action Component
|
||||
/*
|
||||
public void testActionComponentDisposeItselfFromComponentStack() throws Exception {
|
||||
ConfigurationManager.clearConfigurationProviders();
|
||||
ConfigurationManager.addConfigurationProvider(new TestConfigurationProvider());
|
||||
ConfigurationManager.getConfiguration().reload();
|
||||
|
||||
ActionContext actionContext = new ActionContext(context);
|
||||
actionContext.setValueStack(stack);
|
||||
ActionContext.setContext(actionContext);
|
||||
|
||||
public void testActionComponentDisposeItselfFromComponentStack() {
|
||||
request.setupGetServletPath(TestConfigurationProvider.TEST_NAMESPACE + "/" + "foo.action");
|
||||
try {
|
||||
TextFieldTag t = new TextFieldTag();
|
||||
@@ -145,17 +134,14 @@ public class ComponentTest extends AbstractTagTest {
|
||||
assertEquals(t.getComponent().getComponentStack().peek(), t.getComponent());
|
||||
|
||||
t.doEndTag();
|
||||
}
|
||||
catch(Exception e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail(e.toString());
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
// AppendInterator
|
||||
public void testAppendIteratorDisposeItselfFromComponentStack() throws Exception {
|
||||
public void testAppendIteratorDisposeItselfFromComponentStack() {
|
||||
TextFieldTag t = new TextFieldTag();
|
||||
t.setPageContext(pageContext);
|
||||
t.setName("textFieldName");
|
||||
@@ -170,8 +156,7 @@ public class ComponentTest extends AbstractTagTest {
|
||||
tag.doEndTag();
|
||||
assertEquals(t.getComponent().getComponentStack().peek(), t.getComponent());
|
||||
t.doEndTag();
|
||||
}
|
||||
catch(Exception e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail(e.toString());
|
||||
}
|
||||
@@ -179,7 +164,7 @@ public class ComponentTest extends AbstractTagTest {
|
||||
|
||||
|
||||
// Bean
|
||||
public void testBeanComponentDisposeItselfFromComponentStack() throws Exception {
|
||||
public void testBeanComponentDisposeItselfFromComponentStack() {
|
||||
TextFieldTag t = new TextFieldTag();
|
||||
t.setPageContext(pageContext);
|
||||
t.setName("textFieldName");
|
||||
@@ -195,8 +180,7 @@ public class ComponentTest extends AbstractTagTest {
|
||||
tag.doEndTag();
|
||||
assertEquals(t.getComponent().getComponentStack().peek(), t.getComponent());
|
||||
t.doEndTag();
|
||||
}
|
||||
catch(Exception e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail();
|
||||
}
|
||||
@@ -204,7 +188,7 @@ public class ComponentTest extends AbstractTagTest {
|
||||
|
||||
|
||||
// ElseIf
|
||||
public void testElseIfComponentDisposeItselfFromComponentStack() throws Exception {
|
||||
public void testElseIfComponentDisposeItselfFromComponentStack() {
|
||||
TextFieldTag t = new TextFieldTag();
|
||||
t.setPageContext(pageContext);
|
||||
t.setName("textFieldName");
|
||||
@@ -219,8 +203,7 @@ public class ComponentTest extends AbstractTagTest {
|
||||
tag.doEndTag();
|
||||
assertEquals(t.getComponent().getComponentStack().peek(), t.getComponent());
|
||||
t.doEndTag();
|
||||
}
|
||||
catch(Exception e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail(e.toString());
|
||||
}
|
||||
@@ -228,7 +211,7 @@ public class ComponentTest extends AbstractTagTest {
|
||||
|
||||
|
||||
// Else
|
||||
public void testElseComponentDisposeItselfFromComponentStack() throws Exception {
|
||||
public void testElseComponentDisposeItselfFromComponentStack() {
|
||||
TextFieldTag t = new TextFieldTag();
|
||||
t.setPageContext(pageContext);
|
||||
t.setName("textFieldName");
|
||||
@@ -243,8 +226,7 @@ public class ComponentTest extends AbstractTagTest {
|
||||
tag.doEndTag();
|
||||
assertEquals(t.getComponent().getComponentStack().peek(), t.getComponent());
|
||||
t.doEndTag();
|
||||
}
|
||||
catch(Exception e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail(e.toString());
|
||||
}
|
||||
@@ -252,7 +234,7 @@ public class ComponentTest extends AbstractTagTest {
|
||||
|
||||
|
||||
// If
|
||||
public void testIfComponentDisposeItselfFromComponentStack() throws Exception {
|
||||
public void testIfComponentDisposeItselfFromComponentStack() {
|
||||
TextFieldTag t = new TextFieldTag();
|
||||
t.setPageContext(pageContext);
|
||||
t.setName("textFieldName");
|
||||
@@ -268,8 +250,7 @@ public class ComponentTest extends AbstractTagTest {
|
||||
tag.doEndTag();
|
||||
assertEquals(t.getComponent().getComponentStack().peek(), t.getComponent());
|
||||
t.doEndTag();
|
||||
}
|
||||
catch(Exception e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail(e.toString());
|
||||
}
|
||||
@@ -277,7 +258,7 @@ public class ComponentTest extends AbstractTagTest {
|
||||
|
||||
|
||||
// Iterator
|
||||
public void testIteratorComponentDisposeItselfFromComponentStack() throws Exception {
|
||||
public void testIteratorComponentDisposeItselfFromComponentStack() {
|
||||
TextFieldTag t = new TextFieldTag();
|
||||
t.setPageContext(pageContext);
|
||||
t.setName("textFieldName");
|
||||
@@ -291,15 +272,14 @@ public class ComponentTest extends AbstractTagTest {
|
||||
tag.doStartTag();
|
||||
assertEquals(tag.getComponent().getComponentStack().peek(), tag.getComponent());
|
||||
int endIt = tag.doAfterBody();
|
||||
while(TagSupport.EVAL_BODY_AGAIN == endIt) {
|
||||
while (TagSupport.EVAL_BODY_AGAIN == endIt) {
|
||||
assertEquals(tag.getComponent().getComponentStack().peek(), tag.getComponent());
|
||||
endIt = tag.doAfterBody();
|
||||
}
|
||||
tag.doEndTag();
|
||||
assertEquals(t.getComponent().getComponentStack().peek(), t.getComponent());
|
||||
t.doEndTag();
|
||||
}
|
||||
catch(Exception e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail(e.toString());
|
||||
}
|
||||
@@ -307,7 +287,7 @@ public class ComponentTest extends AbstractTagTest {
|
||||
|
||||
|
||||
// MergeIterator
|
||||
public void testMergeIteratorComponentDisposeItselfFromComponentStack() throws Exception {
|
||||
public void testMergeIteratorComponentDisposeItselfFromComponentStack() {
|
||||
TextFieldTag t = new TextFieldTag();
|
||||
t.setPageContext(pageContext);
|
||||
t.setName("textFieldName");
|
||||
@@ -322,8 +302,7 @@ public class ComponentTest extends AbstractTagTest {
|
||||
tag.doEndTag();
|
||||
assertEquals(t.getComponent().getComponentStack().peek(), t.getComponent());
|
||||
t.doEndTag();
|
||||
}
|
||||
catch(Exception e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail(e.toString());
|
||||
}
|
||||
@@ -331,7 +310,7 @@ public class ComponentTest extends AbstractTagTest {
|
||||
|
||||
|
||||
// Property
|
||||
public void testPropertyComponentDisposeItselfFromComponentStack() throws Exception {
|
||||
public void testPropertyComponentDisposeItselfFromComponentStack() {
|
||||
TextFieldTag t = new TextFieldTag();
|
||||
t.setPageContext(pageContext);
|
||||
t.setName("textFieldName");
|
||||
@@ -346,8 +325,7 @@ public class ComponentTest extends AbstractTagTest {
|
||||
tag.doEndTag();
|
||||
assertEquals(t.getComponent().getComponentStack().peek(), t.getComponent());
|
||||
t.doEndTag();
|
||||
}
|
||||
catch(Exception e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail(e.toString());
|
||||
}
|
||||
@@ -355,7 +333,7 @@ public class ComponentTest extends AbstractTagTest {
|
||||
|
||||
|
||||
// Push
|
||||
public void testPushComponentDisposeItselfFromComponentStack() throws Exception {
|
||||
public void testPushComponentDisposeItselfFromComponentStack() {
|
||||
TextFieldTag t = new TextFieldTag();
|
||||
t.setPageContext(pageContext);
|
||||
t.setName("textFieldName");
|
||||
@@ -371,8 +349,7 @@ public class ComponentTest extends AbstractTagTest {
|
||||
tag.doEndTag();
|
||||
assertEquals(t.getComponent().getComponentStack().peek(), t.getComponent());
|
||||
t.doEndTag();
|
||||
}
|
||||
catch(Exception e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail(e.toString());
|
||||
}
|
||||
@@ -380,7 +357,7 @@ public class ComponentTest extends AbstractTagTest {
|
||||
|
||||
|
||||
// Set
|
||||
public void testSetComponentDisposeItselfFromComponentStack() throws Exception {
|
||||
public void testSetComponentDisposeItselfFromComponentStack() {
|
||||
TextFieldTag t = new TextFieldTag();
|
||||
t.setPageContext(pageContext);
|
||||
t.setName("textFieldName");
|
||||
@@ -397,8 +374,7 @@ public class ComponentTest extends AbstractTagTest {
|
||||
tag.doEndTag();
|
||||
assertEquals(t.getComponent().getComponentStack().peek(), t.getComponent());
|
||||
t.doEndTag();
|
||||
}
|
||||
catch(Exception e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail(e.toString());
|
||||
}
|
||||
@@ -406,7 +382,7 @@ public class ComponentTest extends AbstractTagTest {
|
||||
|
||||
|
||||
// Text
|
||||
public void testTextComponentDisposeItselfFromComponentStack() throws Exception {
|
||||
public void testTextComponentDisposeItselfFromComponentStack() {
|
||||
TextFieldTag t = new TextFieldTag();
|
||||
t.setPageContext(pageContext);
|
||||
t.setName("textFieldName");
|
||||
@@ -422,15 +398,14 @@ public class ComponentTest extends AbstractTagTest {
|
||||
tag.doEndTag();
|
||||
assertEquals(t.getComponent().getComponentStack().peek(), t.getComponent());
|
||||
t.doEndTag();
|
||||
}
|
||||
catch(Exception e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void testI18nComponentDisposeItselfFromComponentStack() throws Exception {
|
||||
public void testI18nComponentDisposeItselfFromComponentStack() {
|
||||
stack.getActionContext().withLocale(Locale.getDefault());
|
||||
|
||||
TextFieldTag t = new TextFieldTag();
|
||||
@@ -450,15 +425,14 @@ public class ComponentTest extends AbstractTagTest {
|
||||
tag.doEndTag();
|
||||
assertEquals(t.getComponent().getComponentStack().peek(), t.getComponent());
|
||||
t.doEndTag();
|
||||
}
|
||||
catch(Exception e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
// URL
|
||||
public void testURLComponentDisposeItselfFromComponentStack() throws Exception {
|
||||
public void testURLComponentDisposeItselfFromComponentStack() {
|
||||
TextFieldTag t = new TextFieldTag();
|
||||
t.setPageContext(pageContext);
|
||||
t.setName("textFieldName");
|
||||
@@ -473,15 +447,14 @@ public class ComponentTest extends AbstractTagTest {
|
||||
tag.doEndTag();
|
||||
assertEquals(t.getComponent().getComponentStack().peek(), t.getComponent());
|
||||
t.doEndTag();
|
||||
}
|
||||
catch(Exception e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
// updownselect
|
||||
public void testUpDownSelectDisposeItselfFromComponentStack() throws Exception {
|
||||
public void testUpDownSelectDisposeItselfFromComponentStack() {
|
||||
TextFieldTag t = new TextFieldTag();
|
||||
t.setPageContext(pageContext);
|
||||
t.setName("textFieldName");
|
||||
@@ -499,8 +472,7 @@ public class ComponentTest extends AbstractTagTest {
|
||||
tag.doEndTag();
|
||||
assertEquals(t.getComponent().getComponentStack().peek(), t.getComponent());
|
||||
t.doEndTag();
|
||||
}
|
||||
catch(Exception e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail(e.toString());
|
||||
}
|
||||
@@ -508,22 +480,22 @@ public class ComponentTest extends AbstractTagTest {
|
||||
|
||||
/**
|
||||
* Test the expected default behaviour for component body state methods.
|
||||
*/
|
||||
*/
|
||||
public void testComponentDefaultBodyStates() {
|
||||
Component component = new Component(stack);
|
||||
// Test expected default results for: usesBody(), escapeHtmlBody().
|
||||
assertFalse("Component default usesBody not false ?", component.usesBody());
|
||||
assertTrue("Component default htmlEscapeBody not true ?", component.escapeHtmlBody());
|
||||
assertFalse("Component default htmlEscapeBody not false ?", component.escapeHtmlBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the behaviour for Anchor body state methods.
|
||||
*/
|
||||
*/
|
||||
public void testAnchorBodyStates() {
|
||||
Anchor anchor = new Anchor(stack, request, response);
|
||||
// Test expected default results for: usesBody(), escapeHtmlBody().
|
||||
assertTrue("Anchor default usesBody not true ?", anchor.usesBody());
|
||||
assertTrue("Anchor default htmlEscapeBody not true ?", anchor.escapeHtmlBody());
|
||||
assertFalse("Anchor default htmlEscapeBody not false ?", anchor.escapeHtmlBody());
|
||||
anchor.setEscapeHtmlBody(false);
|
||||
assertFalse("Anchor htmlEscapeBody not false after set false ?", anchor.escapeHtmlBody());
|
||||
anchor.setEscapeHtmlBody(true);
|
||||
@@ -532,12 +504,12 @@ public class ComponentTest extends AbstractTagTest {
|
||||
|
||||
/**
|
||||
* Test the behaviour for Submit body state methods.
|
||||
*/
|
||||
public void testAnchortBodyStates() {
|
||||
*/
|
||||
public void testSubmitBodyStates() {
|
||||
Submit submit = new Submit(stack, request, response);
|
||||
// Test expected default results for: usesBody(), escapeHtmlBody().
|
||||
assertTrue("Submit default usesBody not true ?", submit.usesBody());
|
||||
assertTrue("Submit default htmlEscapeBody not true ?", submit.escapeHtmlBody());
|
||||
assertFalse("Submit default htmlEscapeBody not false ?", submit.escapeHtmlBody());
|
||||
submit.setEscapeHtmlBody(false);
|
||||
assertFalse("Submit htmlEscapeBody not false after set false ?", submit.escapeHtmlBody());
|
||||
submit.setEscapeHtmlBody(true);
|
||||
@@ -547,10 +519,8 @@ public class ComponentTest extends AbstractTagTest {
|
||||
/**
|
||||
* Attempt some code coverage tests for {@link Component} that can be achieved without
|
||||
* too much difficulty.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testComponent_coverageTest() throws Exception {
|
||||
public void testComponent_coverageTest() {
|
||||
HashMap<String, Object> propertyMap = new HashMap<>();
|
||||
Exception exception = new Exception("Generic exception");
|
||||
Property property = new Property(stack);
|
||||
@@ -586,8 +556,7 @@ public class ComponentTest extends AbstractTagTest {
|
||||
assertFalse("Initial performClearTagStateForTagPoolingServers not false ?", actionComponent.getPerformClearTagStateForTagPoolingServers());
|
||||
actionComponent.setPerformClearTagStateForTagPoolingServers(true);
|
||||
assertTrue("performClearTagStateForTagPoolingServers false after setting to true ?", actionComponent.getPerformClearTagStateForTagPoolingServers());
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
property.getComponentStack().pop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,17 +18,15 @@
|
||||
*/
|
||||
package org.apache.struts2.views.jsp.ui;
|
||||
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.TestAction;
|
||||
import org.apache.struts2.components.Anchor;
|
||||
import org.apache.struts2.views.jsp.AbstractUITagTest;
|
||||
|
||||
import javax.servlet.jsp.JspException;
|
||||
import java.beans.BeanInfo;
|
||||
import java.beans.Introspector;
|
||||
import java.beans.PropertyDescriptor;
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
public class AnchorTest extends AbstractUITagTest {
|
||||
|
||||
public void testBeanInfo() throws Exception {
|
||||
@@ -72,7 +70,7 @@ public class AnchorTest extends AbstractUITagTest {
|
||||
AnchorTag freshTag = new AnchorTag();
|
||||
freshTag.setPerformClearTagStateForTagPoolingServers(true);
|
||||
freshTag.setPageContext(pageContext);
|
||||
assertTrue("Tag state after doEndTag() and explicit tag state clearing is inequal to new Tag with pageContext/parent set. " +
|
||||
assertTrue("Tag state after doEndTag() and explicit tag state clearing is unequal to new Tag with pageContext/parent set. " +
|
||||
"May indicate that clearTagStateForTagPoolingServers() calls are not working properly.",
|
||||
strutsBodyTagsAreReflectionEqual(tag, freshTag));
|
||||
}
|
||||
@@ -111,7 +109,7 @@ public class AnchorTest extends AbstractUITagTest {
|
||||
AnchorTag freshTag = new AnchorTag();
|
||||
freshTag.setPerformClearTagStateForTagPoolingServers(true);
|
||||
freshTag.setPageContext(pageContext);
|
||||
assertTrue("Tag state after doEndTag() and explicit tag state clearing is inequal to new Tag with pageContext/parent set. " +
|
||||
assertTrue("Tag state after doEndTag() and explicit tag state clearing is unequal to new Tag with pageContext/parent set. " +
|
||||
"May indicate that clearTagStateForTagPoolingServers() calls are not working properly.",
|
||||
strutsBodyTagsAreReflectionEqual(tag, freshTag));
|
||||
}
|
||||
@@ -156,7 +154,7 @@ public class AnchorTest extends AbstractUITagTest {
|
||||
AnchorTag freshTag = new AnchorTag();
|
||||
freshTag.setPerformClearTagStateForTagPoolingServers(true);
|
||||
freshTag.setPageContext(pageContext);
|
||||
assertTrue("Tag state after doEndTag() and explicit tag state clearing is inequal to new Tag with pageContext/parent set. " +
|
||||
assertTrue("Tag state after doEndTag() and explicit tag state clearing is unequal to new Tag with pageContext/parent set. " +
|
||||
"May indicate that clearTagStateForTagPoolingServers() calls are not working properly.",
|
||||
strutsBodyTagsAreReflectionEqual(tag, freshTag));
|
||||
}
|
||||
@@ -201,7 +199,7 @@ public class AnchorTest extends AbstractUITagTest {
|
||||
AnchorTag freshTag = new AnchorTag();
|
||||
freshTag.setPerformClearTagStateForTagPoolingServers(true);
|
||||
freshTag.setPageContext(pageContext);
|
||||
assertTrue("Tag state after doEndTag() and explicit tag state clearing is inequal to new Tag with pageContext/parent set. " +
|
||||
assertTrue("Tag state after doEndTag() and explicit tag state clearing is unequal to new Tag with pageContext/parent set. " +
|
||||
"May indicate that clearTagStateForTagPoolingServers() calls are not working properly.",
|
||||
strutsBodyTagsAreReflectionEqual(tag, freshTag));
|
||||
}
|
||||
@@ -211,7 +209,7 @@ public class AnchorTest extends AbstractUITagTest {
|
||||
testAction.setFoo("bar");
|
||||
}
|
||||
|
||||
private AnchorTag createTag() throws JspException {
|
||||
private AnchorTag createTag() {
|
||||
AnchorTag tag = new AnchorTag();
|
||||
tag.setPageContext(pageContext);
|
||||
|
||||
@@ -221,8 +219,6 @@ public class AnchorTest extends AbstractUITagTest {
|
||||
|
||||
/**
|
||||
* Test anchor tag body supported
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testSimpleWithBody() throws Exception {
|
||||
createAction();
|
||||
@@ -242,8 +238,6 @@ public class AnchorTest extends AbstractUITagTest {
|
||||
|
||||
/**
|
||||
* Test that by default anchor tag body is HTML-escaped.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testSimpleWithBodyHTMLEscaped() throws Exception {
|
||||
createAction();
|
||||
@@ -254,6 +248,7 @@ public class AnchorTest extends AbstractUITagTest {
|
||||
StrutsBodyContent body = new StrutsBodyContent(null);
|
||||
body.print("should HTML escape: < & >");
|
||||
tag.setBodyContent(body);
|
||||
tag.setEscapeHtmlBody("true");
|
||||
|
||||
tag.doStartTag();
|
||||
tag.doEndTag();
|
||||
@@ -263,15 +258,13 @@ public class AnchorTest extends AbstractUITagTest {
|
||||
|
||||
/**
|
||||
* Test that with htmlEscapeBody false anchor tag body is not HTML-escaped.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testSimpleWithBodyNotHTMLEscaped() throws Exception {
|
||||
createAction();
|
||||
|
||||
AnchorTag tag = createTag();
|
||||
tag.setHref("a");
|
||||
tag.setEscapeHtmlBody(false);
|
||||
tag.setEscapeHtmlBody("false");
|
||||
|
||||
StrutsBodyContent body = new StrutsBodyContent(null);
|
||||
body.print("should not HTML escape: < & >");
|
||||
@@ -282,4 +275,50 @@ public class AnchorTest extends AbstractUITagTest {
|
||||
|
||||
verifyResource("href-5.txt");
|
||||
}
|
||||
|
||||
public void testInjectEscapeHtmlBodyFlag() throws Exception {
|
||||
// given
|
||||
initDispatcherWithConfigs("struts-default.xml, struts-escape-body.xml");
|
||||
String escapeHtmlBody = container.getInstance(String.class, StrutsConstants.STRUTS_UI_ESCAPE_HTML_BODY);
|
||||
assertEquals("true", escapeHtmlBody);
|
||||
|
||||
createMocks();
|
||||
|
||||
createAction();
|
||||
|
||||
AnchorTag tag = createTag();
|
||||
|
||||
// when
|
||||
tag.doStartTag();
|
||||
|
||||
// then
|
||||
Anchor component = (Anchor) tag.getComponent();
|
||||
assertTrue(component.escapeHtmlBody());
|
||||
|
||||
tag.doEndTag();
|
||||
}
|
||||
|
||||
public void testTagAttributeTakesPrecedenceOverInjectEscapeHtmlBodyFlag() throws Exception {
|
||||
// given
|
||||
initDispatcherWithConfigs("struts-default.xml, struts-escape-body.xml");
|
||||
String escapeHtmlBody = container.getInstance(String.class, StrutsConstants.STRUTS_UI_ESCAPE_HTML_BODY);
|
||||
assertEquals("true", escapeHtmlBody);
|
||||
|
||||
createMocks();
|
||||
|
||||
createAction();
|
||||
|
||||
AnchorTag tag = createTag();
|
||||
tag.setEscapeHtmlBody("false");
|
||||
|
||||
// when
|
||||
tag.doStartTag();
|
||||
|
||||
// then
|
||||
Anchor component = (Anchor) tag.getComponent();
|
||||
assertFalse(component.escapeHtmlBody());
|
||||
|
||||
tag.doEndTag();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -40,8 +40,8 @@ public class CheckboxTest extends AbstractUITagTest {
|
||||
* as key.
|
||||
*/
|
||||
@Override
|
||||
protected Map initializedGenericTagTestProperties() {
|
||||
Map result = super.initializedGenericTagTestProperties();
|
||||
protected Map<String, PropertyHolder> initializedGenericTagTestProperties() {
|
||||
Map<String, PropertyHolder> result = super.initializedGenericTagTestProperties();
|
||||
new PropertyHolder("value", "true").addToMap(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -96,8 +96,8 @@ public class FileTest extends AbstractUITagTest {
|
||||
* as key.
|
||||
*/
|
||||
@Override
|
||||
protected Map initializedGenericTagTestProperties() {
|
||||
Map result = super.initializedGenericTagTestProperties();
|
||||
protected Map<String, PropertyHolder> initializedGenericTagTestProperties() {
|
||||
Map<String, PropertyHolder> result = super.initializedGenericTagTestProperties();
|
||||
new PropertyHolder("accept", "someAccepted").addToMap(result);
|
||||
new PropertyHolder("size", "101").addToMap(result);
|
||||
new PropertyHolder("value", "", "").addToMap(result);
|
||||
|
||||
@@ -630,8 +630,8 @@ public class SubmitTest extends AbstractUITagTest {
|
||||
* as key.
|
||||
*/
|
||||
@Override
|
||||
protected Map initializedGenericTagTestProperties() {
|
||||
Map result = new HashMap();
|
||||
protected Map<String, PropertyHolder> initializedGenericTagTestProperties() {
|
||||
Map<String, PropertyHolder> result = new HashMap<>();
|
||||
new PropertyHolder("title", "someTitle").addToMap(result);
|
||||
new PropertyHolder("cssClass", "cssClass1", "class=\"cssClass1\"").addToMap(result);
|
||||
new PropertyHolder("cssStyle", "cssStyle1", "style=\"cssStyle1\"").addToMap(result);
|
||||
@@ -652,8 +652,6 @@ public class SubmitTest extends AbstractUITagTest {
|
||||
|
||||
/**
|
||||
* Test that by default submit tag body is HTML-escaped.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testSubmitWithBodyHTMLEscaped() throws Exception {
|
||||
TestAction testAction = (TestAction) action;
|
||||
@@ -670,6 +668,7 @@ public class SubmitTest extends AbstractUITagTest {
|
||||
StrutsBodyContent body = new StrutsBodyContent(null);
|
||||
body.print("should HTML escape: < & >");
|
||||
tag.setBodyContent(body);
|
||||
tag.setEscapeHtmlBody(true);
|
||||
tag.doStartTag();
|
||||
tag.doEndTag();
|
||||
|
||||
@@ -678,8 +677,6 @@ public class SubmitTest extends AbstractUITagTest {
|
||||
|
||||
/**
|
||||
* Test that with htmlEscapeBody false submit tag body is not HTML-escaped.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testSubmitWithBodyNotHTMLEscaped() throws Exception {
|
||||
TestAction testAction = (TestAction) action;
|
||||
|
||||
@@ -130,8 +130,8 @@ public class TextareaTest extends AbstractUITagTest {
|
||||
* as key.
|
||||
*/
|
||||
@Override
|
||||
protected Map initializedGenericTagTestProperties() {
|
||||
Map result = super.initializedGenericTagTestProperties();
|
||||
protected Map<String, PropertyHolder> initializedGenericTagTestProperties() {
|
||||
Map<String, PropertyHolder> result = super.initializedGenericTagTestProperties();
|
||||
new PropertyHolder("cols", "10").addToMap(result);
|
||||
new PropertyHolder("rows", "11").addToMap(result);
|
||||
new PropertyHolder("readonly", "true", "readonly=\"readonly\"").addToMap(result);
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
-->
|
||||
<!DOCTYPE struts PUBLIC
|
||||
"-//Apache Software Foundation//DTD Struts Configuration 2.6//EN"
|
||||
"http://struts.apache.org/dtds/struts-2.6.dtd">
|
||||
<struts>
|
||||
<constant name="struts.ui.escapeHtmlBody" value="true"/>
|
||||
|
||||
<package name="default" extends="struts-default">
|
||||
</package>
|
||||
|
||||
</struts>
|
||||
+7
-6
@@ -22,14 +22,15 @@ import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
||||
/**
|
||||
* Default implementation of TagHandlerFactory
|
||||
* Default implementation of TagHandlerFactory
|
||||
*/
|
||||
public class DefaultTagHandlerFactory implements TagHandlerFactory {
|
||||
private static final Logger LOG = LogManager.getLogger(DefaultTagHandlerFactory.class);
|
||||
|
||||
private Class tagHandlerClass;
|
||||
|
||||
public DefaultTagHandlerFactory(Class tagHandlerClass) {
|
||||
private static final Logger LOG = LogManager.getLogger(DefaultTagHandlerFactory.class);
|
||||
|
||||
private final Class<?> tagHandlerClass;
|
||||
|
||||
public DefaultTagHandlerFactory(Class<?> tagHandlerClass) {
|
||||
this.tagHandlerClass = tagHandlerClass;
|
||||
}
|
||||
|
||||
@@ -41,7 +42,7 @@ public class DefaultTagHandlerFactory implements TagHandlerFactory {
|
||||
} catch (Exception e) {
|
||||
LOG.error("Failed to instantiate tag handler class [{}]", tagHandlerClass.getName(), e);
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
+4
-2
@@ -45,8 +45,10 @@ public class AnchorHandler extends AbstractTagHandler implements TagGenerator {
|
||||
.addIfExists("tabindex", params.get("tabindex"));
|
||||
start("a", attrs);
|
||||
String body = (String) params.get("body");
|
||||
if (StringUtils.isNotEmpty(body))
|
||||
characters(body, false);
|
||||
Boolean escapeHtmlBody = (Boolean) params.get("escapeHtmlBody");
|
||||
if (StringUtils.isNotEmpty(body)) {
|
||||
characters(body, escapeHtmlBody);
|
||||
}
|
||||
end("a");
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -65,13 +65,13 @@ public class SimpleTheme extends DefaultTheme {
|
||||
setName("simple");
|
||||
}
|
||||
|
||||
private class FactoryList extends ArrayList<TagHandlerFactory> {
|
||||
private static class FactoryList extends ArrayList<TagHandlerFactory> {
|
||||
|
||||
private static final long serialVersionUID = -1551895041394434032L;
|
||||
|
||||
public FactoryList(Class... classes) {
|
||||
public FactoryList(Class<?>... classes) {
|
||||
super();
|
||||
for (Class cls : classes) {
|
||||
for (Class<?> cls : classes) {
|
||||
add(new DefaultTagHandlerFactory(cls));
|
||||
}
|
||||
add(new DefaultTagHandlerFactory(XHTMLTagSerializer.class));
|
||||
|
||||
+9
-5
@@ -73,6 +73,7 @@ public class SubmitHandler extends AbstractTagHandler implements TagGenerator {
|
||||
public void generate() throws IOException {
|
||||
Map<String, Object> params = context.getParameters();
|
||||
String body = (String) params.get("body");
|
||||
Boolean escapeHtmlBody = (Boolean) params.get("escapeHtmlBody");
|
||||
|
||||
String type = StringUtils.defaultString((String) params.get("type"), "input");
|
||||
if ("button".equals(type)) {
|
||||
@@ -81,16 +82,19 @@ public class SubmitHandler extends AbstractTagHandler implements TagGenerator {
|
||||
characters(body, false);
|
||||
else if (params.containsKey("label")) {
|
||||
String label = (String) params.get("label");
|
||||
if (StringUtils.isNotEmpty(label))
|
||||
characters(label, false);
|
||||
if (StringUtils.isNotEmpty(label)) {
|
||||
characters(label, escapeHtmlBody);
|
||||
}
|
||||
}
|
||||
end("button");
|
||||
} else if ("image".equals(type)) {
|
||||
if (StringUtils.isNotEmpty(body))
|
||||
characters(body, false);
|
||||
if (StringUtils.isNotEmpty(body)) {
|
||||
characters(body, escapeHtmlBody);
|
||||
}
|
||||
end("input");
|
||||
} else
|
||||
} else {
|
||||
end("input");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+36
@@ -69,6 +69,42 @@ public class AnchorTest extends AbstractTest {
|
||||
assertEquals(expected, output);
|
||||
}
|
||||
|
||||
public void testEnableEscapeBody() {
|
||||
tag.setName("name_");
|
||||
tag.setHref("http://sometest.com?ab=10");
|
||||
tag.setEscapeHtmlBody(true);
|
||||
tag.evaluateParams();
|
||||
|
||||
map.putAll(tag.getParameters());
|
||||
context.getParameters().put("body", s("<i class='i-image'/>"));
|
||||
|
||||
theme.renderTag(getTagName(), context);
|
||||
theme.renderTag(getTagName() + "-close", context);
|
||||
|
||||
String output = writer.getBuffer().toString();
|
||||
String expected = s("<a name='name_' id='name_' href='http://sometest.com?ab=10'><i class="i-image"/></a>");
|
||||
|
||||
assertEquals(expected, output);
|
||||
}
|
||||
|
||||
public void testDefaultDisabledEscapeBody() {
|
||||
tag.setName("name_");
|
||||
tag.setHref("http://sometest.com?ab=10");
|
||||
//tag.setEscapeHtmlBody(true);
|
||||
tag.evaluateParams();
|
||||
|
||||
map.putAll(tag.getParameters());
|
||||
context.getParameters().put("body", s("<i class='i-image'/>"));
|
||||
|
||||
theme.renderTag(getTagName(), context);
|
||||
theme.renderTag(getTagName() + "-close", context);
|
||||
|
||||
String output = writer.getBuffer().toString();
|
||||
String expected = s("<a name='name_' id='name_' href='http://sometest.com?ab=10'><i class='i-image'/></a>");
|
||||
|
||||
assertEquals(expected, output);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
Reference in New Issue
Block a user