mirror of
https://github.com/apache/struts.git
synced 2026-08-31 19:35:40 +00:00
Merged from STRUTS_2_3_14_X
Disable eval expressions [from revision 1469249] WW-4063 Improved security by making static method attribute immutable [from revision 1486054] WW-4063 Skipping unneeded translation for included parameters [from revision 1486076] WW-4063 Testcase modification after refactoring [from revision 1486164] WW-4063 Testcases for double parameter evaluation problems [from revision 1486576] git-svn-id: https://svn.apache.org/repos/asf/struts/struts2/trunk@1486633 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
@@ -241,47 +241,45 @@ public class DefaultUrlHelper implements UrlHelper {
|
||||
|
||||
private String buildParameterSubstring(String name, String value) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(translateAndEncode(name));
|
||||
builder.append(encode(name));
|
||||
builder.append('=');
|
||||
builder.append(translateAndEncode(value));
|
||||
builder.append(encode(value));
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates any script expressions using {@link com.opensymphony.xwork2.util.TextParseUtil#translateVariables} and
|
||||
* encodes the URL using {@link java.net.URLEncoder#encode} with the encoding specified in the configuration.
|
||||
*
|
||||
* @param input
|
||||
* @return the translated and encoded string
|
||||
*/
|
||||
public String translateAndEncode(String input) {
|
||||
String translatedInput = translateVariable(input);
|
||||
try {
|
||||
return URLEncoder.encode(translatedInput, encoding);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
if (LOG.isWarnEnabled()) {
|
||||
LOG.warn("Could not encode URL parameter '#0', returning value un-encoded", input);
|
||||
}
|
||||
return translatedInput;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Encodes the URL using {@link java.net.URLEncoder#encode} with the encoding specified in the configuration.
|
||||
*
|
||||
* @param input the input to encode
|
||||
* @return the encoded string
|
||||
*/
|
||||
public String encode( String input ) {
|
||||
try {
|
||||
return URLEncoder.encode(input, encoding);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
if (LOG.isWarnEnabled()) {
|
||||
LOG.warn("Could not encode URL parameter '#0', returning value un-encoded", input);
|
||||
}
|
||||
return input;
|
||||
}
|
||||
}
|
||||
|
||||
public String translateAndDecode(String input) {
|
||||
String translatedInput = translateVariable(input);
|
||||
try {
|
||||
return URLDecoder.decode(translatedInput, encoding);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
if (LOG.isWarnEnabled()) {
|
||||
LOG.warn("Could not encode URL parameter '#0', returning value un-encoded", input);
|
||||
}
|
||||
return translatedInput;
|
||||
}
|
||||
}
|
||||
|
||||
private String translateVariable(String input) {
|
||||
ValueStack valueStack = ServletActionContext.getContext().getValueStack();
|
||||
return TextParseUtil.translateVariables(input, valueStack);
|
||||
}
|
||||
/**
|
||||
* Decodes the URL using {@link java.net.URLDecoder#decode(String, String)} with the encoding specified in the configuration.
|
||||
*
|
||||
* @param input the input to decode
|
||||
* @return the encoded string
|
||||
*/
|
||||
public String decode( String input ) {
|
||||
try {
|
||||
return URLDecoder.decode(input, encoding);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
if (LOG.isWarnEnabled()) {
|
||||
LOG.warn("Could not decode URL parameter '#0', returning value un-decoded", input);
|
||||
}
|
||||
return input;
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, Object> parseQueryString(String queryString, boolean forceValueArray) {
|
||||
Map<String, Object> queryParams = new LinkedHashMap<String, Object>();
|
||||
@@ -299,8 +297,8 @@ public class DefaultUrlHelper implements UrlHelper {
|
||||
paramValue = tmpParams[1];
|
||||
}
|
||||
if (paramName != null) {
|
||||
paramName = translateAndDecode(paramName);
|
||||
String translatedParamValue = translateAndDecode(paramValue);
|
||||
paramName = decode(paramName);
|
||||
String translatedParamValue = decode(paramValue);
|
||||
|
||||
if (queryParams.containsKey(paramName) || forceValueArray) {
|
||||
// WW-1619 append new param value to existing value(s)
|
||||
|
||||
@@ -21,16 +21,12 @@
|
||||
|
||||
package org.apache.struts2.views.jsp;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpSession;
|
||||
import javax.servlet.jsp.JspWriter;
|
||||
|
||||
import com.mockobjects.dynamic.Mock;
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import com.opensymphony.xwork2.ActionProxy;
|
||||
import com.opensymphony.xwork2.DefaultActionInvocation;
|
||||
import com.opensymphony.xwork2.DefaultActionProxyFactory;
|
||||
import com.opensymphony.xwork2.inject.Container;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.components.URL;
|
||||
import org.apache.struts2.dispatcher.ApplicationMap;
|
||||
@@ -40,15 +36,14 @@ import org.apache.struts2.dispatcher.SessionMap;
|
||||
import org.apache.struts2.dispatcher.mapper.ActionMapping;
|
||||
import org.apache.struts2.dispatcher.mapper.DefaultActionMapper;
|
||||
|
||||
import com.mockobjects.dynamic.Mock;
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import com.opensymphony.xwork2.ActionProxy;
|
||||
import com.opensymphony.xwork2.DefaultActionInvocation;
|
||||
import com.opensymphony.xwork2.DefaultActionProxy;
|
||||
import com.opensymphony.xwork2.DefaultActionProxyFactory;
|
||||
import com.opensymphony.xwork2.config.providers.XWorkConfigurationProvider;
|
||||
import com.opensymphony.xwork2.config.providers.XmlConfigurationProvider;
|
||||
import com.opensymphony.xwork2.inject.Container;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import javax.servlet.jsp.JspWriter;
|
||||
import java.io.File;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Unit test for {@link URLTag}.
|
||||
@@ -619,6 +614,69 @@ public class URLTagTest extends AbstractUITagTest {
|
||||
|
||||
}
|
||||
|
||||
public void testEmbeddedParamTagExpressionGetsEvaluatedCorrectly() throws Exception {
|
||||
request.setRequestURI("/public/about");
|
||||
request.setQueryString("section=team&company=acme inc");
|
||||
|
||||
tag.setAction("team");
|
||||
tag.setIncludeParams("all");
|
||||
|
||||
tag.doStartTag();
|
||||
|
||||
Foo foo = new Foo("test");
|
||||
stack.push(foo);
|
||||
|
||||
// include nested param tag
|
||||
ParamTag paramTag = new ParamTag();
|
||||
paramTag.setPageContext(pageContext);
|
||||
paramTag.setName("title");
|
||||
paramTag.setValue("%{title}");
|
||||
paramTag.doStartTag();
|
||||
paramTag.doEndTag();
|
||||
|
||||
tag.doEndTag();
|
||||
|
||||
assertEquals("/team.action?section=team&company=acme+inc&title=test", writer.toString());
|
||||
}
|
||||
|
||||
public void testAccessToStackInternalsGetsHandledCorrectly() throws Exception {
|
||||
Map<String, Object> params = new HashMap<String, Object>();
|
||||
params.put("aaa", new String[] {"1${#session[\"foo\"]='true'}"});
|
||||
params.put("aab", new String[] {"1${#session[\"bar\"]}"});
|
||||
params.put("aac", new String[] {"1${#_memberAccess[\"allowStaticMethodAccess\"]='true'}"});
|
||||
params.put("aad", new String[] {"1${#_memberAccess[\"allowStaticMethodAccess\"]}"});
|
||||
|
||||
request.setParameterMap(params);
|
||||
request.setRequestURI("/public/about");
|
||||
request.setQueryString("aae${%23session[\"bar\"]}=1%24%7B%23session%5B%22bar%22%5D%7D");
|
||||
session.put("bar", "rab");
|
||||
|
||||
tag.setAction("team");
|
||||
tag.setIncludeParams("all");
|
||||
|
||||
tag.doStartTag();
|
||||
tag.doEndTag();
|
||||
|
||||
Object allowMethodAccess = stack.findValue("\u0023_memberAccess['allowStaticMethodAccess']");
|
||||
assertNotNull(allowMethodAccess);
|
||||
assertEquals(Boolean.FALSE, allowMethodAccess);
|
||||
|
||||
assertNull(session.get("foo"));
|
||||
|
||||
assertEquals("/team.action?" +
|
||||
"aab=1%24%7B%23session%5B%22bar%22%5D%7D" +
|
||||
"&" +
|
||||
"aac=1%24%7B%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3D%27true%27%7D" +
|
||||
"&" +
|
||||
"aaa=1%24%7B%23session%5B%22foo%22%5D%3D%27true%27%7D" +
|
||||
"&" +
|
||||
"aad=1%24%7B%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%7D" +
|
||||
"&"+
|
||||
"aae%24%7B%23session%5B%22bar%22%5D%7D=1%24%7B%23session%5B%22bar%22%5D%7D"
|
||||
, writer.toString()
|
||||
);
|
||||
}
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
@@ -635,7 +693,14 @@ public class URLTagTest extends AbstractUITagTest {
|
||||
public static class Foo {
|
||||
private String title;
|
||||
|
||||
public void setTitle(String title) {
|
||||
public Foo() {
|
||||
}
|
||||
|
||||
public Foo( String title ) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
|
||||
@@ -378,17 +378,17 @@ public class DefaultUrlHelperTest extends StrutsTestCase {
|
||||
}
|
||||
|
||||
|
||||
public void testTranslateAndEncode() throws Exception {
|
||||
public void testEncode() throws Exception {
|
||||
setProp(StrutsConstants.STRUTS_I18N_ENCODING, "UTF-8");
|
||||
String result = urlHelper.translateAndEncode("\u65b0\u805e");
|
||||
String result = urlHelper.encode("\u65b0\u805e");
|
||||
String expectedResult = "%E6%96%B0%E8%81%9E";
|
||||
|
||||
assertEquals(result, expectedResult);
|
||||
}
|
||||
|
||||
public void testTranslateAndDecode() throws Exception {
|
||||
public void testDecode() throws Exception {
|
||||
setProp(StrutsConstants.STRUTS_I18N_ENCODING, "UTF-8");
|
||||
String result = urlHelper.translateAndDecode("%E6%96%B0%E8%81%9E");
|
||||
String result = urlHelper.decode("%E6%96%B0%E8%81%9E");
|
||||
String expectedResult = "\u65b0\u805e";
|
||||
|
||||
assertEquals(result, expectedResult);
|
||||
|
||||
@@ -32,7 +32,7 @@ import java.util.regex.Pattern;
|
||||
*/
|
||||
public class SecurityMemberAccess extends DefaultMemberAccess {
|
||||
|
||||
private boolean allowStaticMethodAccess;
|
||||
private final boolean allowStaticMethodAccess;
|
||||
Set<Pattern> excludeProperties = Collections.emptySet();
|
||||
Set<Pattern> acceptProperties = Collections.emptySet();
|
||||
|
||||
@@ -45,10 +45,6 @@ public class SecurityMemberAccess extends DefaultMemberAccess {
|
||||
return allowStaticMethodAccess;
|
||||
}
|
||||
|
||||
public void setAllowStaticMethodAccess(boolean allowStaticMethodAccess) {
|
||||
this.allowStaticMethodAccess = allowStaticMethodAccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccessible(Map context, Object target, Member member,
|
||||
String propertyName) {
|
||||
|
||||
Reference in New Issue
Block a user