Repository: struts
Updated Branches:
  refs/heads/master 7fdc103e8 -> ef9c66118


WW-4628: proper decoding of parameters in query-string


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

Branch: refs/heads/master
Commit: ef9c66118ede16f3ff239ea864641d5bdadeecae
Parents: 7fdc103
Author: cnenning <cnenn...@apache.org>
Authored: Wed Aug 3 13:02:16 2016 +0200
Committer: cnenning <cnenn...@apache.org>
Committed: Wed Aug 3 13:02:16 2016 +0200

----------------------------------------------------------------------
 .../org/apache/struts2/util/URLDecoderUtil.java | 12 ++++
 .../struts2/views/util/DefaultUrlHelper.java    | 27 +++++---
 .../apache/struts2/util/URLDecoderUtilTest.java |  7 ++
 .../views/util/DefaultUrlHelperTest.java        | 71 +++++---------------
 4 files changed, 53 insertions(+), 64 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/ef9c6611/core/src/main/java/org/apache/struts2/util/URLDecoderUtil.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/struts2/util/URLDecoderUtil.java 
b/core/src/main/java/org/apache/struts2/util/URLDecoderUtil.java
index 10f2a78..3c61d1e 100644
--- a/core/src/main/java/org/apache/struts2/util/URLDecoderUtil.java
+++ b/core/src/main/java/org/apache/struts2/util/URLDecoderUtil.java
@@ -19,4 +19,16 @@ public class URLDecoderUtil {
         return UDecoder.URLDecode(sequence, charset);
     }
 
+    /**
+     * Decodes a <code>x-www-form-urlencoded</code> string.
+     * @param sequence the String to decode
+     * @param charset The name of a supported character encoding.
+     * @param isQueryString whether input is a query string. If 
<code>true</code> other decoding rules apply.
+     * @return the newly decoded <code>String</code>
+     * @exception IllegalArgumentException If the encoding is not valid
+     */
+    public static String decode(String sequence, String charset, boolean 
isQueryString) {
+        return UDecoder.URLDecode(sequence, charset, isQueryString);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/struts/blob/ef9c6611/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 16739af..668d1a9 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
@@ -284,14 +284,25 @@ public class DefaultUrlHelper implements UrlHelper {
         * @return the encoded string
         */
        public String decode( String input ) {
-               try {
-            return URLDecoderUtil.decode(input, encoding);
-               } catch (Exception e) {
-               LOG.warn("Could not decode URL parameter '{}', returning value 
un-decoded", input);
-                       return input;
-               }
+        return URLDecoderUtil.decode(input, encoding, false);
        }
 
+    /**
+     * Decodes the URL using {@link URLDecoderUtil#decode(String, String, 
boolean)} with the encoding specified in the configuration.
+     *
+     * @param input the input to decode
+     * @param isQueryString whether input is a query string. If 
<code>true</code> other decoding rules apply.
+     * @return the encoded string
+     */
+    public String decode( String input, boolean isQueryString ) {
+        try {
+            return URLDecoderUtil.decode(input, encoding, isQueryString);
+        } catch (Exception e) {
+            LOG.warn("Could not decode URL parameter '{}', returning value 
un-decoded", input);
+        return input;
+        }
+    }
+
     public Map<String, Object> parseQueryString(String queryString, boolean 
forceValueArray) {
         Map<String, Object> queryParams = new LinkedHashMap<String, Object>();
         if (queryString != null) {
@@ -308,8 +319,8 @@ public class DefaultUrlHelper implements UrlHelper {
                         paramValue = tmpParams[1];
                     }
                     if (paramName != null) {
-                        paramName = decode(paramName);
-                        String translatedParamValue = decode(paramValue);
+                        paramName = decode(paramName, true);
+                        String translatedParamValue = decode(paramValue, true);
 
                         if (queryParams.containsKey(paramName) || 
forceValueArray) {
                             // WW-1619 append new param value to existing 
value(s)

http://git-wip-us.apache.org/repos/asf/struts/blob/ef9c6611/core/src/test/java/org/apache/struts2/util/URLDecoderUtilTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/struts2/util/URLDecoderUtilTest.java 
b/core/src/test/java/org/apache/struts2/util/URLDecoderUtilTest.java
index f21c08f..fd274bf 100644
--- a/core/src/test/java/org/apache/struts2/util/URLDecoderUtilTest.java
+++ b/core/src/test/java/org/apache/struts2/util/URLDecoderUtilTest.java
@@ -68,4 +68,11 @@ public class URLDecoderUtilTest {
         assertEquals("xxxx\u00ea", result);
     }
 
+    @Test
+    public void testURLDecodePlusCharAsSpace() {
+
+        String result = URLDecoderUtil.decode("a+b", "UTF-8", true);
+        assertEquals("a b", result);
+    }
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/struts/blob/ef9c6611/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 57786c4..b4a5b26 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
@@ -21,22 +21,23 @@
 
 package org.apache.struts2.views.util;
 
-import com.mockobjects.dynamic.Mock;
-import com.opensymphony.xwork2.ActionContext;
-import com.opensymphony.xwork2.inject.Container;
-import com.opensymphony.xwork2.inject.Scope.Strategy;
-import org.apache.struts2.StrutsConstants;
-import org.apache.struts2.StrutsInternalTestCase;
-import org.junit.Ignore;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeMap;
 
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.struts2.StrutsConstants;
+import org.apache.struts2.StrutsInternalTestCase;
+
+import com.mockobjects.dynamic.Mock;
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.inject.Container;
+import com.opensymphony.xwork2.inject.Scope.Strategy;
+
 
 /**
  * Test case for DefaultUrlHelper.
@@ -129,34 +130,6 @@ public class DefaultUrlHelperTest extends 
StrutsInternalTestCase {
            expectedUrl, url.toString());
     }
 
-    @Ignore
-    public void ignoreTestBuildUrlWithJavaScriptInjected() 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";;
 
@@ -423,25 +396,11 @@ public class DefaultUrlHelperTest extends 
StrutsInternalTestCase {
         assertEquals(result, expectedResult);
     }
 
-    @Ignore
-    public void ignoreTestDontEncode() throws Exception {
-        String expectedUrl = 
"http://localhost/contextPath/myAction.action?param1=value+with+spaces";;
+    public void testDecodeSpacesInQueryString() throws Exception {
+        Map<String, Object> queryParameters = 
urlHelper.parseQueryString("name=value+with+space", false);
 
-        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);
+        assertTrue(queryParameters.containsKey("name"));
+        assertEquals("value with space", queryParameters.get("name"));
     }
 
 

Reply via email to