This is an automated email from the ASF dual-hosted git repository.

yasserzamani pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/struts.git


The following commit(s) were added to refs/heads/master by this push:
     new d3eb1fc  Fix for default (un-configured) allowStaticFieldAccess state, 
Showcase Application in 2.6.x (#334)
d3eb1fc is described below

commit d3eb1fc5955f793d18aea5c43d0ca077e0a8794b
Author: JCgH4164838Gh792C124B5 
<43964333+jcgh4164838gh792c12...@users.noreply.github.com>
AuthorDate: Mon Mar 11 02:05:48 2019 -0400

    Fix for default (un-configured) allowStaticFieldAccess state, Showcase 
Application in 2.6.x (#334)
    
    * Fix for default un-configured allowStaticFieldAccess state:
    1) Ensure OgnlValueStackFactory returns true for allowStaticFieldAccess 
when not configured (consistency - same as OgnlUtil does).
    2) Add test to OgnlValueStackTest for the no allowStaticXXX flags present.
    
    Minor config fixes for the Showcase Application in 2.6.x:
    1) File upload examples.  Multiple file upload missing result page (list 
and array), added missing JSP.  Added missing input results in configuration.
    2) File upload examples.  Fixed NPE for multiple file upload (array 
version) when no files selected.
    3) Add manual test for public constant access via expression (to If tag 
JSP).
    
    * Added missed logic elements from PR#320 (identified by Y. Zamani):
    1) Added ognlAllowStaticFieldAccess field and getter/setter to 
ConstantConfig.
    2) Added allowStaticFieldAccess (set to true) to default.properties.
    
    * Follow-up commit:
    - Fixed wrong package reference in testNullMethod(), as well as in new tets.
    - Added additional tests to cover the full set of static access flag 
combinations.
    
    * Follow-up commit:
    - Fixed createValueStack() not setting allowStaticFieldAccess parameter.
    - Removed 3 unused import statement.
    - Refactored OgnlValueStackFactory creation logic into two utility methods: 
getValueStackFactory(), reloadValueStackFactory()
    - Added one additional test with a raw OgnlValueStackFactory generated 
OgnlValueStack (staticMethodAccess false, staticFieldAccess true).
      Test confirms same result as with a default OgnlValueStackFactory.
---
 .../MultipleFileUploadUsingArrayAction.java        |   6 +-
 .../src/main/resources/struts-fileupload.xml       |   2 +
 .../webapp/WEB-INF/tags/non-ui/ifTag/testIf.jsp    |  14 +
 .../struts2/config/entities/ConstantConfig.java    |  10 +
 .../org/apache/struts2/default.properties          |   3 +
 .../xwork2/ognl/OgnlValueStackTest.java            | 294 ++++++++++++++++++++-
 6 files changed, 321 insertions(+), 8 deletions(-)

diff --git 
a/apps/showcase/src/main/java/org/apache/struts2/showcase/fileupload/MultipleFileUploadUsingArrayAction.java
 
