Repository: struts
Updated Branches:
  refs/heads/support-2-3 e8b48f8bb -> ae2840f18


merged fix for WW-4628 (avoid double encoding of url parameters)


Project: http://git-wip-us.apache.org/repos/asf/struts/repo
Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/ae2840f1
Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/ae2840f1
Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/ae2840f1

Branch: refs/heads/support-2-3
Commit: ae2840f18386492530de1fb875ca9f8804adbb3e
Parents: e8b48f8
Author: cnenning <cnenn...@apache.org>
Authored: Mon Aug 1 13:50:23 2016 +0200
Committer: cnenning <cnenn...@apache.org>
Committed: Mon Aug 1 13:50:23 2016 +0200

----------------------------------------------------------------------
 .../struts2/views/util/DefaultUrlHelper.java    | 33 +++++++++----
 .../views/util/DefaultUrlHelperTest.java        | 50 +++++++++++++++++++-
 2 files changed, 74 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/ae2840f1/core/src/main/java/org/apache/struts2/views/util/DefaultUrlHelper.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/struts2/views/util/DefaultUrlHelper.java 
b/core/src/main/java/org/apache/struts2/views/util/DefaultUrlHelper.java
index 66a9b7c..05895f0 100644
--- a/core/src/main/java/org/apache/struts2/views/util/DefaultUrlHelper.java
+++ b/core/src/main/java/org/apache/struts2/views/util/DefaultUrlHelper.java
@@ -24,6 +24,18 @@ package org.apache.struts2.views.util;
 import com.opensymphony.xwork2.inject.Inject;
 import com.opensymphony.xwork2.util.logging.Logger;
 import com.opensymphony.xwork2.util.logging.LoggerFactory;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
 import org.apache.commons.lang3.StringEscapeUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.struts2.StrutsConstants;
@@ -178,10 +190,11 @@ public class DefaultUrlHelper implements UrlHelper {
         }
 
         //if the action was not explicitly set grab the params from the request
+        //always pass encode=false here as encoding might happen for complete 
URL later
         if (escapeAmp) {
-            buildParametersString(params, link, AMP);
+            buildParametersString(params, link, AMP, false);
         } else {
-            buildParametersString(params, link, "&");
+            buildParametersString(params, link, "&", false);
         }
 
         String result = link.toString();
