mirror of
https://github.com/apache/struts.git
synced 2026-08-08 08:07:17 +00:00
Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e8656d5737 | |||
| 7f10ed505f | |||
| 043814b774 | |||
| 0fabde9f97 | |||
| 4457f03c70 | |||
| 3d3512a399 | |||
| 59a6cbf6ca | |||
| 19802b0614 | |||
| e46e662a7a | |||
| 4786fba0d7 | |||
| e32bd7dba9 | |||
| 6e1d2add07 | |||
| 2eeac367fe | |||
| 30b43044a3 | |||
| 5c82f0246e | |||
| fff35cfd9d | |||
| 1526b36dd6 | |||
| 6d6a422db7 | |||
| 5cf57b9132 | |||
| f4c0135878 | |||
| 77cfae3084 | |||
| ec56290056 | |||
| 47c87bc62c | |||
| ce467b7fa5 | |||
| 73eb6ed189 | |||
| 80a91dc75f |
+1
-1
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
</parent>
|
||||
<artifactId>struts2-apps</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
@@ -24,12 +24,12 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-apps</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-rest-showcase</artifactId>
|
||||
<packaging>war</packaging>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
<name>Struts 2 Rest Showcase Webapp</name>
|
||||
<description>Struts 2 Rest Showcase Example</description>
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-apps</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-showcase</artifactId>
|
||||
@@ -167,7 +167,7 @@
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
<version>5.1.3.Final</version>
|
||||
<version>5.4.3.Final</version>
|
||||
</dependency>
|
||||
|
||||
<!-- The Servlet API mocks in Spring Framework 4.x only supports Servlet 3.0 and higher.
|
||||
|
||||
+8
@@ -84,4 +84,12 @@ public class FileUploadAction extends ActionSupport {
|
||||
public void setCaption(String caption) {
|
||||
this.caption = caption;
|
||||
}
|
||||
|
||||
public long getUploadSize() {
|
||||
if (upload != null) {
|
||||
return upload.length();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@
|
||||
<validators>
|
||||
<field name="upload">
|
||||
<field-validator type="fieldexpression">
|
||||
<param name="expression"><![CDATA[upload.length() > 0]]></param>
|
||||
<param name="expression"><![CDATA[getUploadSize() > 0]]></param>
|
||||
<message>File cannot be empty</message>
|
||||
</field-validator>
|
||||
</field>
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
<div class="hero-unit">
|
||||
<h1>Welcome!</h1>
|
||||
<p>The Struts Showcase demonstrates a variety of use cases and tag usages. Essentially, the application exercises various framework features in isolation. The Showcase is not meant as a "best practices" example.</p>
|
||||
<p>For more "by example" solutions, see the <a class="btn btn-primary btn-large">Struts Cookbook »</a> pages.</p>
|
||||
<p>For more "by example" solutions, see the <a href="https://github.com/apache/struts-examples" class="btn btn-primary btn-large">Struts Examples »</a> pages.</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-assembly</artifactId>
|
||||
|
||||
+3
-3
@@ -30,7 +30,7 @@
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-bom</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>Struts 2 Bill of Materials</name>
|
||||
@@ -45,7 +45,7 @@
|
||||
</licenses>
|
||||
|
||||
<properties>
|
||||
<struts-version.version>2.5.22</struts-version.version>
|
||||
<struts-version.version>2.5.23</struts-version.version>
|
||||
<maven.site.skip>true</maven.site.skip>
|
||||
<maven.site.deploy.skip>true</maven.site.deploy.skip>
|
||||
</properties>
|
||||
@@ -181,6 +181,6 @@
|
||||
</dependencyManagement>
|
||||
|
||||
<scm>
|
||||
<tag>STRUTS_2_5_22</tag>
|
||||
<tag>STRUTS_2_5_23</tag>
|
||||
</scm>
|
||||
</project>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-osgi-bundles</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-osgi-admin-bundle</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-osgi-bundles</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-osgi-demo-bundle</artifactId>
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-osgi-bundles</artifactId>
|
||||
|
||||
+3
-2
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
</parent>
|
||||
<artifactId>struts2-core</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
@@ -190,7 +190,8 @@
|
||||
<dependency>
|
||||
<groupId>com.sun</groupId>
|
||||
<artifactId>tools</artifactId>
|
||||
<version>1.5.0</version>
|
||||
<version>1.7.0</version>
|
||||
<!-- Match version of minimum compatible version -->
|
||||
<scope>system</scope>
|
||||
<systemPath>${java.home}/../lib/tools.jar</systemPath>
|
||||
</dependency>
|
||||
|
||||
@@ -36,10 +36,8 @@ import java.util.*;
|
||||
* @since 2.1
|
||||
*/
|
||||
public abstract class AbstractMatcher<E> implements Serializable {
|
||||
/**
|
||||
* <p> The logging instance </p>
|
||||
*/
|
||||
private static final Logger log = LogManager.getLogger(AbstractMatcher.class);
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(AbstractMatcher.class);
|
||||
|
||||
/**
|
||||
* <p> Handles all wildcard pattern matching. </p>
|
||||
@@ -50,10 +48,34 @@ public abstract class AbstractMatcher<E> implements Serializable {
|
||||
* <p> The compiled patterns and their associated target objects </p>
|
||||
*/
|
||||
List<Mapping<E>> compiledPatterns = new ArrayList<>();
|
||||
;
|
||||
|
||||
/**
|
||||
* This flag controls if passed named params should be appended
|
||||
* to the map in {@link #replaceParameters(Map, Map)}
|
||||
* and will be accessible in {@link com.opensymphony.xwork2.config.entities.ResultConfig}.
|
||||
* If set to false, the named parameters won't be appended.
|
||||
*
|
||||
* This behaviour is controlled by {@link org.apache.struts2.StrutsConstants#STRUTS_MATCHER_APPEND_NAMED_PARAMETERS}
|
||||
*
|
||||
* @since 2.5.23
|
||||
* See WW-5065
|
||||
*/
|
||||
private final boolean appendNamedParameters;
|
||||
|
||||
public AbstractMatcher(PatternMatcher<?> helper) {
|
||||
public AbstractMatcher(PatternMatcher<?> helper, boolean appendNamedParameters) {
|
||||
this.wildcard = (PatternMatcher<Object>) helper;
|
||||
this.appendNamedParameters = appendNamedParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a matcher with {@link #appendNamedParameters} set to true to keep backward compatibility
|
||||
*
|
||||
* @param helper an instance of {@link PatternMatcher}
|
||||
* @deprecated use @{link {@link AbstractMatcher(PatternMatcher, boolean)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public AbstractMatcher(PatternMatcher<?> helper) {
|
||||
this(helper, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,17 +106,17 @@ public abstract class AbstractMatcher<E> implements Serializable {
|
||||
name = name.substring(1);
|
||||
}
|
||||
|
||||
log.debug("Compiling pattern '{}'", name);
|
||||
LOG.debug("Compiling pattern '{}'", name);
|
||||
|
||||
pattern = wildcard.compilePattern(name);
|
||||
compiledPatterns.add(new Mapping<E>(name, pattern, target));
|
||||
compiledPatterns.add(new Mapping<>(name, pattern, target));
|
||||
|
||||
if (looseMatch) {
|
||||
int lastStar = name.lastIndexOf('*');
|
||||
if (lastStar > 1 && lastStar == name.length() - 1) {
|
||||
if (name.charAt(lastStar - 1) != '*') {
|
||||
pattern = wildcard.compilePattern(name.substring(0, lastStar - 1));
|
||||
compiledPatterns.add(new Mapping<E>(name, pattern, target));
|
||||
compiledPatterns.add(new Mapping<>(name, pattern, target));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -115,12 +137,12 @@ public abstract class AbstractMatcher<E> implements Serializable {
|
||||
E config = null;
|
||||
|
||||
if (compiledPatterns.size() > 0) {
|
||||
log.debug("Attempting to match '{}' to a wildcard pattern, {} available", potentialMatch, compiledPatterns.size());
|
||||
LOG.debug("Attempting to match '{}' to a wildcard pattern, {} available", potentialMatch, compiledPatterns.size());
|
||||
|
||||
Map<String,String> vars = new LinkedHashMap<String,String>();
|
||||
Map<String,String> vars = new LinkedHashMap<>();
|
||||
for (Mapping<E> m : compiledPatterns) {
|
||||
if (wildcard.match(vars, potentialMatch, m.getPattern())) {
|
||||
log.debug("Value matches pattern '{}'", m.getOriginalPattern());
|
||||
LOG.debug("Value matches pattern '{}'", m.getOriginalPattern());
|
||||
config = convert(potentialMatch, m.getTarget(), vars);
|
||||
break;
|
||||
}
|
||||
@@ -152,20 +174,23 @@ public abstract class AbstractMatcher<E> implements Serializable {
|
||||
*/
|
||||
protected Map<String,String> replaceParameters(Map<String, String> orig, Map<String,String> vars) {
|
||||
Map<String, String> map = new LinkedHashMap<>();
|
||||
|
||||
|
||||
//this will set the group index references, like {1}
|
||||
for (Map.Entry<String,String> entry : orig.entrySet()) {
|
||||
map.put(entry.getKey(), convertParam(entry.getValue(), vars));
|
||||
}
|
||||
|
||||
//the values map will contain entries like name->"Lex Luthor" and 1->"Lex Luthor"
|
||||
//now add the non-numeric values
|
||||
for (Map.Entry<String,String> entry: vars.entrySet()) {
|
||||
if (!NumberUtils.isCreatable(entry.getKey())) {
|
||||
map.put(entry.getKey(), entry.getValue());
|
||||
|
||||
if (appendNamedParameters) {
|
||||
LOG.debug("Appending named parameters to the result map");
|
||||
//the values map will contain entries like name->"Lex Luthor" and 1->"Lex Luthor"
|
||||
//now add the non-numeric values
|
||||
for (Map.Entry<String,String> entry: vars.entrySet()) {
|
||||
if (!NumberUtils.isCreatable(entry.getKey())) {
|
||||
map.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
@@ -192,7 +217,7 @@ public abstract class AbstractMatcher<E> implements Serializable {
|
||||
c = val.charAt(x);
|
||||
if (x < len - 2 &&
|
||||
c == '{' && '}' == val.charAt(x+2)) {
|
||||
varVal = (String)vars.get(String.valueOf(val.charAt(x + 1)));
|
||||
varVal = vars.get(String.valueOf(val.charAt(x + 1)));
|
||||
if (varVal != null) {
|
||||
ret.append(varVal);
|
||||
}
|
||||
@@ -213,18 +238,18 @@ public abstract class AbstractMatcher<E> implements Serializable {
|
||||
/**
|
||||
* <p> The original pattern. </p>
|
||||
*/
|
||||
private String original;
|
||||
private final String original;
|
||||
|
||||
|
||||
/**
|
||||
* <p> The compiled pattern. </p>
|
||||
*/
|
||||
private Object pattern;
|
||||
private final Object pattern;
|
||||
|
||||
/**
|
||||
* <p> The original object. </p>
|
||||
*/
|
||||
private E config;
|
||||
private final E config;
|
||||
|
||||
/**
|
||||
* <p> Contructs a read-only Mapping instance. </p>
|
||||
|
||||
@@ -58,7 +58,33 @@ public class ActionConfigMatcher extends AbstractMatcher<ActionConfig> implement
|
||||
public ActionConfigMatcher(PatternMatcher<?> patternMatcher,
|
||||
Map<String, ActionConfig> configs,
|
||||
boolean looseMatch) {
|
||||
super(patternMatcher);
|
||||
this(patternMatcher, configs, looseMatch, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> Finds and precompiles the wildcard patterns from the ActionConfig
|
||||
* "path" attributes. ActionConfig's will be evaluated in the order they
|
||||
* exist in the config file. Only paths that actually contain a
|
||||
* wildcard will be compiled. </p>
|
||||
*
|
||||
* <p>Patterns can optionally be matched "loosely". When
|
||||
* the end of the pattern matches \*[^*]\*$ (wildcard, no wildcard,
|
||||
* wildcard), if the pattern fails, it is also matched as if the
|
||||
* last two characters didn't exist. The goal is to support the
|
||||
* legacy "*!*" syntax, where the "!*" is optional.</p>
|
||||
*
|
||||
* @param patternMatcher pattern matcher
|
||||
* @param configs An array of ActionConfig's to process
|
||||
* @param looseMatch To loosely match wildcards or not
|
||||
* @param appendNamedParameters To append named parameters or not
|
||||
*
|
||||
* @since 2.5.23
|
||||
* See WW-5065
|
||||
*/
|
||||
public ActionConfigMatcher(PatternMatcher<?> patternMatcher,
|
||||
Map<String, ActionConfig> configs,
|
||||
boolean looseMatch, boolean appendNamedParameters) {
|
||||
super(patternMatcher, appendNamedParameters);
|
||||
for (Map.Entry<String, ActionConfig> entry : configs.entrySet()) {
|
||||
addPattern(entry.getKey(), entry.getValue(), looseMatch);
|
||||
}
|
||||
|
||||
@@ -289,6 +289,8 @@ public class DefaultConfiguration implements Configuration {
|
||||
builder.constant(XWorkConstants.RELOAD_XML_CONFIGURATION, "false");
|
||||
builder.constant(StrutsConstants.STRUTS_I18N_RELOAD, "false");
|
||||
|
||||
builder.constant(StrutsConstants.STRUTS_MATCHER_APPEND_NAMED_PARAMETERS, "true");
|
||||
|
||||
return builder.create(true);
|
||||
}
|
||||
|
||||
@@ -338,8 +340,12 @@ public class DefaultConfiguration implements Configuration {
|
||||
}
|
||||
|
||||
PatternMatcher<int[]> matcher = container.getInstance(PatternMatcher.class);
|
||||
boolean appendNamedParameters = Boolean.parseBoolean(
|
||||
container.getInstance(String.class, StrutsConstants.STRUTS_MATCHER_APPEND_NAMED_PARAMETERS)
|
||||
);
|
||||
|
||||
return new RuntimeConfigurationImpl(Collections.unmodifiableMap(namespaceActionConfigs),
|
||||
Collections.unmodifiableMap(namespaceConfigs), matcher);
|
||||
Collections.unmodifiableMap(namespaceConfigs), matcher, appendNamedParameters);
|
||||
}
|
||||
|
||||
private void setDefaultResults(Map<String, ResultConfig> results, PackageConfig packageContext) {
|
||||
@@ -417,15 +423,18 @@ public class DefaultConfiguration implements Configuration {
|
||||
|
||||
public RuntimeConfigurationImpl(Map<String, Map<String, ActionConfig>> namespaceActionConfigs,
|
||||
Map<String, String> namespaceConfigs,
|
||||
PatternMatcher<int[]> matcher) {
|
||||
PatternMatcher<int[]> matcher,
|
||||
boolean appendNamedParameters)
|
||||
{
|
||||
this.namespaceActionConfigs = namespaceActionConfigs;
|
||||
this.namespaceConfigs = namespaceConfigs;
|
||||
|
||||
this.namespaceActionConfigMatchers = new LinkedHashMap<>();
|
||||
this.namespaceMatcher = new NamespaceMatcher(matcher, namespaceActionConfigs.keySet());
|
||||
this.namespaceMatcher = new NamespaceMatcher(matcher, namespaceActionConfigs.keySet(), appendNamedParameters);
|
||||
|
||||
for (Map.Entry<String, Map<String, ActionConfig>> entry : namespaceActionConfigs.entrySet()) {
|
||||
namespaceActionConfigMatchers.put(entry.getKey(), new ActionConfigMatcher(matcher, entry.getValue(), true));
|
||||
ActionConfigMatcher configMatcher = new ActionConfigMatcher(matcher, entry.getValue(), true, appendNamedParameters);
|
||||
namespaceActionConfigMatchers.put(entry.getKey(), configMatcher);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,9 +29,23 @@ import java.util.Set;
|
||||
* @since 2.1
|
||||
*/
|
||||
public class NamespaceMatcher extends AbstractMatcher<NamespaceMatch> {
|
||||
public NamespaceMatcher(PatternMatcher<?> patternMatcher,
|
||||
Set<String> namespaces) {
|
||||
super(patternMatcher);
|
||||
|
||||
public NamespaceMatcher(PatternMatcher<?> patternMatcher, Set<String> namespaces) {
|
||||
this(patternMatcher, namespaces, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches namespace strings against a wildcard pattern matcher
|
||||
*
|
||||
* @param patternMatcher pattern matcher
|
||||
* @param namespaces A set of namespaces to process
|
||||
* @param appendNamedParameters To append named parameters or not
|
||||
*
|
||||
* @since 2.5.23
|
||||
* See WW-5065
|
||||
*/
|
||||
public NamespaceMatcher(PatternMatcher<?> patternMatcher, Set<String> namespaces, boolean appendNamedParameters) {
|
||||
super(patternMatcher, appendNamedParameters);
|
||||
for (String name : namespaces) {
|
||||
if (!patternMatcher.isLiteral(name)) {
|
||||
addPattern(name, new NamespaceMatch(name, null), false);
|
||||
|
||||
+2
@@ -108,6 +108,7 @@ import com.opensymphony.xwork2.validator.DefaultValidatorFactory;
|
||||
import com.opensymphony.xwork2.validator.DefaultValidatorFileParser;
|
||||
import com.opensymphony.xwork2.validator.ValidatorFactory;
|
||||
import com.opensymphony.xwork2.validator.ValidatorFileParser;
|
||||
import com.sun.org.apache.xpath.internal.operations.Bool;
|
||||
import ognl.MethodAccessor;
|
||||
import ognl.PropertyAccessor;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
@@ -227,6 +228,7 @@ public class XWorkConfigurationProvider implements ConfigurationProvider {
|
||||
props.setProperty(XWorkConstants.ENABLE_OGNL_EVAL_EXPRESSION, Boolean.FALSE.toString());
|
||||
props.setProperty(XWorkConstants.RELOAD_XML_CONFIGURATION, Boolean.FALSE.toString());
|
||||
props.setProperty(StrutsConstants.STRUTS_ALLOW_STATIC_METHOD_ACCESS, Boolean.FALSE.toString());
|
||||
props.setProperty(StrutsConstants.STRUTS_MATCHER_APPEND_NAMED_PARAMETERS, Boolean.TRUE.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,13 +25,16 @@ import com.opensymphony.xwork2.XWorkConstants;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.security.AcceptedPatternsChecker;
|
||||
import com.opensymphony.xwork2.security.ExcludedPatternsChecker;
|
||||
import com.opensymphony.xwork2.util.*;
|
||||
import com.opensymphony.xwork2.util.ClearableValueStack;
|
||||
import com.opensymphony.xwork2.util.MemberAccessValueStack;
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import com.opensymphony.xwork2.util.ValueStackFactory;
|
||||
import com.opensymphony.xwork2.util.reflection.ReflectionContextState;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.dispatcher.Parameter;
|
||||
import org.apache.struts2.dispatcher.HttpParameters;
|
||||
import org.apache.struts2.dispatcher.Parameter;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
@@ -100,8 +103,8 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
|
||||
*/
|
||||
static final Comparator<String> rbCollator = new Comparator<String>() {
|
||||
public int compare(String s1, String s2) {
|
||||
int l1 = countOGNLCharacters(s1),
|
||||
l2 = countOGNLCharacters(s2);
|
||||
int l1 = countOGNLCharacters(s1);
|
||||
int l2 = countOGNLCharacters(s2);
|
||||
return l1 < l2 ? -1 : (l2 < l1 ? 1 : s1.compareTo(s2));
|
||||
}
|
||||
|
||||
@@ -185,7 +188,7 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
|
||||
if (clearableStack) {
|
||||
//if the stack's context can be cleared, do that to prevent OGNL
|
||||
//from having access to objects in the stack, see XW-641
|
||||
((ClearableValueStack)newStack).clearContextValues();
|
||||
((ClearableValueStack) newStack).clearContextValues();
|
||||
Map<String, Object> context = newStack.getContext();
|
||||
ReflectionContextState.setCreatingNullObjects(context, true);
|
||||
ReflectionContextState.setDenyMethodExecution(context, true);
|
||||
@@ -228,7 +231,7 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
|
||||
TextProvider tp = (TextProvider) action;
|
||||
developerNotification = tp.getText("devmode.notification",
|
||||
"Developer Notification:\n{0}",
|
||||
new String[]{ developerNotification }
|
||||
new String[]{developerNotification}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -245,7 +248,7 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
|
||||
/**
|
||||
* Checks if name of parameter can be accepted or thrown away
|
||||
*
|
||||
* @param name parameter name
|
||||
* @param name parameter name
|
||||
* @param action current action
|
||||
* @return true if parameter is accepted
|
||||
*/
|
||||
@@ -289,27 +292,45 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
|
||||
return accepted;
|
||||
}
|
||||
|
||||
protected boolean isWithinLengthLimit( String name ) {
|
||||
protected boolean isWithinLengthLimit(String name) {
|
||||
boolean matchLength = name.length() <= paramNameMaxLength;
|
||||
if (!matchLength) {
|
||||
LOG.debug("Parameter [{}] is too long, allowed length is [{}]", name, String.valueOf(paramNameMaxLength));
|
||||
if (devMode) { // warn only when in devMode
|
||||
LOG.warn("Parameter [{}] is too long, allowed length is [{}]. Use Interceptor Parameter Overriding " +
|
||||
"to override the limit, see more at\n" +
|
||||
"https://struts.apache.org/core-developers/interceptors.html#interceptor-parameter-overriding",
|
||||
name, paramNameMaxLength);
|
||||
} else {
|
||||
LOG.warn("Parameter [{}] is too long, allowed length is [{}]", name, paramNameMaxLength);
|
||||
}
|
||||
}
|
||||
return matchLength;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isAccepted(String paramName) {
|
||||
AcceptedPatternsChecker.IsAccepted result = acceptedPatterns.isAccepted(paramName);
|
||||
if (result.isAccepted()) {
|
||||
return true;
|
||||
} else if (devMode) { // warn only when in devMode
|
||||
LOG.warn("Parameter [{}] didn't match accepted pattern [{}]! See Accepted / Excluded patterns at\n" +
|
||||
"https://struts.apache.org/security/#accepted--excluded-patterns",
|
||||
paramName, result.getAcceptedPattern());
|
||||
} else {
|
||||
LOG.debug("Parameter [{}] didn't match accepted pattern [{}]!", paramName, result.getAcceptedPattern());
|
||||
}
|
||||
LOG.debug("Parameter [{}] didn't match accepted pattern [{}]!", paramName, result.getAcceptedPattern());
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean isExcluded(String paramName) {
|
||||
ExcludedPatternsChecker.IsExcluded result = excludedPatterns.isExcluded(paramName);
|
||||
if (result.isExcluded()) {
|
||||
LOG.debug("Parameter [{}] matches excluded pattern [{}]!", paramName, result.getExcludedPattern());
|
||||
if (devMode) { // warn only when in devMode
|
||||
LOG.warn("Parameter [{}] matches excluded pattern [{}]! See Accepted / Excluded patterns at\n" +
|
||||
"https://struts.apache.org/security/#accepted--excluded-patterns",
|
||||
paramName, result.getExcludedPattern());
|
||||
} else {
|
||||
LOG.debug("Parameter [{}] matches excluded pattern [{}]!", paramName, result.getExcludedPattern());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -341,4 +341,7 @@ public final class StrutsConstants {
|
||||
public static final String STRUTS_DISALLOW_PROXY_MEMBER_ACCESS = "struts.disallowProxyMemberAccess";
|
||||
|
||||
public static final String STRUTS_OGNL_AUTO_GROWTH_COLLECTION_LIMIT = "struts.ognl.autoGrowthCollectionLimit";
|
||||
|
||||
/** See {@link com.opensymphony.xwork2.config.impl.AbstractMatcher#appendNamedParameters */
|
||||
public static final String STRUTS_MATCHER_APPEND_NAMED_PARAMETERS = "struts.matcher.appendNamedParameters";
|
||||
}
|
||||
|
||||
@@ -696,12 +696,23 @@ public class Dispatcher {
|
||||
try {
|
||||
locale = LocaleUtils.toLocale(defaultLocale);
|
||||
} catch (IllegalArgumentException e) {
|
||||
LOG.warn(new ParameterizedMessage("Cannot convert 'struts.locale' = [{}] to proper locale, defaulting to request locale [{}]",
|
||||
defaultLocale, request.getLocale()), e);
|
||||
locale = request.getLocale();
|
||||
try {
|
||||
locale = request.getLocale();
|
||||
LOG.warn(new ParameterizedMessage("Cannot convert 'struts.locale' = [{}] to proper locale, defaulting to request locale [{}]",
|
||||
defaultLocale, locale), e);
|
||||
} catch (RuntimeException rex) {
|
||||
LOG.warn(new ParameterizedMessage("Cannot convert 'struts.locale' = [{}] to proper locale, and cannot get locale from HTTP Request, falling back to system default locale",
|
||||
defaultLocale), rex);
|
||||
locale = Locale.getDefault();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
locale = request.getLocale();
|
||||
try {
|
||||
locale = request.getLocale();
|
||||
} catch (RuntimeException rex) {
|
||||
LOG.warn("Cannot get locale from HTTP Request, falling back to system default locale", rex);
|
||||
locale = Locale.getDefault();
|
||||
}
|
||||
}
|
||||
return locale;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.opensymphony.xwork2.config.entities.ExceptionMappingConfig;
|
||||
import com.opensymphony.xwork2.config.entities.InterceptorMapping;
|
||||
import com.opensymphony.xwork2.config.entities.ResultConfig;
|
||||
import com.opensymphony.xwork2.util.WildcardHelper;
|
||||
import org.apache.struts2.util.RegexPatternMatcher;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -142,6 +143,79 @@ public class ActionConfigMatcherTest extends XWorkTestCase {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to make sure the {@link AbstractMatcher#replaceParameters(Map, Map)} method isn't adding values to the
|
||||
* return value.
|
||||
*/
|
||||
public void testReplaceParametersWithNoAppendingParams() {
|
||||
Map<String, ActionConfig> map = new HashMap<>();
|
||||
|
||||
HashMap<String, String> params = new HashMap<>();
|
||||
params.put("first", "{1}");
|
||||
|
||||
ActionConfig config = new ActionConfig.Builder("package", "foo/{one}/{two}/{three}", "foo.bar.Action")
|
||||
.addParams(params)
|
||||
.addExceptionMapping(new ExceptionMappingConfig.Builder("foo{1}", "java.lang.{2}Exception", "success{1}")
|
||||
.addParams(new HashMap<>(params))
|
||||
.build())
|
||||
.addResultConfig(new ResultConfig.Builder("success{1}", "foo.{2}").addParams(params).build())
|
||||
.setStrictMethodInvocation(false)
|
||||
.build();
|
||||
map.put("foo/{one}/{two}/{three}", config);
|
||||
ActionConfigMatcher replaceMatcher = new ActionConfigMatcher(new RegexPatternMatcher(), map, false, false);
|
||||
ActionConfig matched = replaceMatcher.match("foo/paramOne/paramTwo/paramThree");
|
||||
assertNotNull("ActionConfig should be matched", matched);
|
||||
|
||||
// Verify all The ActionConfig, ExceptionConfig, and ResultConfig have the correct number of params
|
||||
assertEquals("The ActionConfig should have the correct number of params", 1, matched.getParams().size());
|
||||
assertEquals("The ExceptionMappingConfigs should have the correct number of params", 1, matched.getExceptionMappings().get(0).getParams().size());
|
||||
assertEquals("The ResultConfigs should have the correct number of params", 1, matched.getResults().get("successparamOne").getParams().size());
|
||||
|
||||
// Verify the params are still getting their values replaced correctly
|
||||
assertEquals("The ActionConfig params have replaced values", "paramOne", matched.getParams().get("first"));
|
||||
assertEquals("The ActionConfig params have replaced values", "paramOne", matched.getExceptionMappings().get(0).getParams().get("first"));
|
||||
assertEquals("The ActionConfig params have replaced values", "paramOne", matched.getResults().get("successparamOne").getParams().get("first"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to make sure the {@link AbstractMatcher#replaceParameters(Map, Map)} method is adding values to the
|
||||
* return value.
|
||||
*/
|
||||
public void testReplaceParametersWithAppendingParams() {
|
||||
Map<String, ActionConfig> map = new HashMap<>();
|
||||
|
||||
HashMap<String, String> params = new HashMap<>();
|
||||
params.put("first", "{1}");
|
||||
|
||||
ActionConfig config = new ActionConfig.Builder("package", "foo/{one}/{two}/{three}", "foo.bar.Action")
|
||||
.addParams(params)
|
||||
.addExceptionMapping(new ExceptionMappingConfig.Builder("foo{1}", "java.lang.{2}Exception", "success{1}")
|
||||
.addParams(new HashMap<>(params))
|
||||
.build())
|
||||
.addResultConfig(new ResultConfig.Builder("success{1}", "foo.{2}").addParams(params).build())
|
||||
.setStrictMethodInvocation(false)
|
||||
.build();
|
||||
map.put("foo/{one}/{two}/{three}", config);
|
||||
ActionConfigMatcher replaceMatcher = new ActionConfigMatcher(new RegexPatternMatcher(), map, false, true);
|
||||
ActionConfig matched = replaceMatcher.match("foo/paramOne/paramTwo/paramThree");
|
||||
assertNotNull("ActionConfig should be matched", matched);
|
||||
|
||||
assertEquals(4, matched.getParams().size());
|
||||
assertEquals(4, matched.getExceptionMappings().get(0).getParams().size());
|
||||
assertEquals(4, matched.getResults().get("successparamOne").getParams().size());
|
||||
|
||||
// Verify the params are still getting their values replaced correctly
|
||||
assertEquals("paramOne", matched.getParams().get("first"));
|
||||
assertEquals("paramOne", matched.getParams().get("one"));
|
||||
assertEquals("paramTwo", matched.getParams().get("two"));
|
||||
assertEquals("paramThree", matched.getParams().get("three"));
|
||||
assertEquals("paramOne", matched.getExceptionMappings().get(0).getParams().get("first"));
|
||||
assertEquals("paramOne", matched.getExceptionMappings().get(0).getParams().get("one"));
|
||||
assertEquals("paramTwo", matched.getExceptionMappings().get(0).getParams().get("two"));
|
||||
assertEquals("paramThree", matched.getExceptionMappings().get(0).getParams().get("three"));
|
||||
assertEquals("paramOne", matched.getResults().get("successparamOne").getParams().get("first"));
|
||||
}
|
||||
|
||||
private Map<String,ActionConfig> buildActionConfigMap() {
|
||||
Map<String, ActionConfig> map = new HashMap<>();
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ public class DateRangeValidatorTest extends XWorkTestCase {
|
||||
HashMap<String, Object> params = new HashMap<>();
|
||||
params.put("date", date.getTime());
|
||||
context.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
|
||||
context.put(ActionContext.LOCALE, Locale.US); // Force US Locale for date conversion tests on JDK9+
|
||||
|
||||
ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.VALIDATION_ACTION_NAME, null, context);
|
||||
proxy.execute();
|
||||
|
||||
@@ -38,6 +38,7 @@ public class VisitorFieldValidatorTest extends XWorkTestCase {
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
ActionContext.getContext().put(ActionContext.LOCALE, Locale.US); // Force US Locale for date conversion tests on JDK9+
|
||||
action = container.inject(VisitorValidatorTestAction.class);
|
||||
|
||||
TestBean bean = action.getBean();
|
||||
|
||||
@@ -20,6 +20,7 @@ package org.apache.struts2.dispatcher;
|
||||
|
||||
import com.mockobjects.dynamic.C;
|
||||
import com.mockobjects.dynamic.Mock;
|
||||
import com.opensymphony.xwork2.ActionContext;
|
||||
import com.opensymphony.xwork2.ObjectFactory;
|
||||
import com.opensymphony.xwork2.XWorkConstants;
|
||||
import com.opensymphony.xwork2.config.Configuration;
|
||||
@@ -36,6 +37,7 @@ import org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper;
|
||||
import org.apache.struts2.util.ObjectFactoryDestroyable;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.mock.web.MockHttpSession;
|
||||
import org.springframework.mock.web.MockServletContext;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@@ -374,6 +376,207 @@ public class DispatcherTest extends StrutsInternalTestCase {
|
||||
assertTrue("Modified Dispatcher devMode state not true ?", du2.isDevMode());
|
||||
}
|
||||
|
||||
public void testGetLocale_With_DefaultLocale_FromConfiguration() throws Exception {
|
||||
// Given
|
||||
Mock mock = new Mock(HttpServletRequest.class);
|
||||
MockHttpSession mockHttpSession = new MockHttpSession();
|
||||
mock.expectAndReturn("getCharacterEncoding", "utf-8"); // From Dispatcher prepare().
|
||||
mock.expectAndReturn("getHeader", "X-Requested-With", ""); // From Dispatcher prepare().
|
||||
mock.expectAndReturn("getParameterMap", new HashMap<String, Object>()); // From Dispatcher prepare().
|
||||
mock.expectAndReturn("getSession", false, mockHttpSession); // From Dispatcher prepare().
|
||||
mock.expectAndReturn("getSession", true, mockHttpSession); // From createTestContextMap().
|
||||
HttpServletRequest request = (HttpServletRequest) mock.proxy();
|
||||
HttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
Dispatcher testDispatcher = initDispatcher(new HashMap<String, String>() {{
|
||||
put(StrutsConstants.STRUTS_I18N_ENCODING, "utf-8");
|
||||
// Not setting a Struts Locale here, so we should receive the default "de_DE" from the test configuration.
|
||||
}});
|
||||
|
||||
// When
|
||||
testDispatcher.prepare(request, response);
|
||||
Map<String, Object> contextMap = createTestContextMap(testDispatcher, request, response);
|
||||
|
||||
// Then
|
||||
assertEquals(Locale.GERMANY, contextMap.get(ActionContext.LOCALE)); // Expect the Dispatcher defaultLocale value "de_DE" from the test configuration.
|
||||
mock.verify();
|
||||
}
|
||||
|
||||
public void testGetLocale_With_DefaultLocale_fr_CA() throws Exception {
|
||||
// Given
|
||||
Mock mock = new Mock(HttpServletRequest.class);
|
||||
MockHttpSession mockHttpSession = new MockHttpSession();
|
||||
mock.expectAndReturn("getCharacterEncoding", "utf-8"); // From Dispatcher prepare().
|
||||
mock.expectAndReturn("getHeader", "X-Requested-With", ""); // From Dispatcher prepare().
|
||||
mock.expectAndReturn("getParameterMap", new HashMap<String, Object>()); // From Dispatcher prepare().
|
||||
mock.expectAndReturn("getSession", false, mockHttpSession); // From Dispatcher prepare().
|
||||
mock.expectAndReturn("getSession", true, mockHttpSession); // From createTestContextMap().
|
||||
HttpServletRequest request = (HttpServletRequest) mock.proxy();
|
||||
HttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
Dispatcher testDispatcher = initDispatcher(new HashMap<String, String>() {{
|
||||
put(StrutsConstants.STRUTS_I18N_ENCODING, "utf-8");
|
||||
put(StrutsConstants.STRUTS_LOCALE, Locale.CANADA_FRENCH.toString()); // Set the Dispatcher defaultLocale to fr_CA.
|
||||
}});
|
||||
|
||||
// When
|
||||
testDispatcher.prepare(request, response);
|
||||
Map<String, Object> contextMap = createTestContextMap(testDispatcher, request, response);
|
||||
|
||||
// Then
|
||||
assertEquals(Locale.CANADA_FRENCH, contextMap.get(ActionContext.LOCALE)); // Expect the Dispatcher defaultLocale value.
|
||||
mock.verify();
|
||||
}
|
||||
|
||||
public void testGetLocale_With_BadDefaultLocale_RequestLocale_en_UK() throws Exception {
|
||||
// Given
|
||||
Mock mock = new Mock(HttpServletRequest.class);
|
||||
MockHttpSession mockHttpSession = new MockHttpSession();
|
||||
mock.expectAndReturn("getCharacterEncoding", "utf-8"); // From Dispatcher prepare().
|
||||
mock.expectAndReturn("getHeader", "X-Requested-With", ""); // From Dispatcher prepare().
|
||||
mock.expectAndReturn("getLocale", Locale.UK); // From Dispatcher prepare().
|
||||
mock.expectAndReturn("getParameterMap", new HashMap<String, Object>()); // From Dispatcher prepare().
|
||||
mock.expectAndReturn("getSession", false, mockHttpSession); // From Dispatcher prepare().
|
||||
mock.expectAndReturn("getSession", true, mockHttpSession); // From createTestContextMap().
|
||||
mock.expectAndReturn("getLocale", Locale.UK); // From createTestContextMap().
|
||||
HttpServletRequest request = (HttpServletRequest) mock.proxy();
|
||||
HttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
Dispatcher testDispatcher = initDispatcher(new HashMap<String, String>() {{
|
||||
put(StrutsConstants.STRUTS_I18N_ENCODING, "utf-8");
|
||||
put(StrutsConstants.STRUTS_LOCALE, "This_is_not_a_valid_Locale_string"); // Set Dispatcher defaultLocale to an invalid value.
|
||||
}});
|
||||
|
||||
// When
|
||||
testDispatcher.prepare(request, response);
|
||||
Map<String, Object> contextMap = createTestContextMap(testDispatcher, request, response);
|
||||
|
||||
// Then
|
||||
assertEquals(Locale.UK, contextMap.get(ActionContext.LOCALE)); // Expect the request set value from Mock.
|
||||
mock.verify();
|
||||
}
|
||||
|
||||
public void testGetLocale_With_BadDefaultLocale_And_RuntimeException() throws Exception {
|
||||
// Given
|
||||
Mock mock = new Mock(HttpServletRequest.class);
|
||||
MockHttpSession mockHttpSession = new MockHttpSession();
|
||||
mock.expectAndReturn("getCharacterEncoding", "utf-8"); // From Dispatcher prepare().
|
||||
mock.expectAndReturn("getHeader", "X-Requested-With", ""); // From Dispatcher prepare().
|
||||
mock.expectAndReturn("getLocale", Locale.UK); // From Dispatcher prepare().
|
||||
mock.expectAndReturn("getParameterMap", new HashMap<String, Object>()); // From Dispatcher prepare().
|
||||
mock.expectAndReturn("getSession", false, mockHttpSession); // From Dispatcher prepare().
|
||||
mock.expectAndReturn("getSession", true, mockHttpSession); // From createTestContextMap().
|
||||
mock.expectAndThrow("getLocale", new IllegalStateException("Test theoretical state preventing HTTP Request Locale access")); // From createTestContextMap().
|
||||
HttpServletRequest request = (HttpServletRequest) mock.proxy();
|
||||
HttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
Dispatcher testDispatcher = initDispatcher(new HashMap<String, String>() {{
|
||||
put(StrutsConstants.STRUTS_I18N_ENCODING, "utf-8");
|
||||
put(StrutsConstants.STRUTS_LOCALE, "This_is_not_a_valid_Locale_string"); // Set the Dispatcher defaultLocale to an invalid value.
|
||||
}});
|
||||
|
||||
// When
|
||||
testDispatcher.prepare(request, response);
|
||||
Map<String, Object> contextMap = createTestContextMap(testDispatcher, request, response);
|
||||
|
||||
// Then
|
||||
assertEquals(Locale.getDefault(), contextMap.get(ActionContext.LOCALE)); // Expect the system default value, when BOTH Dispatcher default Locale AND request access fail.
|
||||
mock.verify();
|
||||
}
|
||||
|
||||
public void testGetLocale_With_NullDefaultLocale() throws Exception {
|
||||
// Given
|
||||
Mock mock = new Mock(HttpServletRequest.class);
|
||||
MockHttpSession mockHttpSession = new MockHttpSession();
|
||||
mock.expectAndReturn("getCharacterEncoding", "utf-8"); // From Dispatcher prepare().
|
||||
mock.expectAndReturn("getHeader", "X-Requested-With", ""); // From Dispatcher prepare().
|
||||
mock.expectAndReturn("getLocale", Locale.CANADA_FRENCH); // From Dispatcher prepare().
|
||||
mock.expectAndReturn("getParameterMap", new HashMap<String, Object>()); // From Dispatcher prepare().
|
||||
mock.expectAndReturn("getSession", false, mockHttpSession); // From Dispatcher prepare().
|
||||
mock.expectAndReturn("getSession", true, mockHttpSession); // From createTestContextMap().
|
||||
mock.expectAndReturn("getLocale", Locale.CANADA_FRENCH); // From createTestContextMap().
|
||||
HttpServletRequest request = (HttpServletRequest) mock.proxy();
|
||||
HttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
Dispatcher testDispatcher = initDispatcher(new HashMap<String, String>() {{
|
||||
put(StrutsConstants.STRUTS_I18N_ENCODING, "utf-8");
|
||||
// Attempting to set StrutsConstants.STRUTS_LOCALE to null here via parameters causes an NPE.
|
||||
}});
|
||||
|
||||
testDispatcher.setDefaultLocale(null); // Force a null Struts default locale, otherwise we receive the default "de_DE" from the test configuration.
|
||||
|
||||
// When
|
||||
testDispatcher.prepare(request, response);
|
||||
Map<String, Object> contextMap = createTestContextMap(testDispatcher, request, response);
|
||||
|
||||
// Then
|
||||
assertEquals(Locale.CANADA_FRENCH, contextMap.get(ActionContext.LOCALE)); // Expect the request set value from Mock.
|
||||
mock.verify();
|
||||
}
|
||||
|
||||
public void testGetLocale_With_NullDefaultLocale_And_RuntimeException() throws Exception {
|
||||
// Given
|
||||
Mock mock = new Mock(HttpServletRequest.class);
|
||||
MockHttpSession mockHttpSession = new MockHttpSession();
|
||||
mock.expectAndReturn("getCharacterEncoding", "utf-8"); // From Dispatcher prepare().
|
||||
mock.expectAndReturn("getHeader", "X-Requested-With", ""); // From Dispatcher prepare().
|
||||
mock.expectAndReturn("getLocale", Locale.CANADA_FRENCH); // From Dispatcher prepare().
|
||||
mock.expectAndReturn("getParameterMap", new HashMap<String, Object>()); // From Dispatcher prepare().
|
||||
mock.expectAndReturn("getSession", false, mockHttpSession); // From Dispatcher prepare().
|
||||
mock.expectAndReturn("getSession", true, mockHttpSession); // From createTestContextMap().
|
||||
mock.expectAndThrow("getLocale", new IllegalStateException("Test some theoretical state preventing HTTP Request Locale access")); // From createTestContextMap().
|
||||
HttpServletRequest request = (HttpServletRequest) mock.proxy();
|
||||
HttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
Dispatcher testDispatcher = initDispatcher(new HashMap<String, String>() {{
|
||||
put(StrutsConstants.STRUTS_I18N_ENCODING, "utf-8");
|
||||
// Attempting to set StrutsConstants.STRUTS_LOCALE to null via parameters causes an NPE.
|
||||
}});
|
||||
|
||||
testDispatcher.setDefaultLocale(null); // Force a null Struts default locale, otherwise we receive the default "de_DE" from the test configuration.
|
||||
|
||||
// When
|
||||
testDispatcher.prepare(request, response);
|
||||
Map<String, Object> contextMap = createTestContextMap(testDispatcher, request, response);
|
||||
|
||||
// Then
|
||||
assertEquals(Locale.getDefault(), contextMap.get(ActionContext.LOCALE)); // Expect the system default value when Mock request access fails.
|
||||
mock.verify();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test context Map from a Dispatcher instance.
|
||||
*
|
||||
* The method directly calls getParameterMap() and getSession(true) on the HttpServletRequest.
|
||||
*
|
||||
* The method indirectly calls getLocale(request) on the Dispatcher instance, allowing a test of that code path.
|
||||
* The derived Struts Dispatcher Locale can be retrieved from the Map afterwards.
|
||||
*
|
||||
* @param dispatcher
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
protected static Map<String, Object> createTestContextMap(Dispatcher dispatcher,
|
||||
HttpServletRequest request, HttpServletResponse response) {
|
||||
if (dispatcher == null) {
|
||||
throw new IllegalArgumentException("Cannot create a test ContextMap from a null Dispatcher");
|
||||
}
|
||||
if (request == null) {
|
||||
throw new IllegalArgumentException("Cannot create a test ContextMap from a null HttpServletRequest");
|
||||
}
|
||||
if (response == null) {
|
||||
throw new IllegalArgumentException("Cannot create a test ContextMap from a null HttpServletResponse");
|
||||
}
|
||||
|
||||
return dispatcher.createContextMap(new RequestMap(request),
|
||||
HttpParameters.create(request.getParameterMap()).build(),
|
||||
new SessionMap(request),
|
||||
new ApplicationMap(request.getSession(true).getServletContext()),
|
||||
request,
|
||||
response);
|
||||
}
|
||||
|
||||
class InternalConfigurationManager extends ConfigurationManager {
|
||||
public boolean destroyConfiguration = false;
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -244,7 +245,7 @@ public class FileUploadInterceptorTest extends StrutsInternalTestCase {
|
||||
public void testNoContentMultipartRequest() throws Exception {
|
||||
MockHttpServletRequest req = new MockHttpServletRequest();
|
||||
|
||||
req.setCharacterEncoding("text/html");
|
||||
req.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
||||
req.setMethod("post");
|
||||
req.addHeader("Content-type", "multipart/form-data");
|
||||
req.setContent(null); // there is no content
|
||||
@@ -265,7 +266,7 @@ public class FileUploadInterceptorTest extends StrutsInternalTestCase {
|
||||
|
||||
public void testSuccessUploadOfATextFileMultipartRequest() throws Exception {
|
||||
MockHttpServletRequest req = new MockHttpServletRequest();
|
||||
req.setCharacterEncoding("text/html");
|
||||
req.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
||||
req.setMethod("post");
|
||||
req.addHeader("Content-type", "multipart/form-data; boundary=---1234");
|
||||
|
||||
@@ -322,7 +323,7 @@ public class FileUploadInterceptorTest extends StrutsInternalTestCase {
|
||||
final String endline = "\r\n";
|
||||
|
||||
MockHttpServletRequest req = new MockHttpServletRequest();
|
||||
req.setCharacterEncoding("text/html");
|
||||
req.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
||||
req.setMethod("POST");
|
||||
req.addHeader("Content-type", "multipart/form-data; boundary=" + bondary);
|
||||
StringBuilder content = new StringBuilder(128);
|
||||
@@ -371,7 +372,7 @@ public class FileUploadInterceptorTest extends StrutsInternalTestCase {
|
||||
|
||||
public void testMultipartRequestLocalizedError() throws Exception {
|
||||
MockHttpServletRequest req = new MockHttpServletRequest();
|
||||
req.setCharacterEncoding("text/html");
|
||||
req.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
||||
req.setMethod("post");
|
||||
req.addHeader("Content-type", "multipart/form-data; boundary=---1234");
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
<version>5.1.3.Final</version>
|
||||
<version>5.4.3.Final</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
+2
-2
@@ -25,7 +25,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-cdi-plugin</artifactId>
|
||||
@@ -47,7 +47,7 @@
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jboss.weld</groupId>
|
||||
<groupId>org.jboss.weld.se</groupId>
|
||||
<artifactId>weld-se</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-config-browser-plugin</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-convention-plugin</artifactId>
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-dwr-plugin</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-embeddedjsp-plugin</artifactId>
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-gxp-plugin</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-jasperreports-plugin</artifactId>
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-javatemplates-plugin</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-jfreechart-plugin</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-json-plugin</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-junit-plugin</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-osgi-plugin</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-oval-plugin</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-pell-multipart-plugin</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-plexus-plugin</artifactId>
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-portlet-tiles-plugin</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-portlet-plugin</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-rest-plugin</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-sitegraph-plugin</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-sitemesh-plugin</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-spring-plugin</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-testng-plugin</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-plugins</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>struts2-tiles-plugin</artifactId>
|
||||
|
||||
@@ -24,12 +24,12 @@
|
||||
<parent>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts-master</artifactId>
|
||||
<version>13</version>
|
||||
<version>14</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>struts2-parent</artifactId>
|
||||
<version>2.5.22</version>
|
||||
<version>2.5.23</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>Struts 2</name>
|
||||
<url>http://struts.apache.org/</url>
|
||||
@@ -51,7 +51,7 @@
|
||||
<connection>scm:git:https://gitbox.apache.org/repos/asf/struts.git</connection>
|
||||
<developerConnection>scm:git:https://gitbox.apache.org/repos/asf/struts.git</developerConnection>
|
||||
<url>https://github.com/apache/struts/</url>
|
||||
<tag>STRUTS_2_5_22</tag>
|
||||
<tag>STRUTS_2_5_23</tag>
|
||||
</scm>
|
||||
|
||||
<issueManagement>
|
||||
@@ -96,20 +96,20 @@
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<ognl.version>3.1.26</ognl.version>
|
||||
<spring.platformVersion>4.3.25.RELEASE</spring.platformVersion>
|
||||
<asm.version>7.1</asm.version>
|
||||
<ognl.version>3.1.28</ognl.version>
|
||||
<spring.platformVersion>4.3.26.RELEASE</spring.platformVersion>
|
||||
<asm.version>7.3.1</asm.version>
|
||||
<tiles.version>3.0.8</tiles.version>
|
||||
<tiles-request.version>1.0.7</tiles-request.version>
|
||||
<log4j2.version>2.12.1</log4j2.version>
|
||||
<jackson.version>2.10.0</jackson.version>
|
||||
<jackson.version>2.10.3</jackson.version>
|
||||
|
||||
<!-- Site generation -->
|
||||
<fluido-skin.version>1.8</fluido-skin.version>
|
||||
|
||||
<!-- Sonar -->
|
||||
<sonar.host.url>https://builds.apache.org/analysis/</sonar.host.url>
|
||||
<maven-surefire-plugin.version>2.22.1</maven-surefire-plugin.version>
|
||||
<maven-surefire-plugin.version>3.0.0-M4</maven-surefire-plugin.version>
|
||||
</properties>
|
||||
|
||||
<profiles>
|
||||
@@ -217,7 +217,7 @@
|
||||
<plugin>
|
||||
<groupId>com.updateimpact</groupId>
|
||||
<artifactId>updateimpact-maven-plugin</artifactId>
|
||||
<version>1.0.10</version>
|
||||
<version>1.0.12</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
@@ -230,7 +230,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-project-info-reports-plugin</artifactId>
|
||||
<version>2.7</version>
|
||||
<version>3.0.0</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
@@ -262,17 +262,19 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<version>2.1</version>
|
||||
<version>3.2.3</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<version>2.1.0</version>
|
||||
<!-- Warning: Version 2.2.0+ often produces "java.lang.OutOfMemoryError: PermGen space" failure with JDK7 and default
|
||||
heap settings. The "Final Memory:" total memory from a build with 2.2.0+ is 3x or more than that of 2.1.0. -->
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<version>2.10</version>
|
||||
<version>3.1.2</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
@@ -327,7 +329,7 @@
|
||||
<plugin>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-maven</artifactId>
|
||||
<version>3.3.4</version>
|
||||
<version>5.3.2</version>
|
||||
<configuration>
|
||||
<suppressionFiles>
|
||||
<suppressionFile>src/etc/project-suppression.xml</suppressionFile>
|
||||
@@ -381,6 +383,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-site-plugin</artifactId>
|
||||
<version>3.9.0</version>
|
||||
<configuration>
|
||||
<relativizeDecorationLinks>false</relativizeDecorationLinks>
|
||||
</configuration>
|
||||
@@ -388,12 +391,12 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.maven.doxia</groupId>
|
||||
<artifactId>doxia-core</artifactId>
|
||||
<version>1.8</version>
|
||||
<version>1.9.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven.doxia</groupId>
|
||||
<artifactId>doxia-module-markdown</artifactId>
|
||||
<version>1.7</version>
|
||||
<version>1.9.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
@@ -622,13 +625,13 @@
|
||||
<dependency>
|
||||
<groupId>org.freemarker</groupId>
|
||||
<artifactId>freemarker</artifactId>
|
||||
<version>2.3.28</version>
|
||||
<version>2.3.30</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>org.apache.felix.main</artifactId>
|
||||
<version>4.6.1</version>
|
||||
<version>6.0.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
@@ -1000,12 +1003,12 @@
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.28</version>
|
||||
<version>1.7.30</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>1.7.28</version>
|
||||
<version>1.7.30</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -1099,19 +1102,19 @@
|
||||
<dependency>
|
||||
<groupId>javax.enterprise</groupId>
|
||||
<artifactId>cdi-api</artifactId>
|
||||
<version>1.0-SP4</version>
|
||||
<version>1.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jboss.weld</groupId>
|
||||
<artifactId>weld-core</artifactId>
|
||||
<version>1.0.1-SP4</version>
|
||||
<version>2.2.16.SP1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jboss.weld</groupId>
|
||||
<groupId>org.jboss.weld.se</groupId>
|
||||
<artifactId>weld-se</artifactId>
|
||||
<version>1.0.1-Final</version>
|
||||
<version>2.2.16.SP1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
Reference in New Issue
Block a user