You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by lu...@apache.org on 2022/01/04 08:01:27 UTC

[struts] branch WW-5022-escape-false created (now ecef56b)

This is an automated email from the ASF dual-hosted git repository.

lukaszlenart pushed a change to branch WW-5022-escape-false
in repository https://gitbox.apache.org/repos/asf/struts.git.


      at ecef56b  WW-5022 Sets escapeHtmlBody to false by default and defines new flag to switch to true globally

This branch includes the following new commits:

     new ecef56b  WW-5022 Sets escapeHtmlBody to false by default and defines new flag to switch to true globally

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


[struts] 01/01: WW-5022 Sets escapeHtmlBody to false by default and defines new flag to switch to true globally

Posted by lu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

lukaszlenart pushed a commit to branch WW-5022-escape-false
in repository https://gitbox.apache.org/repos/asf/struts.git

commit ecef56b546b1a7ae3a8411b3e2af2b64fc72799e
Author: Lukasz Lenart <lu...@apache.org>
AuthorDate: Tue Jan 4 09:01:21 2022 +0100

    WW-5022 Sets escapeHtmlBody to false by default and defines new flag to switch to true globally
---
 core/pom.xml                                       |   2 +-
 .../java/org/apache/struts2/StrutsConstants.java   |  14 ++-
 .../java/org/apache/struts2/components/Anchor.java |  18 +--
 .../org/apache/struts2/components/Component.java   |  22 ++--
 .../java/org/apache/struts2/components/Submit.java |  18 +--
 .../org/apache/struts2/views/jsp/ui/AnchorTag.java |  18 +--
 .../org/apache/struts2/views/jsp/ui/SubmitTag.java |   8 +-
 .../apache/struts2/components/ComponentTest.java   | 133 ++++++++-------------
 .../apache/struts2/views/jsp/ui/AnchorTest.java    |  48 +++++---
 .../apache/struts2/views/jsp/ui/CheckboxTest.java  |   4 +-
 .../org/apache/struts2/views/jsp/ui/FileTest.java  |   4 +-
 .../apache/struts2/views/jsp/ui/SubmitTest.java    |   9 +-
 .../apache/struts2/views/jsp/ui/TextareaTest.java  |   4 +-
 core/src/test/resources/struts-escape-body.xml     |  31 +++++
 14 files changed, 168 insertions(+), 165 deletions(-)

diff --git a/core/pom.xml b/core/pom.xml
index 9807142..cd56777 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -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.
diff --git a/core/src/main/java/org/apache/struts2/StrutsConstants.java b/core/src/main/java/org/apache/struts2/StrutsConstants.java
index 60007ce..626f963 100644
--- a/core/src/main/java/org/apache/struts2/StrutsConstants.java
+++ b/core/src/main/java/org/apache/struts2/StrutsConstants.java
@@ -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";
@@ -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";
 
@@ -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";
 
@@ -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";
 
@@ -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";
+
 }
diff --git a/core/src/main/java/org/apache/struts2/components/Anchor.java b/core/src/main/java/org/apache/struts2/components/Anchor.java
index 153fdf8..e00291d 100644
--- a/core/src/main/java/org/apache/struts2/components/Anchor.java
+++ b/core/src/main/java/org/apache/struts2/components/Anchor.java
@@ -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();
@@ -276,7 +264,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 = "true")
     public void setEscapeHtmlBody(boolean escapeHtmlBody) {
         this.escapeHtmlBody = escapeHtmlBody;
     }
diff --git a/core/src/main/java/org/apache/struts2/components/Component.java b/core/src/main/java/org/apache/struts2/components/Component.java
index 4d5c845..2b0c58a 100644
--- a/core/src/main/java/org/apache/struts2/components/Component.java
+++ b/core/src/main/java/org/apache/struts2/components/Component.java
@@ -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;
     }
diff --git a/core/src/main/java/org/apache/struts2/components/Submit.java b/core/src/main/java/org/apache/struts2/components/Submit.java
index 124526a..6a9ce97 100644
--- a/core/src/main/java/org/apache/struts2/components/Submit.java
+++ b/core/src/main/java/org/apache/struts2/components/Submit.java
@@ -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);
@@ -101,7 +103,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 = "true")
     public void setEscapeHtmlBody(boolean escapeHtmlBody) {
         this.escapeHtmlBody = escapeHtmlBody;
     }
@@ -112,18 +114,6 @@ public class Submit extends FormButton {
     }
 
     /**
-     * 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
      */
     public boolean end(Writer writer, String body) {
diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/AnchorTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/AnchorTag.java
index 4f334ad..0e181d5 100644
--- a/core/src/main/java/org/apache/struts2/views/jsp/ui/AnchorTag.java
+++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/AnchorTag.java
@@ -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;
     }
 
diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/SubmitTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/SubmitTag.java
index 5250cbe..2bfd6a9 100644
--- a/core/src/main/java/org/apache/struts2/views/jsp/ui/SubmitTag.java
+++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/SubmitTag.java
@@ -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) {
diff --git a/core/src/test/java/org/apache/struts2/components/ComponentTest.java b/core/src/test/java/org/apache/struts2/components/ComponentTest.java
index 0bc0982..762e37a 100644
--- a/core/src/test/java/org/apache/struts2/components/ComponentTest.java
+++ b/core/src/test/java/org/apache/struts2/components/ComponentTest.java
@@ -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();
         }
     }
diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/AnchorTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/AnchorTest.java
index 8101cc8..53fa8ba 100644
--- a/core/src/test/java/org/apache/struts2/views/jsp/ui/AnchorTest.java
+++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/AnchorTest.java
@@ -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,27 @@ 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();
+    }
+
 }
diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/CheckboxTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/CheckboxTest.java
index 778fb19..783d5ae 100644
--- a/core/src/test/java/org/apache/struts2/views/jsp/ui/CheckboxTest.java
+++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/CheckboxTest.java
@@ -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;
     }
diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/FileTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/FileTest.java
index 32b9322..d5a296c 100644
--- a/core/src/test/java/org/apache/struts2/views/jsp/ui/FileTest.java
+++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/FileTest.java
@@ -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);
diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/SubmitTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/SubmitTest.java
index 6f573ae..99eff80 100644
--- a/core/src/test/java/org/apache/struts2/views/jsp/ui/SubmitTest.java
+++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/SubmitTest.java
@@ -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;
diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/TextareaTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/TextareaTest.java
index 54fa478..d94bbd2 100644
--- a/core/src/test/java/org/apache/struts2/views/jsp/ui/TextareaTest.java
+++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/TextareaTest.java
@@ -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);
diff --git a/core/src/test/resources/struts-escape-body.xml b/core/src/test/resources/struts-escape-body.xml
new file mode 100644
index 0000000..d3f7084
--- /dev/null
+++ b/core/src/test/resources/struts-escape-body.xml
@@ -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>