Skip to content

Commit

Permalink
WW-5022 Sets escapeHtmlBody to false by default and defines new flag …
Browse files Browse the repository at this point in the history
…to switch to true globally
  • Loading branch information
lukaszlenart committed Jan 4, 2022
1 parent bab276e commit ecef56b
Show file tree
Hide file tree
Showing 14 changed files with 168 additions and 165 deletions.
2 changes: 1 addition & 1 deletion core/pom.xml
Expand Up @@ -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.
Expand Down
14 changes: 9 additions & 5 deletions core/src/main/java/org/apache/struts2/StrutsConstants.java
Expand Up @@ -35,13 +35,13 @@ public final class StrutsConstants {
/** The encoding to use for localization messages */
public static final String STRUTS_I18N_ENCODING = "struts.i18n.encoding";

/**
/**
* Whether the default bundles should be searched for messages first. Can be used to modify the
* standard processing order for message lookup in TextProvider implementations.
* <p>
* Note: This control flag may not be meaningful to all provider implementations, and should be false by default.
* </p>
*
*
* @since 2.6
*/
public static final String STRUTS_I18N_SEARCH_DEFAULTBUNDLES_FIRST = "struts.i18n.search.defaultbundles.first";
Expand Down Expand Up @@ -104,10 +104,10 @@ public final class StrutsConstants {

/** Update freemarker templates cache in seconds */
public static final String STRUTS_FREEMARKER_TEMPLATES_CACHE_UPDATE_DELAY = "struts.freemarker.templatesCache.updateDelay";

/** Cache model instances at BeanWrapper level */
public static final String STRUTS_FREEMARKER_BEANWRAPPER_CACHE = "struts.freemarker.beanwrapperCache";

/** Maximum strong sizing for MruCacheStorage for freemarker */
public static final String STRUTS_FREEMARKER_MRU_MAX_STRONG_SIZE = "struts.freemarker.mru.max.strong.size";

Expand All @@ -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";

Expand Down Expand Up @@ -188,7 +191,7 @@ public final class StrutsConstants {
* You can specify different prefixes that will be handled by different mappers
*/
public static final String PREFIX_BASED_MAPPER_CONFIGURATION = "struts.mapper.prefixMapping";

/** Whether the Struts filter should serve static content or not */
public static final String STRUTS_SERVE_STATIC_CONTENT = "struts.serve.static";

Expand Down Expand Up @@ -362,4 +365,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";

}
18 changes: 3 additions & 15 deletions core/src/main/java/org/apache/struts2/components/Anchor.java
Expand Up @@ -20,6 +20,7 @@

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;
Expand Down Expand Up @@ -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();

Expand All @@ -96,18 +96,6 @@ public boolean usesBody() {
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();
Expand Down Expand Up @@ -276,7 +264,7 @@ public void setForceAddSchemeHostAndPort(boolean forceAddSchemeHostAndPort) {
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 = "true")
public void setEscapeHtmlBody(boolean escapeHtmlBody) {
this.escapeHtmlBody = escapeHtmlBody;
}
Expand Down
22 changes: 14 additions & 8 deletions core/src/main/java/org/apache/struts2/components/Component.java
Expand Up @@ -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;
Expand Down Expand Up @@ -116,6 +117,11 @@ public void setThrowExceptionsOnELFailure(String throwException) {
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;
Expand Down Expand Up @@ -213,13 +219,13 @@ protected void popComponentStack() {
* @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;
}
Expand Down Expand Up @@ -536,7 +542,7 @@ public boolean usesBody() {
* @since 2.6
*/
public boolean escapeHtmlBody() {
return true;
return escapeHtmlBody;
}

/**
Expand Down Expand Up @@ -572,16 +578,16 @@ protected Collection<String> getStandardAttributes() {
/**
* 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;
}
Expand Down
18 changes: 4 additions & 14 deletions core/src/main/java/org/apache/struts2/components/Submit.java
Expand Up @@ -23,6 +23,9 @@
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;

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -101,7 +103,7 @@ public void setSrc(String src) {
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 = "true")
public void setEscapeHtmlBody(boolean escapeHtmlBody) {
this.escapeHtmlBody = escapeHtmlBody;
}
Expand All @@ -111,18 +113,6 @@ public boolean usesBody() {
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
*/
Expand Down
18 changes: 10 additions & 8 deletions core/src/main/java/org/apache/struts2/views/jsp/ui/AnchorTag.java
Expand Up @@ -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();
Expand All @@ -80,10 +80,12 @@ protected void populateParams() {
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) {
Expand Down Expand Up @@ -149,12 +151,12 @@ public void setForceAddSchemeHostAndPort(String forceAddSchemeHostAndPort) {

/**
* 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;
}

Expand Down
Expand Up @@ -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) {
Expand Down Expand Up @@ -78,9 +78,9 @@ public void setSrc(String src) {

/**
* Set via parameter to control if body content should be HTML-escaped.
*
* @param escapeHtmlBody
*
*
* @param escapeHtmlBody
*
* @since 2.6
*/
public void setEscapeHtmlBody(boolean escapeHtmlBody) {
Expand Down

0 comments on commit ecef56b

Please sign in to comment.