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 3c61d1ec4..10f2a7855 100644 --- a/core/src/main/java/org/apache/struts2/util/URLDecoderUtil.java +++ b/core/src/main/java/org/apache/struts2/util/URLDecoderUtil.java @@ -19,16 +19,4 @@ public class URLDecoderUtil { return UDecoder.URLDecode(sequence, charset); } - /** - * Decodes a x-www-form-urlencoded 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 true other decoding rules apply. - * @return the newly decoded String - * @exception IllegalArgumentException If the encoding is not valid - */ - public static String decode(String sequence, String charset, boolean isQueryString) { - return UDecoder.URLDecode(sequence, charset, isQueryString); - } - } 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 668d1a94e..16739af63 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,25 +284,14 @@ public class DefaultUrlHelper implements UrlHelper { * @return the encoded string */ public String decode( String input ) { - return URLDecoderUtil.decode(input, encoding, false); + try { + return URLDecoderUtil.decode(input, encoding); + } catch (Exception e) { + LOG.warn("Could not decode URL parameter '{}', returning value un-decoded", input); + return input; + } } - /** - * 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 true 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 parseQueryString(String queryString, boolean forceValueArray) { Map queryParams = new LinkedHashMap(); if (queryString != null) { @@ -319,8 +308,8 @@ public class DefaultUrlHelper implements UrlHelper { paramValue = tmpParams[1]; } if (paramName != null) { - paramName = decode(paramName, true); - String translatedParamValue = decode(paramValue, true); + paramName = decode(paramName); + String translatedParamValue = decode(paramValue); if (queryParams.containsKey(paramName) || forceValueArray) { // WW-1619 append new param value to existing value(s) 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 fd274bf34..f21c08fc8 100644 --- a/core/src/test/java/org/apache/struts2/util/URLDecoderUtilTest.java +++ b/core/src/test/java/org/apache/struts2/util/URLDecoderUtilTest.java @@ -68,11 +68,4 @@ 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 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 b4a5b26c4..57786c49b 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,23 +21,22 @@ 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. @@ -130,6 +129,34 @@ public class DefaultUrlHelperTest extends StrutsInternalTestCase { expectedUrl, url.toString()); } + @Ignore + public void ignoreTestBuildUrlWithJavaScriptInjected() throws Exception { + String expectedUrl = "http://localhost:8080/myContext/myPage.jsp?initParam=initValue&param1=value1&param2=value2&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&param1=value1&param2=value2&param3\\\"","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"; @@ -396,11 +423,25 @@ public class DefaultUrlHelperTest extends StrutsInternalTestCase { assertEquals(result, expectedResult); } - public void testDecodeSpacesInQueryString() throws Exception { - Map queryParameters = urlHelper.parseQueryString("name=value+with+space", false); + @Ignore + public void ignoreTestDontEncode() throws Exception { + String expectedUrl = "http://localhost/contextPath/myAction.action?param1=value+with+spaces"; - assertTrue(queryParameters.containsKey("name")); - assertEquals("value with space", queryParameters.get("name")); + 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); }