You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by am...@apache.org on 2018/11/01 20:06:06 UTC

[struts] branch master updated (b82db24 -> 9fd8d6f)

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

amashchenko pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/struts.git.


    from b82db24  [WW-4973] Upgrades to OGNL 3.2.8 (#258)
     new 9fa53dd  Merge pull request #257 from JCgH4164838Gh792C124B5/localS2_2_5_x_Branch
     new 9fd8d6f  WW-4971 Use response encoding for include by default

The 2 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.


Summary of changes:
 .../java/org/apache/struts2/StrutsConstants.java   | 65 +++++++++++-----------
 .../org/apache/struts2/components/Include.java     | 35 +++++++++---
 .../struts2/util/FastByteArrayOutputStream.java    | 24 ++++++--
 .../apache/struts2/views/jsp/IncludeTagTest.java   | 60 +++++++++++++++++++-
 4 files changed, 137 insertions(+), 47 deletions(-)


[struts] 01/02: Merge pull request #257 from JCgH4164838Gh792C124B5/localS2_2_5_x_Branch

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

amashchenko pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/struts.git

commit 9fa53dddb92c6eea59396d9505c467acb1d74d97
Author: Aleksandr Mashchenko <al...@users.noreply.github.com>
AuthorDate: Thu Nov 1 21:53:04 2018 +0200

    Merge pull request #257 from JCgH4164838Gh792C124B5/localS2_2_5_x_Branch
    
    Fix WW-4971 (broken includes for non-UTF8 content).
---
 .../java/org/apache/struts2/StrutsConstants.java   | 65 +++++++++++-----------
 .../org/apache/struts2/components/Include.java     | 36 +++++++++---
 .../struts2/util/FastByteArrayOutputStream.java    | 24 ++++++--
 .../apache/struts2/views/jsp/IncludeTagTest.java   | 60 +++++++++++++++++++-
 4 files changed, 138 insertions(+), 47 deletions(-)

diff --git a/core/src/main/java/org/apache/struts2/StrutsConstants.java b/core/src/main/java/org/apache/struts2/StrutsConstants.java
index 81a4f80..f786305 100644
--- a/core/src/main/java/org/apache/struts2/StrutsConstants.java
+++ b/core/src/main/java/org/apache/struts2/StrutsConstants.java
@@ -41,12 +41,15 @@ public final class StrutsConstants {
     /** The URL extension to use to determine if the request is meant for a Struts action */
     public static final String STRUTS_ACTION_EXTENSION = "struts.action.extension";
 
-	/** Comma separated list of patterns (java.util.regex.Pattern) to be excluded from Struts2-processing */
-	public static final String STRUTS_ACTION_EXCLUDE_PATTERN = "struts.action.excludePattern";
+    /** Comma separated list of patterns (java.util.regex.Pattern) to be excluded from Struts2-processing */
+    public static final String STRUTS_ACTION_EXCLUDE_PATTERN = "struts.action.excludePattern";
 
-    /** Whether to use the alterative syntax for the tags or not */
+    /** Whether to use the alternative syntax for the tags or not */
     public static final String STRUTS_TAG_ALTSYNTAX = "struts.tag.altSyntax";
 
+    /** Whether to use the response encoding (JSP page encoding) for s:include tag processing (false - use STRUTS_I18N_ENCODING - by default) */
+    public static final String STRUTS_TAG_INCLUDETAG_USERESPONSEENCODING = "struts.tag.includetag.useResponseEncoding";
+
     /** The HTTP port used by Struts URLs */
     public static final String STRUTS_URL_HTTP_PORT = "struts.url.http.port";
 
@@ -56,7 +59,7 @@ public final class StrutsConstants {
     /** The default includeParams method to generate Struts URLs */
     public static final String STRUTS_URL_INCLUDEPARAMS = "struts.url.includeParams";
 
-	public static final String STRUTS_URL_RENDERER = "struts.urlRenderer";
+    public static final String STRUTS_URL_RENDERER = "struts.urlRenderer";
 
     /** The com.opensymphony.xwork2.ObjectFactory implementation class */
     public static final String STRUTS_OBJECTFACTORY = "struts.objectFactory";
@@ -91,7 +94,7 @@ public final class StrutsConstants {
     /** The org.apache.struts2.views.freemarker.FreemarkerManager implementation class */
     public static final String STRUTS_FREEMARKER_MANAGER_CLASSNAME = "struts.freemarker.manager.classname";
 
-    /** Update freemarker templates cache in seconds*/
+    /** 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 */
@@ -220,12 +223,12 @@ public final class StrutsConstants {
     public static final String STRUTS_LOCALE_PROVIDER_FACTORY = "struts.localeProviderFactory";
 
     /** The name of the parameter to create when mapping an id (used by some action mappers) */
-	public static final String STRUTS_ID_PARAMETER_NAME = "struts.mapper.idParameterName";
-	
-	/** The name of the parameter to determine whether static method access will be allowed in OGNL expressions or not */
-	public static final String STRUTS_ALLOW_STATIC_METHOD_ACCESS = "struts.ognl.allowStaticMethodAccess";
+    public static final String STRUTS_ID_PARAMETER_NAME = "struts.mapper.idParameterName";
+
+    /** The name of the parameter to determine whether static method access will be allowed in OGNL expressions or not */
+    public static final String STRUTS_ALLOW_STATIC_METHOD_ACCESS = "struts.ognl.allowStaticMethodAccess";
 
-	/** The com.opensymphony.xwork2.validator.ActionValidatorManager implementation class */
+    /** The com.opensymphony.xwork2.validator.ActionValidatorManager implementation class */
     public static final String STRUTS_ACTIONVALIDATORMANAGER = "struts.actionValidatorManager";
 
     /** The {@link com.opensymphony.xwork2.util.ValueStackFactory} implementation class */
@@ -236,7 +239,7 @@ public final class StrutsConstants {
 
     /** The {@link com.opensymphony.xwork2.util.reflection.ReflectionContextFactory} implementation class */
     public static final String STRUTS_REFLECTIONCONTEXTFACTORY = "struts.reflectionContextFactory";
-    
+
     /** The {@link com.opensymphony.xwork2.util.PatternMatcher} implementation class */
     public static final String STRUTS_PATTERNMATCHER = "struts.patternMatcher";
 
@@ -246,32 +249,32 @@ public final class StrutsConstants {
     /** The {@link com.opensymphony.xwork2.UnknownHandlerManager} implementation class */
     public static final String STRUTS_UNKNOWN_HANDLER_MANAGER = "struts.unknownHandlerManager";
 
-    /** Throw RuntimeException when a property is not found, or the evaluation of the espression fails*/
+    /** Throw RuntimeException when a property is not found, or the evaluation of the expression fails */
     public static final String STRUTS_EL_THROW_EXCEPTION = "struts.el.throwExceptionOnFailure";
 
-    /** Logs properties that are not found (very verbose) **/
+    /** Logs properties that are not found (very verbose) */
     public static final String STRUTS_LOG_MISSING_PROPERTIES = "struts.ognl.logMissingProperties";
 
-    /** Enables caching of parsed OGNL expressions **/
+    /** Enables caching of parsed OGNL expressions */
     public static final String STRUTS_ENABLE_OGNL_EXPRESSION_CACHE = "struts.ognl.enableExpressionCache";
 
-    /** Enables evaluation of OGNL expressions **/
+    /** Enables evaluation of OGNL expressions */
     public static final String STRUTS_ENABLE_OGNL_EVAL_EXPRESSION = "struts.ognl.enableOGNLEvalExpression";
 
-    /** Disables {@link org.apache.struts2.dispatcher.StrutsRequestWrapper} request attribute value stack lookup (JSTL accessibility) **/
+    /** Disables {@link org.apache.struts2.dispatcher.StrutsRequestWrapper} request attribute value stack lookup (JSTL accessibility) */
     public static final String STRUTS_DISABLE_REQUEST_ATTRIBUTE_VALUE_STACK_LOOKUP = "struts.disableRequestAttributeValueStackLookup";
 
-    /** The{@link org.apache.struts2.views.util.UrlHelper} implementation class **/
+    /** The{@link org.apache.struts2.views.util.UrlHelper} implementation class */
     public static final String STRUTS_URL_HELPER = "struts.view.urlHelper";
 
-    /** {@link com.opensymphony.xwork2.conversion.impl.XWorkBasicConverter} **/
+    /** {@link com.opensymphony.xwork2.conversion.impl.XWorkBasicConverter} */
     public static final String STRUTS_CONVERTER_COLLECTION = "struts.converter.collection";
     public static final String STRUTS_CONVERTER_ARRAY = "struts.converter.array";
     public static final String STRUTS_CONVERTER_DATE = "struts.converter.date";
     public static final String STRUTS_CONVERTER_NUMBER = "struts.converter.number";
     public static final String STRUTS_CONVERTER_STRING = "struts.converter.string";
 
-    /** Enable handling exceptions by Dispatcher - true by default **/
+    /** Enable handling exceptions by Dispatcher - true by default */
     public static final String STRUTS_HANDLE_EXCEPTION = "struts.handle.exception";
 
     public static final String STRUTS_CONVERTER_PROPERTIES_PROCESSOR = "struts.converter.properties.processor";
@@ -282,42 +285,42 @@ public final class StrutsConstants {
 
     public static final String STRUTS_EXPRESSION_PARSER = "struts.expression.parser";
 
-    /** namespaces names' whitelist **/
+    /** Namespace names' whitelist */
     public static final String STRUTS_ALLOWED_NAMESPACE_NAMES = "struts.allowed.namespace.names";
-    /** default namespace name to use when namespace didn't match the whitelist **/
+    /** Default namespace name to use when namespace didn't match the whitelist */
     public static final String STRUTS_DEFAULT_NAMESPACE_NAME = "struts.default.namespace.name";
 
-    /** actions names' whitelist **/
+    /** Action names' whitelist */
     public static final String STRUTS_ALLOWED_ACTION_NAMES = "struts.allowed.action.names";
-    /** default action name to use when action didn't match the whitelist **/
+    /** Default action name to use when action didn't match the whitelist */
     public static final String STRUTS_DEFAULT_ACTION_NAME = "struts.default.action.name";
 
-    /** methods names' whitelist **/
+    /** Method names' whitelist */
     public static final String STRUTS_ALLOWED_METHOD_NAMES = "struts.allowed.method.names";
-    /** default method name to use when method didn't match the whitelist **/
+    /** Default method name to use when method didn't match the whitelist */
     public static final String STRUTS_DEFAULT_METHOD_NAME = "struts.default.method.name";
 
-    /** enables action: prefix **/
+    /** Enables action: prefix */
     public static final String STRUTS_MAPPER_ACTION_PREFIX_ENABLED = "struts.mapper.action.prefix.enabled";
 
-    /** enables access to actions in other namespaces than current with action: prefix **/
+    /** Enables access to actions in other namespaces than current with action: prefix */
     public static final String STRUTS_MAPPER_ACTION_PREFIX_CROSSNAMESPACES = "struts.mapper.action.prefix.crossNamespaces";
 
     public static final String DEFAULT_TEMPLATE_TYPE_CONFIG_KEY = "struts.ui.templateSuffix";
 
-    /** Allows override default DispatcherErrorHandler **/
+    /** Allows override default DispatcherErrorHandler */
     public static final String STRUTS_DISPATCHER_ERROR_HANDLER = "struts.dispatcher.errorHandler";
 
-    /** Comma delimited set of excluded classes and package names which cannot be accessed via expressions **/
+    /** Comma delimited set of excluded classes and package names which cannot be accessed via expressions */
     public static final String STRUTS_EXCLUDED_CLASSES = "struts.excludedClasses";
     public static final String STRUTS_EXCLUDED_PACKAGE_NAME_PATTERNS = "struts.excludedPackageNamePatterns";
     public static final String STRUTS_EXCLUDED_PACKAGE_NAMES = "struts.excludedPackageNames";
 
-    /** Dedicated services to check if passed string is excluded/accepted **/
+    /** Dedicated services to check if passed string is excluded/accepted */
     public static final String STRUTS_EXCLUDED_PATTERNS_CHECKER = "struts.excludedPatterns.checker";
     public static final String STRUTS_ACCEPTED_PATTERNS_CHECKER = "struts.acceptedPatterns.checker";
 
-    /** Constant is used to override framework's default excluded patterns **/
+    /** Constant is used to override framework's default excluded patterns */
     public static final String STRUTS_OVERRIDE_EXCLUDED_PATTERNS = "struts.override.excludedPatterns";
     public static final String STRUTS_OVERRIDE_ACCEPTED_PATTERNS = "struts.override.acceptedPatterns";
 
diff --git a/core/src/main/java/org/apache/struts2/components/Include.java b/core/src/main/java/org/apache/struts2/components/Include.java
index aa58ade..616aa18 100644
--- a/core/src/main/java/org/apache/struts2/components/Include.java
+++ b/core/src/main/java/org/apache/struts2/components/Include.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.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.struts2.RequestUtils;
@@ -35,6 +36,7 @@ import javax.servlet.ServletRequest;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpServletResponseWrapper;
+
 import java.io.*;
 import java.net.URLEncoder;
 import java.util.*;
@@ -90,17 +92,19 @@ public class Include extends Component {
 
     private static final Logger LOG = LogManager.getLogger(Include.class);
 
-    private static String systemEncoding = System.getProperty("file.encoding");
+    private static final String systemEncoding = System.getProperty("file.encoding");
 
     protected String value;
     private HttpServletRequest req;
     private HttpServletResponse res;
-    private static String defaultEncoding;
+    private String defaultEncoding;       // Made non-static (during WW-4971 fix)
+    private boolean useResponseEncoding;  // Added with WW-4971 fix (allows switch between usage of response or default encoding)
 
     public Include(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
         super(stack);
         this.req = req;
         this.res = res;
+        useResponseEncoding = false;  // By default use defaultEncoding (vs. response/page encoding)
     }
 
     @Inject(StrutsConstants.STRUTS_I18N_ENCODING)
@@ -108,9 +112,25 @@ public class Include extends Component {
         defaultEncoding = encoding;
     }
 
+    @Inject(value = StrutsConstants.STRUTS_TAG_INCLUDETAG_USERESPONSEENCODING, required=false)
+    public void setUseResponseEncoding(String useEncoding) {
+        useResponseEncoding = Boolean.parseBoolean(useEncoding);
+    }
+
     public boolean end(Writer writer, String body) {
         String page = findString(value, "value", "You must specify the URL to include. Example: /foo.jsp");
         StringBuilder urlBuf = new StringBuilder();
+        String encodingForInclude;
+
+        if (useResponseEncoding) {
+            encodingForInclude = res.getCharacterEncoding();  // Use response (page) encoding
+            if (encodingForInclude == null || encodingForInclude.length() == 0) {
+                encodingForInclude = defaultEncoding;  // Revert to defaultEncoding when response (page) encoding is invalid
+            }
+        }
+        else {
+            encodingForInclude = defaultEncoding;  // Use default encoding (when useResponseEncoding is false)
+        }
 
         // Add URL
         urlBuf.append(page);
@@ -147,7 +167,7 @@ public class Include extends Component {
 
         // Include
         try {
-            include(result, writer, req, res, defaultEncoding);
+            include(result, writer, req, res, encodingForInclude);
         } catch (ServletException | IOException e) {
             LOG.warn("Exception thrown during include of {}", result, e);
         }
@@ -209,7 +229,7 @@ public class Include extends Component {
     }
 
     public void addParameter(String key, Object value) {
-        // don't use the default implementation of addParameter,
+        // Don't use the default implementation of addParameter,
         // instead, include tag requires that each parameter be a list of objects,
         // just like the HTTP servlet interfaces are (String[])
         if (value != null) {
@@ -256,7 +276,7 @@ public class Include extends Component {
             // Use given encoding
             pageResponse.getContent().writeTo(writer, encoding);
         } else {
-            //use the platform specific encoding
+            // Use the platform specific encoding
             pageResponse.getContent().writeTo(writer, systemEncoding);
         }
     }
@@ -349,9 +369,9 @@ public class Include extends Component {
          * @throws IOException
          */
         public FastByteArrayOutputStream getContent() throws IOException {
-            //if we are using a writer, we need to flush the
-            //data to the underlying outputstream.
-            //most containers do this - but it seems Jetty 4.0.5 doesn't
+            // If we are using a writer, we need to flush the
+            // data to the underlying outputstream.
+            // Most containers do this - but it seems Jetty 4.0.5 doesn't
             if (pagePrintWriter != null) {
                 pagePrintWriter.flush();
             }
diff --git a/core/src/main/java/org/apache/struts2/util/FastByteArrayOutputStream.java b/core/src/main/java/org/apache/struts2/util/FastByteArrayOutputStream.java
index fd75c46..6c593fd 100644
--- a/core/src/main/java/org/apache/struts2/util/FastByteArrayOutputStream.java
+++ b/core/src/main/java/org/apache/struts2/util/FastByteArrayOutputStream.java
@@ -18,6 +18,9 @@
  */
 package org.apache.struts2.util;
 
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
 import javax.servlet.jsp.JspWriter;
 import java.io.*;
 import java.nio.ByteBuffer;
@@ -35,6 +38,9 @@ import java.util.LinkedList;
  *
  */
 public class FastByteArrayOutputStream extends OutputStream {
+
+    private static final Logger LOG = LogManager.getLogger(FastByteArrayOutputStream.class);
+
     private static final int DEFAULT_BLOCK_SIZE = 8192;
 
     private LinkedList<byte[]> buffers;
@@ -144,7 +150,7 @@ public class FastByteArrayOutputStream extends OutputStream {
         // Append bytes to current buffer
         // Previous data maybe partially decoded, this part will appended to previous
         in.put(bytes, 0, length);
-        // To begin of data
+        // To begin processing of data
         in.flip();
         decodeAndWriteBuffered(writer, in, out, decoder, endOfInput);
     }
@@ -158,7 +164,7 @@ public class FastByteArrayOutputStream extends OutputStream {
             if (in.hasRemaining()) {
                 // Move remaining to top of buffer
                 in.compact();
-                if (result.isOverflow() && !result.isError() && !result.isMalformed()) {
+                if (result.isOverflow() && !result.isError()) {  // isError covers isMalformed and isUnmappable
                     // Not all buffer chars decoded, spin it again
                     // Set to begin
                     in.flip();
@@ -167,16 +173,24 @@ public class FastByteArrayOutputStream extends OutputStream {
                 // Clean up buffer
                 in.clear();
             }
-        } while (in.hasRemaining() && result.isOverflow() && !result.isError() && !result.isMalformed());
+        } while (in.hasRemaining() && result.isOverflow() && !result.isError());  // isError covers isMalformed and isUnmappable
+
+        if (result.isError()) {
+            if (LOG.isWarnEnabled()) {
+                // Provide a log warning when the decoding fails (prior to 2.5.19 it failed silently).
+                // Note: Set FastByteArrayOutputStream's Logger level to error or higher to suppress this log warning.
+                LOG.warn("Buffer decoding-in-to-out [{}] failed, coderResult [{}]", decoder.charset().name(), result.toString());
+            }
+        }
     }
 
     private static CoderResult decodeAndWrite(Writer writer, ByteBuffer in, CharBuffer out, CharsetDecoder decoder, boolean endOfInput) throws IOException {
         CoderResult result = decoder.decode(in, out, endOfInput);
-        // To begin of decoded data
+        // To begin processing of decoded data
         out.flip();
         // Output
         writer.write(out.toString());
-        // clear output to avoid infinitive loops, see WW-4383
+        // Clear output to avoid infinite loops, see WW-4383
         out.clear();
         return result;
     }
diff --git a/core/src/test/java/org/apache/struts2/views/jsp/IncludeTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/IncludeTagTest.java
index 6b91792..4583085 100644
--- a/core/src/test/java/org/apache/struts2/views/jsp/IncludeTagTest.java
+++ b/core/src/test/java/org/apache/struts2/views/jsp/IncludeTagTest.java
@@ -51,7 +51,7 @@ public class IncludeTagTest extends AbstractTagTest {
 
     public void testIncludeNoParam() throws Exception {
         
-        // use always matcher as we can not determine the excact objects used in mock.include(request, response) call
+        // Use always matcher as we can not determine the exact objects used in mock.include(request, response) call
         mockRequestDispatcher.include(anyObject(ServletRequest.class), anyObject(ServletResponse.class));
         expectLastCall().times(1);
         
@@ -69,7 +69,7 @@ public class IncludeTagTest extends AbstractTagTest {
 
     public void testIncludeWithParameters() throws Exception {
        
-        // use always matcher as we can not determine the excact objects used in mock.include(request, response) call
+        // Use always matcher as we can not determine the exact objects used in mock.include(request, response) call
         mockRequestDispatcher.include(anyObject(ServletRequest.class), anyObject(ServletResponse.class));
         expectLastCall().times(1);
         
@@ -90,7 +90,7 @@ public class IncludeTagTest extends AbstractTagTest {
 
     public void testIncludeRelative2Dots() throws Exception {
         // TODO: we should test for .. in unit test - is this test correct?
-        // use always matcher as we can not determine the exact objects used in mock.include(request, response) call
+        // Use always matcher as we can not determine the exact objects used in mock.include(request, response) call
         mockRequestDispatcher.include(anyObject(ServletRequest.class), anyObject(ServletResponse.class));
         expectLastCall().times(1);
         
@@ -108,6 +108,60 @@ public class IncludeTagTest extends AbstractTagTest {
         verify(mockRequestDispatcher);        
     }
 
+    public void testIncludeSetUseResponseEncodingTrue() throws Exception {
+        // TODO: If possible in future mock-test an actual content-includes with various encodings
+        //   while setting the response encoding to match.  Doesn't appear to be possible
+        //   right now in unit-test form.
+        // Seems that the best we can do is verify the setUseResponseEncoding() doesn't fail...
+
+        // Use always matcher as we can not determine the exact objects used in mock.include(request, response) call
+        mockRequestDispatcher.include(anyObject(ServletRequest.class), anyObject(ServletResponse.class));
+        expectLastCall().times(1);
+
+        replay(mockRequestDispatcher);
+
+        tag.setValue("person/create.jsp");
+        response.setCharacterEncoding("UTF-8");
+        tag.doStartTag();
+        // Manipulate after doStartTag to ensure the tag component has undergone injection
+        Include include = (Include) tag.getComponent();
+        include.setUseResponseEncoding("true");
+        tag.doEndTag();
+
+        assertEquals("UTF-8", response.getCharacterEncoding());
+        assertEquals("/person/create.jsp", request.getRequestDispatherString());
+        assertEquals("", writer.toString());  // Nothing gets written for mock-include
+
+        verify(mockRequestDispatcher);
+    }
+
+    public void testIncludeSetUseResponseEncodingFalse() throws Exception {
+        // TODO: If possible in future mock-test an actual content-includes with various encodings
+        //   while setting the response encoding to match.  Doesn't appear to be possible
+        //   right now in unit-test form.
+        // Seems that the best we can do is verify the setUseResponseEncoding() doesn't fail...
+
+        // Use always matcher as we can not determine the exact objects used in mock.include(request, response) call
+        mockRequestDispatcher.include(anyObject(ServletRequest.class), anyObject(ServletResponse.class));
+        expectLastCall().times(1);
+
+        replay(mockRequestDispatcher);
+
+        tag.setValue("person/create.jsp");
+        response.setCharacterEncoding("UTF-8");
+        tag.doStartTag();
+        // Manipulate after doStartTag to ensure the tag component has undergone injection
+        Include include = (Include) tag.getComponent();
+        include.setUseResponseEncoding("false");
+        tag.doEndTag();
+
+        assertEquals("UTF-8", response.getCharacterEncoding());
+        assertEquals("/person/create.jsp", request.getRequestDispatherString());
+        assertEquals("", writer.toString());  // Nothing gets written for mock-include
+
+        verify(mockRequestDispatcher);
+    }
+
     protected void setUp() throws Exception {
         super.setUp();
         request.setupGetRequestDispatcher(new MockRequestDispatcher());


[struts] 02/02: WW-4971 Use response encoding for include by default

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

amashchenko pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/struts.git

commit 9fd8d6fa8019e7a15ee3dfb9fba17aca36ff0b20
Author: Aleksandr Mashchenko <am...@apache.org>
AuthorDate: Thu Nov 1 22:05:47 2018 +0200

    WW-4971 Use response encoding for include by default
---
 core/src/main/java/org/apache/struts2/components/Include.java | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/core/src/main/java/org/apache/struts2/components/Include.java b/core/src/main/java/org/apache/struts2/components/Include.java
index 616aa18..70692bf 100644
--- a/core/src/main/java/org/apache/struts2/components/Include.java
+++ b/core/src/main/java/org/apache/struts2/components/Include.java
@@ -98,13 +98,12 @@ public class Include extends Component {
     private HttpServletRequest req;
     private HttpServletResponse res;
     private String defaultEncoding;       // Made non-static (during WW-4971 fix)
-    private boolean useResponseEncoding;  // Added with WW-4971 fix (allows switch between usage of response or default encoding)
+    private boolean useResponseEncoding = true;  // Added with WW-4971 fix (allows switch between usage of response or default encoding)
 
     public Include(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
         super(stack);
         this.req = req;
         this.res = res;
-        useResponseEncoding = false;  // By default use defaultEncoding (vs. response/page encoding)
     }
 
     @Inject(StrutsConstants.STRUTS_I18N_ENCODING)