mirror of
https://github.com/apache/struts.git
synced 2026-08-07 23:57:03 +00:00
Backport applicable OgnlValueStackTest test fix and unit test additions from 2.6:
- This backport resulted from a review inspired/suggested by Y. Zamani in discussions for PR#334. - Backports fix of error in testNullMethod(). - Backports applicable static access tests (static method access only), cleanup of unused imports. - As with 2.6, it uses Y. Zamani's improved/enhanced reload mechanism.
This commit is contained in:
@@ -19,15 +19,16 @@
|
||||
package com.opensymphony.xwork2.ognl;
|
||||
|
||||
import com.opensymphony.xwork2.*;
|
||||
import com.opensymphony.xwork2.config.ConfigurationManager;
|
||||
import com.opensymphony.xwork2.config.ConfigurationProvider;
|
||||
import com.opensymphony.xwork2.config.providers.XmlConfigurationProvider;
|
||||
import com.opensymphony.xwork2.config.ConfigurationException;
|
||||
import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
|
||||
import com.opensymphony.xwork2.inject.Container;
|
||||
import com.opensymphony.xwork2.inject.ContainerBuilder;
|
||||
import com.opensymphony.xwork2.ognl.accessor.CompoundRootAccessor;
|
||||
import com.opensymphony.xwork2.test.StubConfigurationProvider;
|
||||
import com.opensymphony.xwork2.test.TestBean2;
|
||||
import com.opensymphony.xwork2.util.*;
|
||||
import com.opensymphony.xwork2.util.Foo;
|
||||
import com.opensymphony.xwork2.util.location.LocatableProperties;
|
||||
import com.opensymphony.xwork2.util.reflection.ReflectionContextState;
|
||||
import ognl.PropertyAccessor;
|
||||
|
||||
@@ -36,6 +37,7 @@ import java.math.BigDecimal;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
|
||||
|
||||
/**
|
||||
@@ -43,10 +45,25 @@ import java.util.Map;
|
||||
*/
|
||||
public class OgnlValueStackTest extends XWorkTestCase {
|
||||
|
||||
// Fields for static field access test
|
||||
public static final String STATIC_FINAL_PUBLIC_ATTRIBUTE = "Static_Final_Public_Attribute";
|
||||
static final String STATIC_FINAL_PACKAGE_ATTRIBUTE = "Static_Final_Package_Attribute";
|
||||
protected static final String STATIC_FINAL_PROTECTED_ATTRIBUTE = "Static_Final_Protected_Attribute";
|
||||
private static final String STATIC_FINAL_PRIVATE_ATTRIBUTE = "Static_Final_Private_Attribute";
|
||||
public static String STATIC_PUBLIC_ATTRIBUTE = "Static_Public_Attribute";
|
||||
static String STATIC_PACKAGE_ATTRIBUTE = "Static_Package_Attribute";
|
||||
protected static String STATIC_PROTECTED_ATTRIBUTE = "Static_Protected_Attribute";
|
||||
private static String STATIC_PRIVATE_ATTRIBUTE = "Static_Private_Attribute";
|
||||
|
||||
|
||||
public static Integer staticNullMethod() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Integer staticInteger100Method() {
|
||||
return 100;
|
||||
}
|
||||
|
||||
private OgnlUtil ognlUtil;
|
||||
|
||||
@Override
|
||||
@@ -69,6 +86,33 @@ public class OgnlValueStackTest extends XWorkTestCase {
|
||||
return stack;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return current OgnlValueStackFactory instance from current container
|
||||
*/
|
||||
private OgnlValueStackFactory getValueStackFactory() {
|
||||
return (OgnlValueStackFactory) container.getInstance(ValueStackFactory.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads container and gets a new OgnlValueStackFactory with specified new configuration.
|
||||
* Intended for testing OgnlValueStack instance(s) that are minimally configured.
|
||||
* This should help ensure no underlying configuration/injection side-effects are responsible
|
||||
* for the behaviour of fundamental access control flags).
|
||||
*
|
||||
* @param allowStaticMethod new allowStaticMethod configuration
|
||||
* @return a new OgnlValueStackFactory with specified new configuration
|
||||
*/
|
||||
private OgnlValueStackFactory reloadValueStackFactory(Boolean allowStaticMethod) {
|
||||
try {
|
||||
reloadTestContainerConfiguration(allowStaticMethod);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
fail("Unable to reload container configuration and configure ognlValueStackFactory - exception: " + ex);
|
||||
}
|
||||
|
||||
return getValueStackFactory();
|
||||
}
|
||||
|
||||
public void testExpOverridesCanStackExpUp() throws Exception {
|
||||
Map expr1 = new LinkedHashMap();
|
||||
expr1.put("expr1", "'expr1value'");
|
||||
@@ -580,7 +624,7 @@ public class OgnlValueStackTest extends XWorkTestCase {
|
||||
OgnlValueStack stack = createValueStack();
|
||||
stack.push(dog);
|
||||
assertNull(stack.findValue("nullMethod()"));
|
||||
assertNull(stack.findValue("@com.opensymphony.xwork2.util.OgnlValueStackTest@staticNullMethod()"));
|
||||
assertNull(stack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@staticNullMethod()"));
|
||||
}
|
||||
|
||||
public void testPetSoarBug() {
|
||||
@@ -972,6 +1016,173 @@ public class OgnlValueStackTest extends XWorkTestCase {
|
||||
assertEquals(null, stack.findValue("address.country.name", String.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test a default OgnlValueStackFactory and OgnlValueStack generated by it
|
||||
* when a default configuration is used.
|
||||
*/
|
||||
public void testOgnlValueStackFromOgnlValueStackFactoryDefaultConfig() {
|
||||
OgnlValueStackFactory ognlValueStackFactory = getValueStackFactory();
|
||||
OgnlValueStack ognlValueStack = (OgnlValueStack) ognlValueStackFactory.createValueStack();
|
||||
Object accessedValue;
|
||||
|
||||
// An OgnlValueStackFactory using a container config with default (from XWorkConfigurationProvider)
|
||||
// static method access flag value present should prevent staticMethodAccess but allow staticFieldAccess.
|
||||
assertFalse("OgnlValueStackFactory staticMethodAccess (default flag) not false?", containerAllowsStaticMethodAccess(ognlValueStackFactory.container));
|
||||
// An OgnlValueStack created from the above OgnlValueStackFactory should allow public field access,
|
||||
// but prevent non-public field access. It should also deny static method access.
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@staticInteger100Method()");
|
||||
assertNull("able to access static method (result not null) ?", accessedValue);
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_FINAL_PUBLIC_ATTRIBUTE");
|
||||
assertEquals("accessed static final public field value not equal to actual?", accessedValue, STATIC_FINAL_PUBLIC_ATTRIBUTE);
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_PUBLIC_ATTRIBUTE");
|
||||
assertEquals("accessed static public field value not equal to actual?", accessedValue, STATIC_PUBLIC_ATTRIBUTE);
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_FINAL_PACKAGE_ATTRIBUTE");
|
||||
assertNull("accessed final package field (result not null) ?", accessedValue);
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_PACKAGE_ATTRIBUTE");
|
||||
assertNull("accessed package field (result not null) ?", accessedValue);
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_FINAL_PROTECTED_ATTRIBUTE");
|
||||
assertNull("accessed final protected field (result not null) ?", accessedValue);
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_PROTECTED_ATTRIBUTE");
|
||||
assertNull("accessed protected field (result not null) ?", accessedValue);
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_FINAL_PRIVATE_ATTRIBUTE");
|
||||
assertNull("accessed final private field (result not null) ?", accessedValue);
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_PRIVATE_ATTRIBUTE");
|
||||
assertNull("accessed private field (result not null) ?", accessedValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test a raw OgnlValueStackFactory and OgnlValueStack generated by it
|
||||
* when no static method access flag is set (not present in configuration).
|
||||
*/
|
||||
public void testOgnlValueStackFromOgnlValueStackFactoryNoFlagsSet() {
|
||||
OgnlValueStackFactory ognlValueStackFactory = reloadValueStackFactory(null);
|
||||
OgnlValueStack ognlValueStack = (OgnlValueStack) ognlValueStackFactory.createValueStack();
|
||||
Object accessedValue;
|
||||
|
||||
// An OgnlValueStackFactory using a container config with no static method access flag value present
|
||||
// (such as from a DefaultConfiguration vs. XWorkConfigurationProvider) should
|
||||
// prevent staticMethodAccess and allow staticFieldAccess.
|
||||
// Note: Under normal circumstances, explicit static method access configuration flag should be present,
|
||||
// but this specific check verifies what happens if that configuration flags is not present.
|
||||
assertFalse("OgnlValueStackFactory staticMethodAccess (no flag present) not false?", containerAllowsStaticMethodAccess(ognlValueStackFactory.container));
|
||||
// An OgnlValueStack created from the above OgnlValueStackFactory should allow public field access,
|
||||
// and prevent non-public field access. It should also deny static method access.
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@staticInteger100Method()");
|
||||
assertNull("able to access static method (result not null) ?", accessedValue);
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_FINAL_PUBLIC_ATTRIBUTE");
|
||||
assertEquals("accessed static final public field value not equal to actual?", accessedValue, STATIC_FINAL_PUBLIC_ATTRIBUTE);
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_PUBLIC_ATTRIBUTE");
|
||||
assertEquals("accessed static public field value not equal to actual?", accessedValue, STATIC_PUBLIC_ATTRIBUTE);
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_FINAL_PACKAGE_ATTRIBUTE");
|
||||
assertNull("accessed final package field (result not null) ?", accessedValue);
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_PACKAGE_ATTRIBUTE");
|
||||
assertNull("accessed package field (result not null) ?", accessedValue);
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_FINAL_PROTECTED_ATTRIBUTE");
|
||||
assertNull("accessed final protected field (result not null) ?", accessedValue);
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_PROTECTED_ATTRIBUTE");
|
||||
assertNull("accessed protected field (result not null) ?", accessedValue);
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_FINAL_PRIVATE_ATTRIBUTE");
|
||||
assertNull("accessed final private field (result not null) ?", accessedValue);
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_PRIVATE_ATTRIBUTE");
|
||||
assertNull("accessed private field (result not null) ?", accessedValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test a raw OgnlValueStackFactory and OgnlValueStack generated by it
|
||||
* when static method access flag is set to false.
|
||||
*/
|
||||
public void testOgnlValueStackFromOgnlValueStackFactoryNoStaticMethodAccess() {
|
||||
OgnlValueStackFactory ognlValueStackFactory = reloadValueStackFactory(false);
|
||||
OgnlValueStack ognlValueStack = (OgnlValueStack) ognlValueStackFactory.createValueStack();
|
||||
Object accessedValue;
|
||||
|
||||
// An OgnlValueStackFactory using a container config with static method access flag set false should
|
||||
// prevent staticMethodAccess and allow staticFieldAccess.
|
||||
assertFalse("OgnlValueStackFactory staticMethodAccess (set false) not false?", containerAllowsStaticMethodAccess(ognlValueStackFactory.container));
|
||||
// An OgnlValueStack created from the above OgnlValueStackFactory should allow public field access,
|
||||
// and prevent non-public field access. It should also deny static method access.
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@staticInteger100Method()");
|
||||
assertNull("able to access static method (result not null) ?", accessedValue);
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_FINAL_PUBLIC_ATTRIBUTE");
|
||||
assertEquals("accessed static final public field value not equal to actual?", accessedValue, STATIC_FINAL_PUBLIC_ATTRIBUTE);
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_PUBLIC_ATTRIBUTE");
|
||||
assertEquals("accessed static public field value not equal to actual?", accessedValue, STATIC_PUBLIC_ATTRIBUTE);
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_FINAL_PACKAGE_ATTRIBUTE");
|
||||
assertNull("accessed final package field (result not null) ?", accessedValue);
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_PACKAGE_ATTRIBUTE");
|
||||
assertNull("accessed package field (result not null) ?", accessedValue);
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_FINAL_PROTECTED_ATTRIBUTE");
|
||||
assertNull("accessed final protected field (result not null) ?", accessedValue);
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_PROTECTED_ATTRIBUTE");
|
||||
assertNull("accessed protected field (result not null) ?", accessedValue);
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_FINAL_PRIVATE_ATTRIBUTE");
|
||||
assertNull("accessed final private field (result not null) ?", accessedValue);
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_PRIVATE_ATTRIBUTE");
|
||||
assertNull("accessed private field (result not null) ?", accessedValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test a raw OgnlValueStackFactory and OgnlValueStack generated by it
|
||||
* when static method access flag set to true.
|
||||
*/
|
||||
public void testOgnlValueStackFromOgnlValueStackFactoryStaticMethodAccess() {
|
||||
OgnlValueStackFactory ognlValueStackFactory = reloadValueStackFactory(true);
|
||||
OgnlValueStack ognlValueStack = (OgnlValueStack) ognlValueStackFactory.createValueStack();
|
||||
Object accessedValue;
|
||||
|
||||
// An OgnlValueStackFactory using a container config with static method access flag set true should
|
||||
// allow both staticMethodAccess and staticFieldAccess.
|
||||
assertTrue("OgnlValueStackFactory staticMethodAccess (set true) not true?", containerAllowsStaticMethodAccess(ognlValueStackFactory.container));
|
||||
// An OgnlValueStack created from the above OgnlValueStackFactory should allow public field access,
|
||||
// but prevent non-public field access. It should also allow static method access.
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@staticInteger100Method()");
|
||||
assertNotNull("unable to access static method (result null) ?", accessedValue);
|
||||
assertEquals("accessed static method result not equal to expected?", accessedValue, staticInteger100Method());
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_FINAL_PUBLIC_ATTRIBUTE");
|
||||
assertEquals("accessed static final public field value not equal to actual?", accessedValue, STATIC_FINAL_PUBLIC_ATTRIBUTE);
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_PUBLIC_ATTRIBUTE");
|
||||
assertEquals("accessed static public field value not equal to actual?", accessedValue, STATIC_PUBLIC_ATTRIBUTE);
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_FINAL_PACKAGE_ATTRIBUTE");
|
||||
assertNull("accessed final package field (result not null) ?", accessedValue);
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_PACKAGE_ATTRIBUTE");
|
||||
assertNull("accessed package field (result not null) ?", accessedValue);
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_FINAL_PROTECTED_ATTRIBUTE");
|
||||
assertNull("accessed final protected field (result not null) ?", accessedValue);
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_PROTECTED_ATTRIBUTE");
|
||||
assertNull("accessed protected field (result not null) ?", accessedValue);
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_FINAL_PRIVATE_ATTRIBUTE");
|
||||
assertNull("accessed final private field (result not null) ?", accessedValue);
|
||||
accessedValue = ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_PRIVATE_ATTRIBUTE");
|
||||
assertNull("accessed private field (result not null) ?", accessedValue);
|
||||
}
|
||||
|
||||
protected boolean containerAllowsStaticMethodAccess(Container checkContainer) {
|
||||
return Boolean.parseBoolean(checkContainer.getInstance(String.class, XWorkConstants.ALLOW_STATIC_METHOD_ACCESS));
|
||||
}
|
||||
|
||||
private void reloadTestContainerConfiguration(final Boolean allowStaticMethod) throws Exception {
|
||||
loadConfigurationProviders(new StubConfigurationProvider() {
|
||||
@Override
|
||||
public void register(ContainerBuilder builder,
|
||||
LocatableProperties props) throws ConfigurationException {
|
||||
// null values simulate undefined (by removing).
|
||||
// undefined values then should be evaluated to false
|
||||
if (props.containsKey(StrutsConstants.STRUTS_ALLOW_STATIC_METHOD_ACCESS)) {
|
||||
props.remove(StrutsConstants.STRUTS_ALLOW_STATIC_METHOD_ACCESS);
|
||||
}
|
||||
if (props.containsKey(XWorkConstants.ALLOW_STATIC_METHOD_ACCESS)) {
|
||||
props.remove(XWorkConstants.ALLOW_STATIC_METHOD_ACCESS);
|
||||
}
|
||||
if (allowStaticMethod != null) {
|
||||
props.setProperty(StrutsConstants.STRUTS_ALLOW_STATIC_METHOD_ACCESS, "" + allowStaticMethod);
|
||||
props.setProperty(XWorkConstants.ALLOW_STATIC_METHOD_ACCESS, "" + allowStaticMethod);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
ognlUtil = container.getInstance(OgnlUtil.class);
|
||||
}
|
||||
|
||||
class BadJavaBean {
|
||||
private int count;
|
||||
private int count2;
|
||||
|
||||
Reference in New Issue
Block a user