@@ -202,6 +215,10 @@ public class DefaultUrlHelper implements UrlHelper {
     }
 
     public void buildParametersString(Map<String, Object> params, 
StringBuilder link, String paramSeparator) {
+        buildParametersString(params, link, paramSeparator, true);
+    }
+
+    public void buildParametersString(Map<String, Object> params, 
StringBuilder link, String paramSeparator, boolean encode) {
         if ((params != null) && (params.size() > 0)) {
             if (!link.toString().contains("?")) {
                 link.append("?");
@@ -219,7 +236,7 @@ public class DefaultUrlHelper implements UrlHelper {
                 if (value instanceof Iterable) {
                     for (Iterator iterator = ((Iterable) value).iterator(); 
iterator.hasNext();) {
                         Object paramValue = iterator.next();
-                        link.append(buildParameterSubstring(name, paramValue 
!= null ? paramValue.toString() : StringUtils.EMPTY));
+                        link.append(buildParameterSubstring(name, paramValue 
!= null ? paramValue.toString() : StringUtils.EMPTY, encode));
 
                         if (iterator.hasNext()) {
                             link.append(paramSeparator);
@@ -229,14 +246,14 @@ public class DefaultUrlHelper implements UrlHelper {
                     Object[] array = (Object[]) value;
                     for (int i = 0; i < array.length; i++) {
                         Object paramValue = array[i];
-                        link.append(buildParameterSubstring(name, paramValue 
!= null ? paramValue.toString() : StringUtils.EMPTY));
+                        link.append(buildParameterSubstring(name, paramValue 
!= null ? paramValue.toString() : StringUtils.EMPTY, encode));
 
                         if (i < array.length - 1) {
                             link.append(paramSeparator);
                         }
                     }
                 } else {
-                    link.append(buildParameterSubstring(name, value != null ? 
value.toString() : StringUtils.EMPTY));
+                    link.append(buildParameterSubstring(name, value != null ? 
value.toString() : StringUtils.EMPTY, encode));
                 }
 
                 if (iter.hasNext()) {
@@ -250,11 +267,11 @@ public class DefaultUrlHelper implements UrlHelper {
         return HTTP_PROTOCOL.equals(scheme) || HTTPS_PROTOCOL.equals(scheme);
     }
 
-    private String buildParameterSubstring(String name, String value) {
+    private String buildParameterSubstring(String name, String value, boolean 
encode) {
         StringBuilder builder = new StringBuilder();
-        builder.append(encode(name));
+        builder.append(encode ? encode(name) : name);
         builder.append('=');
-        builder.append(encode(value));
+        builder.append(encode ? encode(value) : value);
         return builder.toString();
     }
 

http://git-wip-us.apache.org/repos/asf/struts/blob/ae2840f1/core/src/test/java/org/apache/struts2/views/util/DefaultUrlHelperTest.java
----------------------------------------------------------------------
diff --git 
a/core/src/test/java/org/apache/struts2/views/util/DefaultUrlHelperTest.java 
b/core/src/test/java/org/apache/struts2/views/util/DefaultUrlHelperTest.java
index 6fda181..aa66602 100644
--- a/core/src/test/java/org/apache/struts2/views/util/DefaultUrlHelperTest.java
+++ b/core/src/test/java/org/apache/struts2/views/util/DefaultUrlHelperTest.java
@@ -128,6 +128,33 @@ public class DefaultUrlHelperTest extends 
StrutsInternalTestCase {
            expectedUrl, url.toString());
     }
 
+    public void testBuildUrlWithJavaScriptInjected() throws Exception {
+        String expectedUrl = 
"http://localhost:8080/myContext/myPage.jsp?initParam=initValue&amp;param1=value1&amp;param2=value2&amp;param3%22%3Cscript+type%3D%22text%2Fjavascript%22%3Ealert%281%29%3B%3C%2Fscript%3E=value3";;
+
+        // there is explicit escaping for EcmaScript before URL encoding
+        String expectedUrlBeforeEncoding = 
"http:\\/\\/localhost:8080\\/myContext\\/myPage.jsp?initParam=initValue&amp;param1=value1&amp;param2=value2&amp;param3\\\"<script
 type=\\\"text\\/javascript\\\">alert(1);<\\/script>=value3";
+
+        Mock mockHttpServletRequest = new Mock(HttpServletRequest.class);
+        mockHttpServletRequest.expectAndReturn("getScheme", "http");
+        mockHttpServletRequest.expectAndReturn("getServerName", "localhost");
+        mockHttpServletRequest.expectAndReturn("getContextPath", "/myContext");
+        mockHttpServletRequest.expectAndReturn("getServerPort", 8080);
+
+        Mock mockHttpServletResponse = new Mock(HttpServletResponse.class);
+        mockHttpServletResponse.expectAndReturn("encodeURL", 
expectedUrlBeforeEncoding, expectedUrl);
+
+        Map parameters = new LinkedHashMap();
+        parameters.put("param1", "value1");
+        parameters.put("param2", "value2");
+        parameters.put("param3\"<script 
type=\"text/javascript\">alert(1);</script>","value3");
+
+        String result = urlHelper.buildUrl("/myPage.jsp?initParam=initValue", 
(HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) 
mockHttpServletResponse.proxy(), parameters, "http", true, true, true);
+
+        assertEquals(
+           expectedUrl, result);
+        mockHttpServletRequest.verify();
+    }
+
     public void testForceAddNullSchemeHostAndPort() throws Exception {
         String expectedUrl = 
"http://localhost/contextPath/path1/path2/myAction.action";;
 
@@ -393,7 +420,28 @@ public class DefaultUrlHelperTest extends 
StrutsInternalTestCase {
 
         assertEquals(result, expectedResult);
     }
-    
+
+    public void testDontEncode() throws Exception {
+        String expectedUrl = 
"http://localhost/contextPath/myAction.action?param1=value+with+spaces";;
+
+        Mock mockHttpServletRequest = new Mock(HttpServletRequest.class);
+        mockHttpServletRequest.expectAndReturn("getScheme", "http");
+        mockHttpServletRequest.expectAndReturn("getServerName", "localhost");
+        mockHttpServletRequest.expectAndReturn("getContextPath", 
"/contextPath");
+        mockHttpServletRequest.expectAndReturn("getServerPort", 80);
+
+        Mock mockHttpServletResponse = new Mock(HttpServletResponse.class);
+
+        Map parameters = new LinkedHashMap();
+        parameters.put("param1", "value+with+spaces");
+
+        String result = urlHelper.buildUrl("/myAction.action", 
(HttpServletRequest) mockHttpServletRequest.proxy(), (HttpServletResponse) 
mockHttpServletResponse.proxy(), parameters, "http", true, false, true);
+
+        assertEquals(
+           expectedUrl, result);
+    }
+
+
     public void setUp() throws Exception {
         super.setUp();
         stubContainer = new StubContainer(container);

Reply via email to