b/apps/showcase/src/main/java/org/apache/struts2/showcase/fileupload/MultipleFileUploadUsingArrayAction.java
index b1a5985..dcf671e 100644
--- 
a/apps/showcase/src/main/java/org/apache/struts2/showcase/fileupload/MultipleFileUploadUsingArrayAction.java
+++ 
b/apps/showcase/src/main/java/org/apache/struts2/showcase/fileupload/MultipleFileUploadUsingArrayAction.java
@@ -32,9 +32,9 @@ import java.io.File;
  */
 public class MultipleFileUploadUsingArrayAction extends ActionSupport {
 
-       private File[] uploads;
-       private String[] uploadFileNames;
-       private String[] uploadContentTypes;
+       private File[] uploads = new File[0];
+       private String[] uploadFileNames = new String[0];
+       private String[] uploadContentTypes = new String[0];
 
 
        public String upload() throws Exception {
diff --git a/apps/showcase/src/main/resources/struts-fileupload.xml 
b/apps/showcase/src/main/resources/struts-fileupload.xml
index a13739a..33be370 100644
--- a/apps/showcase/src/main/resources/struts-fileupload.xml
+++ b/apps/showcase/src/main/resources/struts-fileupload.xml
@@ -40,6 +40,7 @@
                </action>
                
                <action name="doMultipleUploadUsingList" 
class="org.apache.struts2.showcase.fileupload.MultipleFileUploadUsingListAction"
 method="upload">
+                        <result 
name="input">/WEB-INF/fileupload/multipleUploadUsingList.jsp</result>
                        
<result>/WEB-INF/fileupload/multiple-success.jsp</result>
                </action>
 
@@ -49,6 +50,7 @@
                </action>
 
                <action name="doMultipleUploadUsingArray" 
class="org.apache.struts2.showcase.fileupload.MultipleFileUploadUsingArrayAction"
 method="upload">
+                        <result 
name="input">/WEB-INF/fileupload/multipleUploadUsingArray.jsp</result>
                        
<result>/WEB-INF/fileupload/multiple-success.jsp</result>
                </action>
 
diff --git a/apps/showcase/src/main/webapp/WEB-INF/tags/non-ui/ifTag/testIf.jsp 
b/apps/showcase/src/main/webapp/WEB-INF/tags/non-ui/ifTag/testIf.jsp
index f9fe499..a0d52a6 100644
--- a/apps/showcase/src/main/webapp/WEB-INF/tags/non-ui/ifTag/testIf.jsp
+++ b/apps/showcase/src/main/webapp/WEB-INF/tags/non-ui/ifTag/testIf.jsp
@@ -18,6 +18,7 @@
 * under the License.
 */
 -->
+<%@page import="org.apache.struts2.showcase.hangman.HangmanConstants" %>
 <%@taglib prefix="s" uri="/struts-tags" %>
 <html>
 <head>
@@ -635,5 +636,18 @@
                </div>
        </div>
 </div>
+<br>
+<br>
+    <p>
+        A secondary test for this JSP visually verifies expression access to a 
public constant.
+        A direct access to the same public constant via scriptlet provides 
secondary verification.
+    </p>
+<br>
+<div>
+    Test public static (constant) access (expression).  Value: <s:property 
default="unavailable" 
value="@org.apache.struts2.showcase.hangman.HangmanConstants@HANGMAN_SESSION_KEY"
 />
+</div>
+<div>
+    Test public static (constant) access (scriptlet).  Value: 
<%=org.apache.struts2.showcase.hangman.HangmanConstants.HANGMAN_SESSION_KEY%>
+</div>
 </body>
 </html>
diff --git 
a/core/src/main/java/org/apache/struts2/config/entities/ConstantConfig.java 
b/core/src/main/java/org/apache/struts2/config/entities/ConstantConfig.java
index 371d3f4..d92ce00 100644
--- a/core/src/main/java/org/apache/struts2/config/entities/ConstantConfig.java
+++ b/core/src/main/java/org/apache/struts2/config/entities/ConstantConfig.java
@@ -91,6 +91,7 @@ public class ConstantConfig {
     private BeanConfig localeProvider;
     private BeanConfig localeProviderFactory;
     private String mapperIdParameterName;
+    private Boolean ognlAllowStaticFieldAccess;
     private Boolean ognlAllowStaticMethodAccess;
     private BeanConfig actionValidatorManager;
     private BeanConfig valueStackFactory;
@@ -219,6 +220,7 @@ public class ConstantConfig {
         map.put(StrutsConstants.STRUTS_LOCALE_PROVIDER, 
beanConfToString(localeProvider));
         map.put(StrutsConstants.STRUTS_LOCALE_PROVIDER_FACTORY, 
beanConfToString(localeProviderFactory));
         map.put(StrutsConstants.STRUTS_ID_PARAMETER_NAME, 
mapperIdParameterName);
+        map.put(StrutsConstants.STRUTS_ALLOW_STATIC_FIELD_ACCESS, 
Objects.toString(ognlAllowStaticFieldAccess, null));
         map.put(StrutsConstants.STRUTS_ALLOW_STATIC_METHOD_ACCESS, 
Objects.toString(ognlAllowStaticMethodAccess, null));
         map.put(StrutsConstants.STRUTS_ACTIONVALIDATORMANAGER, 
beanConfToString(actionValidatorManager));
         map.put(StrutsConstants.STRUTS_VALUESTACKFACTORY, 
beanConfToString(valueStackFactory));
@@ -824,6 +826,14 @@ public class ConstantConfig {
         this.mapperIdParameterName = mapperIdParameterName;
     }
 
+    public Boolean getOgnlAllowStaticFieldAccess() {
+        return ognlAllowStaticFieldAccess;
+    }
+
+    public void setOgnlAllowStaticFieldAccess(Boolean 
ognlAllowStaticFieldAccess) {
+        this.ognlAllowStaticFieldAccess = ognlAllowStaticFieldAccess;
+    }
+
     public Boolean getOgnlAllowStaticMethodAccess() {
         return ognlAllowStaticMethodAccess;
     }
diff --git a/core/src/main/resources/org/apache/struts2/default.properties 
b/core/src/main/resources/org/apache/struts2/default.properties
index a465567..a441e77 100644
--- a/core/src/main/resources/org/apache/struts2/default.properties
+++ b/core/src/main/resources/org/apache/struts2/default.properties
@@ -203,6 +203,9 @@ struts.xslt.nocache=false
 ### Whether to always select the namespace to be everything before the last 
slash or not
 struts.mapper.alwaysSelectFullNamespace=false
 
+### Whether to allow static field access in OGNL expressions or not
+struts.ognl.allowStaticFieldAccess=true
+
 ### Whether to allow static method access in OGNL expressions or not
 struts.ognl.allowStaticMethodAccess=false
 
diff --git 
a/core/src/test/java/com/opensymphony/xwork2/ognl/OgnlValueStackTest.java 
b/core/src/test/java/com/opensymphony/xwork2/ognl/OgnlValueStackTest.java
index 9209e73..b10cba7 100644
--- a/core/src/test/java/com/opensymphony/xwork2/ognl/OgnlValueStackTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/ognl/OgnlValueStackTest.java
@@ -19,15 +19,15 @@
 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 +36,7 @@ import java.math.BigDecimal;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.Map;
+import org.apache.struts2.StrutsConstants;
 
 
 /**
@@ -43,10 +44,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
@@ -66,9 +82,38 @@ public class OgnlValueStackTest extends XWorkTestCase {
                 container.getInstance(TextProvider.class, "system"), 
allowStaticMethodAccess, allowStaticFieldAccess);
         container.inject(stack);
         
ognlUtil.setAllowStaticMethodAccess(Boolean.toString(allowStaticMethodAccess));
+        
ognlUtil.setAllowStaticFieldAccess(Boolean.toString(allowStaticFieldAccess));
         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
+     * @param allowStaticField new allowStaticField configuration
+     * @return a new OgnlValueStackFactory with specified new configuration
+     */
+    private OgnlValueStackFactory reloadValueStackFactory(Boolean 
allowStaticMethod, Boolean allowStaticField) {
+        try {
+            reloadTestContainerConfiguration(allowStaticMethod, 
allowStaticField);
+        }
+        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 +625,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() {
@@ -980,6 +1025,245 @@ 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 access flag values present should prevent staticMethodAccess 
but allow staticFieldAccess.
+        assertFalse("OgnlValueStackFactory staticMethodAccess (default flags) 
not false?", ognlValueStackFactory.containerAllowsStaticMethodAccess());
+        assertTrue("OgnlValueStackFactory staticFieldAccess (default flags) 
not true?", ognlValueStackFactory.containerAllowsStaticFieldAccess());
+        // 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 access flags are set (not present in configuration).
+     */
+    public void testOgnlValueStackFromOgnlValueStackFactoryNoFlagsSet() {
+        OgnlValueStackFactory ognlValueStackFactory = 
reloadValueStackFactory(null, null);
+        OgnlValueStack ognlValueStack = (OgnlValueStack) 
ognlValueStackFactory.createValueStack();
+        Object accessedValue;
+
+        // An OgnlValueStackFactory using a container config with no static 
access flag values present
+        // (such as from a DefaultConfiguration vs. 
XWorkConfigurationProvider) should
+        // prevent staticMethodAccess AND prevent staticFieldAccess.
+        // Note: Under normal circumstances, explicit static access 
configuration flags should be present,
+        // but this specific check verifies what happens if those 
configuration flags are not present.
+        assertFalse("OgnlValueStackFactory staticMethodAccess (no flag 
present) not false?", 
ognlValueStackFactory.containerAllowsStaticMethodAccess());
+        assertFalse("OgnlValueStackFactory staticFieldAccess (no flag present) 
not false?", ognlValueStackFactory.containerAllowsStaticFieldAccess());
+        // An OgnlValueStack created from the above OgnlValueStackFactory 
should prevent 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");
+        assertNull("able to access static final public field (result not null) 
?", accessedValue);
+        accessedValue = 
ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_PUBLIC_ATTRIBUTE");
+        assertNull("able to access static public field (result not null) ?", 
accessedValue);
+        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 both static access flags are set to false.
+     */
+    public void testOgnlValueStackFromOgnlValueStackFactoryNoStaticAccess() {
+        OgnlValueStackFactory ognlValueStackFactory = 
reloadValueStackFactory(false, false);
+        OgnlValueStack ognlValueStack = (OgnlValueStack) 
ognlValueStackFactory.createValueStack();
+        Object accessedValue;
+
+        // An OgnlValueStackFactory using a container config with both static 
access flags set false should
+        // prevent staticMethodAccess AND prevent staticFieldAccess.
+        assertFalse("OgnlValueStackFactory staticMethodAccess (set false) not 
false?", ognlValueStackFactory.containerAllowsStaticMethodAccess());
+        assertFalse("OgnlValueStackFactory staticFieldAccess (set false) not 
false?", ognlValueStackFactory.containerAllowsStaticFieldAccess());
+        // An OgnlValueStack created from the above OgnlValueStackFactory 
should prevent 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");
+        assertNull("able to access static final public field (result not null) 
?", accessedValue);
+        accessedValue = 
ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_PUBLIC_ATTRIBUTE");
+        assertNull("able to access static public field (result not null) ?", 
accessedValue);
+        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 both static access flags are set to true.
+     */
+    public void testOgnlValueStackFromOgnlValueStackFactoryAllStaticAccess() {
+        OgnlValueStackFactory ognlValueStackFactory = 
reloadValueStackFactory(true, true);
+        OgnlValueStack ognlValueStack = (OgnlValueStack) 
ognlValueStackFactory.createValueStack();
+        Object accessedValue;
+
+        // An OgnlValueStackFactory using a container config with both static 
access flags set true should
+        // allow both staticMethodAccess AND staticFieldAccess.
+        assertTrue("OgnlValueStackFactory staticMethodAccess (set true) not 
true?", ognlValueStackFactory.containerAllowsStaticMethodAccess());
+        assertTrue("OgnlValueStackFactory staticFieldAccess (set true) not 
true?", ognlValueStackFactory.containerAllowsStaticFieldAccess());
+        // 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);
+    }
+
+    /**
+     * Test a raw OgnlValueStackFactory and OgnlValueStack generated by it
+     * when static method access flag is true, static field access flag is 
false.
+     */
+    public void 
testOgnlValueStackFromOgnlValueStackFactoryOnlyStaticMethodAccess() {
+        OgnlValueStackFactory ognlValueStackFactory = 
reloadValueStackFactory(true, false);
+        OgnlValueStack ognlValueStack = (OgnlValueStack) 
ognlValueStackFactory.createValueStack();
+        Object accessedValue;
+
+        // An OgnlValueStackFactory using a container config with static 
method access flag true, static field access false should
+        // allow staticMethodAccess but deny staticFieldAccess.
+        assertTrue("OgnlValueStackFactory staticMethodAccess (set true) not 
true?", ognlValueStackFactory.containerAllowsStaticMethodAccess());
+        assertFalse("OgnlValueStackFactory staticFieldAccess (set false) not 
false?", ognlValueStackFactory.containerAllowsStaticFieldAccess());
+        // An OgnlValueStack created from the above OgnlValueStackFactory 
should deny public field access,
+        // and also 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");
+        assertNull("able to access static final public field (result not null) 
?", accessedValue);
+        accessedValue = 
ognlValueStack.findValue("@com.opensymphony.xwork2.ognl.OgnlValueStackTest@STATIC_PUBLIC_ATTRIBUTE");
+        assertNull("able to access static public field (result not null) ?", 
accessedValue);
+        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 false, static field access flag is 
true.
+     */
+    public void 
testOgnlValueStackFromOgnlValueStackFactoryOnlyStaticFieldAccess() {
+        OgnlValueStackFactory ognlValueStackFactory = 
reloadValueStackFactory(false, true);
+        OgnlValueStack ognlValueStack = (OgnlValueStack) 
ognlValueStackFactory.createValueStack();
+        Object accessedValue;
+
+        // An OgnlValueStackFactory using a container config with static 
method access flag false, static field access true should
+        // deny staticMethodAccess but allow staticFieldAccess.
+        assertFalse("OgnlValueStackFactory staticMethodAccess (set false) not 
false?", ognlValueStackFactory.containerAllowsStaticMethodAccess());
+        assertTrue("OgnlValueStackFactory staticFieldAccess (set true) not 
true?", ognlValueStackFactory.containerAllowsStaticFieldAccess());
+        // 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);
+    }
+
+    private void reloadTestContainerConfiguration(Boolean allowStaticMethod, 
Boolean allowStaticField) 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(StrutsConstants.STRUTS_ALLOW_STATIC_FIELD_ACCESS)) {
+                    
props.remove(StrutsConstants.STRUTS_ALLOW_STATIC_FIELD_ACCESS);
+                }
+                if (allowStaticMethod != null) {
+                    
props.setProperty(StrutsConstants.STRUTS_ALLOW_STATIC_METHOD_ACCESS, "" + 
allowStaticMethod);
+                }
+                if (allowStaticField != null) {
+                    
props.setProperty(StrutsConstants.STRUTS_ALLOW_STATIC_FIELD_ACCESS, "" + 
allowStaticField);
+                }
+            }
+        });
+        ognlUtil = container.getInstance(OgnlUtil.class);
+    }
+
     class BadJavaBean {
         private int count;
         private int count2;

Reply via email to