Compare commits

..

43 Commits

Author SHA1 Message Date
Lukasz Lenart 68fb49c10e [maven-release-plugin] prepare release STRUTS_6_0_0 2022-06-02 09:11:02 +02:00
Lukasz Lenart 77c175c7be Merge pull request #555 from hboutemy/patch-4
upgrade Felix m-bundle-p: reproducible builds
2022-05-25 10:42:55 +02:00
Hervé Boutemy 65b7e8c36f upgrade Felix m-bundle-p: reproducible builds 2022-05-25 10:00:15 +02:00
Lukasz Lenart 735bbc283e [maven-release-plugin] prepare for next development iteration 2022-05-24 13:59:32 +02:00
Lukasz Lenart 981885fd6a [maven-release-plugin] prepare release STRUTS_6_0_0_RC4 2022-05-24 13:59:22 +02:00
Lukasz Lenart 07b88fcc35 Upgrades integration tests config to match Spring and Jetty 2022-05-24 09:51:42 +02:00
Lukasz Lenart 2cbe47297e Merge pull request #554 from gregh3269/More_localdatetime_support
Add basic LocalDateTime support WW-5175
2022-05-23 07:35:43 +02:00
Lukasz Lenart 545add9365 Merge pull request #553 from apache/WW-5179-max-length
[WW-5179] Set default value of struts.ognl.expressionMaxLength to 256
2022-05-23 07:34:17 +02:00
Lukasz Lenart ebecc7d39d Merge pull request #552 from apache/WW-5165-upgrade-spring
[WW-5165] Upgrades Spring to version 5.3.20
2022-05-23 07:34:05 +02:00
Greg Huber 226a1d49ce Add basic LocalDateTime support WW-5175 2022-05-20 11:47:08 +01:00
Greg Huber 075ef7c4e1 Add basic LocalDateTime support WW-5175 2022-05-19 10:30:36 +01:00
Lukasz Lenart 1237110652 WW-5179 Adjusts test to match new default value 2022-05-17 21:17:56 +02:00
Lukasz Lenart 3f2518afa8 WW-5179 Set default value of struts.ognl.expressionMaxLength to 256 2022-05-17 20:59:51 +02:00
Lukasz Lenart 9f9edf4705 WW-5165 Upgrades Spring to version 5.3.20 2022-05-17 07:37:39 +02:00
gregh3269 7e912742ed Basic LocalDateTime support (#532)
* Basic LocalDateTime support

* Basic LocalDateTime support

* Basic LocalDateTime support

* Basic LocalDateTime support

* Basic LocalDateTime support

Co-authored-by: Greg Huber <ghuber@guestales.co.uk>
Co-authored-by: Greg Huber <ghuber@apache.org>
2022-05-17 07:31:30 +02:00
Lukasz Lenart c98b60cd9a Merge pull request #528 from JCgH4164838Gh792C124B5/localS2_26_OgnlUtilOptionalCache1
Potential expression cache enhancement for 2.6 series
2022-05-16 07:38:59 +02:00
Lukasz Lenart 5ae9688ae8 Merge pull request #551 from apache/dependabot/maven/xerces-xercesImpl-2.12.2
Bump xercesImpl from 2.12.0 to 2.12.2
2022-05-16 07:18:03 +02:00
Lukasz Lenart b72200aabf Merge branch 'master' into localS2_26_OgnlUtilOptionalCache1
# Conflicts:
#	core/src/test/java/com/opensymphony/xwork2/ognl/OgnlUtilTest.java
2022-05-16 07:16:03 +02:00
JCgH4164838Gh792C124B5 16e7c9b459 Merge pull request #1 from apache/use-extension-point
Ties cache extension points with implementation
2022-05-15 19:01:17 -04:00
Yasser Zamani bea1c6f09f Merge pull request #549 from apache/WW-5181-static-methods
[WW-5181] Blocks permanently access to static methods
2022-05-15 14:40:12 +04:30
dependabot[bot] 888884cc51 Bump xercesImpl from 2.12.0 to 2.12.2
Bumps xercesImpl from 2.12.0 to 2.12.2.

---
updated-dependencies:
- dependency-name: xerces:xercesImpl
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-15 10:02:32 +00:00
Yasser Zamani b387abae01 Merge pull request #550 from apache/servlet-3
[WW-5182] Upgrade to Servlet API 3.1
2022-05-15 14:27:47 +04:30
Lukasz Lenart 059a2a6117 WW-5182 Upgrade to Servlet API 3.1 2022-05-14 09:12:42 +02:00
Lukasz Lenart c0a3be9fd8 Uses two step build process on Travis similar to Jenkins pipeline 2022-05-10 07:41:34 +02:00
Lukasz Lenart 4a7cae029a Uses proper package to match Jetty Eclipse 2022-05-08 12:31:40 +02:00
Lukasz Lenart 9873a7f56b Tries to fix Travis build 2022-05-06 08:35:06 +02:00
Lukasz Lenart 086b514d59 Adjusts Travis build to be aligned with Jenkins pipeline 2022-05-06 07:47:12 +02:00
Lukasz Lenart 6024dd6fa4 Skips test during deploy 2022-05-06 07:29:29 +02:00
Lukasz Lenart 4eb2ee8384 Fixes typo in deploy step 2022-05-06 07:24:29 +02:00
Lukasz Lenart 8e49362bf8 Uses Maven Wrapper in Jenkins pipeline 2022-05-06 07:15:13 +02:00
Lukasz Lenart 7541d9ab35 WW-5181 Blocks permanently access to static methods 2022-05-05 12:28:09 +02:00
Lukasz Lenart c82fdb5e76 Upgrades Maven Wrapper 2022-05-05 12:27:51 +02:00
Lukasz Lenart f40f9f15e5 Merge pull request #547 from apache/dependabot/maven/junit-junit-4.13.1
Bump junit from 4.13 to 4.13.1
2022-05-04 11:18:43 +02:00
dependabot[bot] 2d9cdb73a5 Bump junit from 4.13 to 4.13.1
Bumps [junit](https://github.com/junit-team/junit4) from 4.13 to 4.13.1.
- [Release notes](https://github.com/junit-team/junit4/releases)
- [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.13.1.md)
- [Commits](https://github.com/junit-team/junit4/compare/r4.13...r4.13.1)

---
updated-dependencies:
- dependency-name: junit:junit
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-04 08:52:18 +00:00
Lukasz Lenart d07a496d5c Uses common Maven Compiler plugin to set proper source and target version 2022-05-04 10:45:02 +02:00
Lukasz Lenart bef1f67d4a Upgrades Maven Jetty Plugin to work with JDK8+ 2022-05-04 10:44:54 +02:00
Lukasz Lenart e2718aa482 Enables branch autodeleting after PR has been merged 2022-04-07 14:43:38 +02:00
Lukasz Lenart b73fec4de0 Drops unused class 2022-04-04 17:12:33 +02:00
Lukasz Lenart c2795d2e30 Uses project specific folder 2022-03-28 13:09:21 +02:00
Lukasz Lenart a987e31a0e Upgrades OWASP Dependency Check plugin to version 7.0.1 2022-03-28 07:45:51 +02:00
Lukasz Lenart 6aff5b7faa WW-5174 Upgrades Jackson-Core to version 2.13.2 and Jackson-Databind to 2.13.2.1 2022-03-28 07:26:50 +02:00
Lukasz Lenart 5b40f9f48e WW-5172 Upgrades Freemarker to 2.3.31 version 2022-03-15 14:32:02 +01:00
Lukasz Lenart e9d0a5518c Cleans up code 2022-03-15 14:27:57 +01:00
92 changed files with 2003 additions and 1015 deletions
+4
View File
@@ -1,3 +1,4 @@
# Documentation https://s.apache.org/asfyaml
notifications:
commits: commits@struts.apache.org
# Send all issue emails (new, closed, comments) to issues@
@@ -8,3 +9,6 @@ notifications:
pullrequests_comment: issues@struts.apache.org
# Link opened PRs with JIRA
jira_options: link label worklog
github:
del_branch_on_merge: true
+1 -1
View File
@@ -14,5 +14,5 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.5/apache-maven-3.8.5-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar
+4 -7
View File
@@ -14,17 +14,14 @@ global:
matrix:
include:
- jdk: oraclejdk8
env: STRUTS_IT=true # do integration tests and coverage reports when jdk7,9 and 11 tests prospered
env: STRUTS_IT=true # do integration tests and coverage reports when jdk 9 and 11 tests prospered
script:
- if [ "$STRUTS_IT" == "true" ]; then
./mvnw clean verify org.jacoco:jacoco-maven-plugin:report org.jacoco:jacoco-maven-plugin:report-integration org.eluder.coveralls:coveralls-maven-plugin:report -Ptravis-coveralls -DskipAssembly -B;
./mvnw clean install -DskipTests -DskipAssembly -B;
./mvnw test org.jacoco:jacoco-maven-plugin:report org.jacoco:jacoco-maven-plugin:report-integration org.eluder.coveralls:coveralls-maven-plugin:report -Ptravis-coveralls -DskipAssembly -B;
else
if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
./mvnw test -DskipAssembly -B;
else
./mvnw test -DskipAssembly -Dupdate-impact -B;
fi;
./mvnw clean package test -DskipAssembly -B;
fi;
cache:
Vendored
+10 -10
View File
@@ -39,12 +39,12 @@ pipeline {
stages {
stage('Build') {
steps {
sh 'mvn -B clean install -DskipTests -DskipAssembly'
sh './mvnw -B clean install -DskipTests -DskipAssembly'
}
}
stage('Test') {
steps {
sh 'mvn -B test'
sh './mvnw -B test'
}
post {
always {
@@ -74,12 +74,12 @@ pipeline {
stages {
stage('Build') {
steps {
sh 'mvn -B clean install -DskipTests -DskipAssembly'
sh './mvnw -B clean install -DskipTests -DskipAssembly'
}
}
stage('Test') {
steps {
sh 'mvn -B test'
sh './mvnw -B test'
}
post {
always {
@@ -94,7 +94,7 @@ pipeline {
}
steps {
withCredentials([string(credentialsId: 'asf-struts-sonarcloud', variable: 'SONARCLOUD_TOKEN')]) {
sh 'mvn sonar:sonar -DskipAssembly -Dsonar.login=${SONARCLOUD_TOKEN}'
sh './mvnw sonar:sonar -DskipAssembly -Dsonar.login=${SONARCLOUD_TOKEN}'
}
}
}
@@ -119,12 +119,12 @@ pipeline {
stages {
stage('Build') {
steps {
sh 'mvn -B clean install -DskipTests -DskipAssembly'
sh './mvnw -B clean install -DskipTests -DskipAssembly'
}
}
stage('Test') {
steps {
sh 'mvn -B test'
sh './mvnw -B test'
// step([$class: 'JiraIssueUpdater', issueSelector: [$class: 'DefaultIssueSelector'], scm: scm])
}
post {
@@ -142,7 +142,7 @@ pipeline {
dir("local-snapshots-dir/") {
deleteDir()
}
sh 'mvn -B source:jar javadoc:jar -DskipAssembbly'
sh './mvnw -B source:jar javadoc:jar -DskipTests -DskipAssembly'
}
}
stage('Deploy Snapshot') {
@@ -151,7 +151,7 @@ pipeline {
}
steps {
withCredentials([file(credentialsId: 'lukaszlenart-repository-access-token', variable: 'CUSTOM_SETTINGS')]) {
sh 'mvn -s \${CUSTOM_SETTINGS} deploy'
sh './mvnw -s \${CUSTOM_SETTINGS} deploy -DskipTests -DskipAssembly'
}
}
}
@@ -165,7 +165,7 @@ pipeline {
configName: 'Nightlies',
transfers: [
sshTransfer(
remoteDirectory: '/x1/dist/struts',
remoteDirectory: '/struts/snapshot',
removePrefix: 'assembly/target/assembly/out',
sourceFiles: 'assembly/target/assembly/out/struts-*.zip'
)
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-parent</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<artifactId>struts2-apps</artifactId>
<packaging>pom</packaging>
+4 -4
View File
@@ -24,12 +24,12 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-apps</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<artifactId>struts2-rest-showcase</artifactId>
<packaging>war</packaging>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
<name>Struts 2 Rest Showcase Webapp</name>
<description>Struts 2 Rest Showcase Example</description>
@@ -108,9 +108,9 @@
<finalName>struts2-rest-showcase</finalName>
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>8.1.16.v20140903</version>
<version>9.4.46.v20220331</version>
<configuration>
<stopKey>CTRL+C</stopKey>
<stopPort>8999</stopPort>
+8 -20
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-apps</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<artifactId>struts2-showcase</artifactId>
@@ -101,7 +101,7 @@
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
@@ -144,7 +144,7 @@
<dependency>
<groupId>net.sourceforge.htmlunit</groupId>
<artifactId>htmlunit</artifactId>
<version>2.39.0</version>
<version>2.61.0</version>
<scope>test</scope>
</dependency>
@@ -155,15 +155,6 @@
<version>6.1.2.Final</version>
</dependency>
<!-- The Servlet API mocks in Spring Framework 4.x only supports Servlet 3.0 and higher.
This is only necessary in tests-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
@@ -171,7 +162,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.0.0-M4</version>
<version>3.0.0-M6</version>
<configuration>
<includes>
<include>it.org.apache.struts2.showcase.*Test</include>
@@ -193,16 +184,16 @@
</executions>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>8.1.16.v20140903</version>
<version>9.4.46.v20220331</version>
<configuration>
<stopKey>CTRL+C</stopKey>
<stopPort>8999</stopPort>
<systemProperties>
<systemProperty>
<name>log4j.configuration</name>
<value>file:${basedir}/src/main/resources/log4j.properties</value>
<value>file:${basedir}/src/main/resources/log4j2.xml</value>
</systemProperty>
<systemProperty>
<name>slf4j</name>
@@ -223,11 +214,8 @@
<goals>
<!-- stop any previous instance to free up the port -->
<goal>stop</goal>
<goal>run-forked</goal>
<goal>start</goal>
</goals>
<configuration>
<waitForChild>false</waitForChild>
</configuration>
</execution>
<execution>
<id>stop-jetty</id>
@@ -45,66 +45,46 @@
</bean>
<bean id="chatLoginAction" class="org.apache.struts2.showcase.chat.ChatLoginAction" scope="prototype">
<constructor-arg index="0">
<ref local="chatService"/>
</constructor-arg>
<constructor-arg index="0" ref="chatService"/>
</bean>
<bean id="chatLogoutAction" class="org.apache.struts2.showcase.chat.ChatLogoutAction" scope="prototype">
<constructor-arg index="0">
<ref local="chatService"/>
</constructor-arg>
<constructor-arg index="0" ref="chatService"/>
</bean>
<bean id="usersAvailableAction" class="org.apache.struts2.showcase.chat.UsersAvailableAction" scope="prototype">
<constructor-arg index="0">
<ref local="chatService"/>
</constructor-arg>
<constructor-arg index="0" ref="chatService"/>
</bean>
<bean id="roomsAvailableAction" class="org.apache.struts2.showcase.chat.RoomsAvailableAction" scope="prototype">
<constructor-arg index="0">
<ref local="chatService"/>
</constructor-arg>
<constructor-arg index="0" ref="chatService"/>
</bean>
<bean id="crudRoomAction" class="org.apache.struts2.showcase.chat.CrudRoomAction" scope="prototype">
<constructor-arg index="0">
<ref local="chatService"/>
</constructor-arg>
<constructor-arg index="0" ref="chatService"/>
</bean>
<bean id="enterRoomAction" class="org.apache.struts2.showcase.chat.EnterRoomAction" scope="prototype">
<constructor-arg index="0">
<ref local="chatService"/>
</constructor-arg>
<constructor-arg index="0" ref="chatService"/>
</bean>
<bean id="messagesAvailableInRoomAction" class="org.apache.struts2.showcase.chat.MessagesAvailableInRoomAction"
scope="prototype">
<constructor-arg index="0">
<ref local="chatService"/>
</constructor-arg>
<constructor-arg index="0" ref="chatService"/>
</bean>
<bean id="sendMessageToRoomAction" class="org.apache.struts2.showcase.chat.SendMessageToRoomAction"
scope="prototype">
<constructor-arg index="0">
<ref local="chatService"/>
</constructor-arg>
<constructor-arg index="0" ref="chatService"/>
</bean>
<bean id="usersAvailableInRoomAction" class="org.apache.struts2.showcase.chat.UsersAvailableInRoomAction"
scope="prototype">
<constructor-arg index="0">
<ref local="chatService"/>
</constructor-arg>
<constructor-arg index="0" ref="chatService"/>
</bean>
<bean id="exitRoomAction" class="org.apache.struts2.showcase.chat.ExitRoomAction" scope="prototype">
<constructor-arg index="0">
<ref local="chatService"/>
</constructor-arg>
<constructor-arg index="0" ref="chatService"/>
</bean>
@@ -129,9 +109,7 @@
</bean>
<bean id="startHangmanAction" class="org.apache.struts2.showcase.hangman.StartHangmanAction" scope="prototype">
<constructor-arg index="0">
<ref local="hangmanService"/>
</constructor-arg>
<constructor-arg index="0" ref="hangmanService"/>
</bean>
<bean id="guessCharacterAction" class="org.apache.struts2.showcase.hangman.GuessCharacterAction" scope="prototype"/>
@@ -32,7 +32,7 @@ public class ActionChainingTest {
try (final WebClient webClient = new WebClient()) {
final HtmlPage page = webClient.getPage(ParameterUtils.getBaseUrl() + "/actionchaining/actionChain1!input");
final String pageAsText = page.asText();
final String pageAsText = page.asNormalizedText();
Assert.assertTrue(pageAsText.contains("Action Chain 1 Property 1: Property Set In Action Chain 1"));
Assert.assertTrue(pageAsText.contains("Action Chain 2 Property 1: Property Set in Action Chain 2"));
Assert.assertTrue(pageAsText.contains("Action Chain 3 Property 1: Property set in Action Chain 3"));
@@ -32,7 +32,7 @@ public class ActionTagExampleTest {
try (final WebClient webClient = new WebClient()) {
final HtmlPage page = webClient.getPage(ParameterUtils.getBaseUrl() + "/tags/ui/actionTagExample!input.action");
final String pageAsText = page.asText();
final String pageAsText = page.asNormalizedText();
Assert.assertTrue(pageAsText.contains("This text is from the called class"));
}
}
@@ -46,7 +46,7 @@ public class AsyncTest {
final DomElement msgs = page2.getElementById("msgs");
Assert.assertEquals("hello", msgs.asText());
Assert.assertEquals("hello", msgs.asNormalizedText());
}
}
}
@@ -44,7 +44,7 @@ public class CRUDTest {
final HtmlSubmitInput button = form.getInputByValue("Save");
final HtmlPage page2 = button.click();
final String page2Text = page2.asText();
final String page2Text = page2.asNormalizedText();
Assert.assertTrue(page2Text.contains("somename1"));
Assert.assertTrue(page2Text.contains("somedescription1"));
@@ -33,7 +33,7 @@ public class ComponentTagExampleTest {
final HtmlPage page = webClient
.getPage(ParameterUtils.getBaseUrl() + "/tags/ui/componentTagExample.action");
final String pageAsText = page.asText();
final String pageAsText = page.asNormalizedText();
Assert.assertTrue(pageAsText.contains("Freemarker Custom Template - parameter 'paramName' - paramValue1"));
Assert.assertTrue(pageAsText.contains("Freemarker Custom Template - parameter 'paramName' - paramValue4"));
Assert.assertTrue(pageAsText.contains("JSP Custom Template - parameter 'paramName' - paramValue2"));
@@ -46,7 +46,7 @@ public class ConversionTest {
final HtmlSubmitInput button = form.getInputByValue("Submit");
final HtmlPage page2 = button.click();
final String page2Text = page2.asText();
final String page2Text = page2.asNormalizedText();
Assert.assertTrue(page2Text.contains("SET 0 Name: name0"));
Assert.assertTrue(page2Text.contains("SET 0 Age: 0"));
@@ -71,7 +71,7 @@ public class ConversionTest {
final HtmlSubmitInput button = form.getInputByValue("Submit");
final HtmlPage page2 = button.click();
final String page2Text = page2.asText();
final String page2Text = page2.asNormalizedText();
Assert.assertTrue(page2Text.contains("id0 -> address0"));
Assert.assertTrue(page2Text.contains("id1 -> address1"));
@@ -92,7 +92,7 @@ public class ConversionTest {
final HtmlSubmitInput button = form.getInputByValue("Submit");
final HtmlPage page2 = button.click();
final String page2Text = page2.asText();
final String page2Text = page2.asNormalizedText();
Assert.assertTrue(page2Text.contains("ADD"));
Assert.assertTrue(page2Text.contains("MINUS"));
@@ -43,12 +43,12 @@ public class ExecAndWaitTest {
final HtmlSubmitInput button = form.getInputByValue("submit");
final HtmlPage page2 = button.click();
Assert.assertTrue(page2.asText().contains("We are processing your request. Please wait."));
Assert.assertTrue(page2.asNormalizedText().contains("We are processing your request. Please wait."));
// hit it again
final HtmlPage page3 = webClient
.getPage(ParameterUtils.getBaseUrl() + "/wait/longProcess1.action?time=1000");
Assert.assertTrue(page3.asText().contains("We are processing your request. Please wait."));
Assert.assertTrue(page3.asNormalizedText().contains("We are processing your request. Please wait."));
}
}
}
@@ -43,6 +43,7 @@ public class FileDownloadTest {
}
}
@Test
public void testZip() throws Exception {
try (final WebClient webClient = new WebClient()) {
final Page page = webClient.getPage(ParameterUtils.getBaseUrl() + "/filedownload/download2.action");
@@ -36,11 +36,11 @@ public class FreeMarkerManagerTest {
final DomElement date = page.getElementById("todaysDate");
Assert.assertNotNull(date);
Assert.assertTrue(date.asText().length() > 0);
Assert.assertTrue(date.asNormalizedText().length() > 0);
final DomElement time = page.getElementById("timeNow");
Assert.assertNotNull(time);
Assert.assertTrue(time.asText().length() > 0);
Assert.assertTrue(time.asNormalizedText().length() > 0);
}
}
@@ -33,26 +33,23 @@ public class StaticContentTest {
webClient.getPage(ParameterUtils.getBaseUrl() + "/struts..");
Assert.fail("Previous request should have failed");
} catch (FailingHttpStatusCodeException e) {
Assert.assertEquals("Not Found", e.getStatusMessage());
Assert.assertEquals(404, e.getStatusCode());
}
}
}
@Test
public void testInvalidRersources2() throws Exception {
try (final WebClient webClient = new WebClient()) {
try {
webClient.getPage(ParameterUtils.getBaseUrl() + "/static/..%252f");
Assert.fail("Previous request should have failed");
} catch (FailingHttpStatusCodeException e) {
Assert.assertEquals("Not Found", e.getStatusMessage());
Assert.assertEquals(404, e.getStatusCode());
}
}
}
/*public void testInvalidRersources3() throws IOException {
try {
beginAt("/static/..%252f..%252f..%252fWEB-INF/classes/org/apache/struts2/showcase/action/EmployeeAction.class/");
fail("Previous request should have failed");
} catch (TestingEngineResponseException ex) {
// ok
}
}*/
}
@@ -65,11 +65,11 @@ public class UITagExampleTest {
final HtmlSubmitInput button = form.getInputByValue("Submit");
final HtmlPage page2 = button.click();
Assert.assertEquals("name", page2.getElementById("name").asText());
Assert.assertEquals("bio", page2.getElementById("bio").asText());
Assert.assertEquals("Red", page2.getElementById("favouriteColor").asText());
Assert.assertEquals("[Patrick, Jason]", page2.getElementById("friends").asText());
Assert.assertEquals("true", page2.getElementById("legalAge").asText());
Assert.assertEquals("name", page2.getElementById("name").asNormalizedText());
Assert.assertEquals("bio", page2.getElementById("bio").asNormalizedText());
Assert.assertEquals("Red", page2.getElementById("favouriteColor").asNormalizedText());
Assert.assertEquals("[Patrick, Jason]", page2.getElementById("friends").asNormalizedText());
Assert.assertEquals("true", page2.getElementById("legalAge").asNormalizedText());
}
}
}
@@ -47,7 +47,7 @@ public class ValidationTest {
final HtmlSubmitInput button = form.getInputByValue("Submit");
final HtmlPage page2 = button.click();
final String page2Text = page2.asText();
final String page2Text = page2.asNormalizedText();
Assert.assertTrue(page2Text.contains("Invalid field value for field \"dateValidatorField\""));
Assert.assertTrue(page2Text.contains("Invalid field value for field \"integerValidatorField\""));
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-parent</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<artifactId>struts2-assembly</artifactId>
+3 -3
View File
@@ -29,7 +29,7 @@
</parent>
<artifactId>struts2-bom</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
<packaging>pom</packaging>
<name>Struts 2 Bill of Materials</name>
@@ -44,7 +44,7 @@
</licenses>
<properties>
<struts-version.version>6.0.0-SNAPSHOT</struts-version.version>
<struts-version.version>6.0.0</struts-version.version>
<maven.site.skip>true</maven.site.skip>
<maven.site.deploy.skip>true</maven.site.deploy.skip>
</properties>
@@ -175,7 +175,7 @@
</dependencyManagement>
<scm>
<tag>HEAD</tag>
<tag>STRUTS_6_0_0</tag>
<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>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-osgi-bundles</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<artifactId>struts2-osgi-admin-bundle</artifactId>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-osgi-bundles</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<artifactId>struts2-osgi-demo-bundle</artifactId>
+2 -4
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-parent</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<artifactId>struts2-osgi-bundles</artifactId>
@@ -53,12 +53,10 @@
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<reporting>
+12 -11
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-parent</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<artifactId>struts2-core</artifactId>
<packaging>jar</packaging>
@@ -188,7 +188,7 @@
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
@@ -242,6 +242,16 @@
<artifactId>spring-web</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
@@ -345,15 +355,6 @@
<scope>test</scope>
</dependency>
<!-- The Servlet API mocks in Spring Framework 4.x only supports Servlet 3.0 and higher.
This is only necessary in tests-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-validator</groupId>
<artifactId>commons-validator</artifactId>
@@ -244,7 +244,6 @@ public class StrutsDefaultConfigurationProvider implements ConfigurationProvider
props.setProperty(StrutsConstants.STRUTS_OGNL_ENABLE_EXPRESSION_CACHE, Boolean.TRUE.toString());
props.setProperty(StrutsConstants.STRUTS_OGNL_ENABLE_EVAL_EXPRESSION, Boolean.FALSE.toString());
props.setProperty(StrutsConstants.STRUTS_CONFIGURATION_XML_RELOAD, Boolean.FALSE.toString());
props.setProperty(StrutsConstants.STRUTS_ALLOW_STATIC_METHOD_ACCESS, Boolean.FALSE.toString());
props.setProperty(StrutsConstants.STRUTS_ALLOW_STATIC_FIELD_ACCESS, Boolean.TRUE.toString());
props.setProperty(StrutsConstants.STRUTS_MATCHER_APPEND_NAMED_PARAMETERS, Boolean.TRUE.toString());
}
@@ -18,28 +18,36 @@
*/
package com.opensymphony.xwork2.conversion.impl;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.struts2.conversion.TypeConversionException;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.TextProvider;
import com.opensymphony.xwork2.util.ValueStack;
import java.lang.reflect.Constructor;
import java.lang.reflect.Member;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.temporal.TemporalAccessor;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.struts2.conversion.TypeConversionException;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.TextProvider;
import com.opensymphony.xwork2.util.ValueStack;
public class DateConverter extends DefaultTypeConverter {
private final static Logger LOG = LogManager.getLogger(DateConverter.class);
@Override
public Object convertValue(Map<String, Object> context, Object target, Member member, String propertyName, Object value, Class toType) {
public Object convertValue(Map<String, Object> context, Object target, Member member, String propertyName,
Object value, Class toType) {
Date result = null;
if (value instanceof String && ((String) value).length() > 0) {
@@ -52,15 +60,12 @@ public class DateConverter extends DefaultTypeConverter {
} else if (java.sql.Timestamp.class == toType) {
Date check = null;
SimpleDateFormat dtfmt = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.SHORT,
DateFormat.MEDIUM,
locale);
SimpleDateFormat fullfmt = new SimpleDateFormat(dtfmt.toPattern() + MILLISECOND_FORMAT,
locale);
DateFormat.MEDIUM, locale);
SimpleDateFormat fullfmt = new SimpleDateFormat(dtfmt.toPattern() + MILLISECOND_FORMAT, locale);
SimpleDateFormat dfmt = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.SHORT,
locale);
SimpleDateFormat dfmt = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.SHORT, locale);
SimpleDateFormat[] fmts = {fullfmt, dtfmt, dfmt};
SimpleDateFormat[] fmts = { fullfmt, dtfmt, dfmt };
for (SimpleDateFormat fmt : fmts) {
try {
check = fmt.parse(sa);
@@ -85,8 +90,39 @@ public class DateConverter extends DefaultTypeConverter {
} catch (ParseException ignore) {
}
}
} else if (java.time.LocalDateTime.class == toType || java.time.LocalDate.class == toType
|| java.time.LocalTime.class == toType) {
DateTimeFormatter dtf = null;
TemporalAccessor check = null;
DateTimeFormatter[] dfs = getDateTimeFormats(ActionContext.of(context), locale);
for (DateTimeFormatter df1 : dfs) {
try {
check = df1.parseBest(sa, LocalDateTime::from, LocalDate::from, LocalTime::from);
dtf = df1;
if (check != null) {
break;
}
} catch (DateTimeParseException ignore) {
}
}
try {
if (dtf != null && check instanceof LocalDateTime) {
return LocalDateTime.parse(sa, dtf);
} else if (dtf != null && check instanceof LocalDate) {
return LocalDate.parse(sa, dtf);
} else if (dtf != null && check instanceof LocalTime) {
return LocalTime.parse(sa, dtf);
} else {
throw new TypeConversionException("Could not parse date");
}
} catch (DateTimeParseException e) {
throw new TypeConversionException("Could not parse date", e);
}
}
//final fallback for dates without time
// final fallback for dates without time
if (df == null) {
df = DateFormat.getDateInstance(DateFormat.SHORT, locale);
}
@@ -95,15 +131,17 @@ public class DateConverter extends DefaultTypeConverter {
result = df.parse(sa);
if (!(Date.class == toType)) {
try {
Constructor<?> constructor = toType.getConstructor(new Class[]{long.class});
return constructor.newInstance(new Object[]{Long.valueOf(result.getTime())});
Constructor<?> constructor = toType.getConstructor(new Class[] { long.class });
return constructor.newInstance(new Object[] { Long.valueOf(result.getTime()) });
} catch (Exception e) {
throw new TypeConversionException("Couldn't create class " + toType + " using default (long) constructor", e);
throw new TypeConversionException(
"Couldn't create class " + toType + " using default (long) constructor", e);
}
}
} catch (ParseException e) {
throw new TypeConversionException("Could not parse date", e);
}
} else if (Date.class.isAssignableFrom(value.getClass())) {
result = (Date) value;
}
@@ -111,16 +149,16 @@ public class DateConverter extends DefaultTypeConverter {
}
/**
* The user defined global date format,
* see {@link org.apache.struts2.components.Date#DATETAG_PROPERTY}
* The user defined global date format, see
* {@link org.apache.struts2.components.Date#DATETAG_PROPERTY}
*
* @param context current ActionContext
* @param locale current Locale to convert to
* @return defined global format
*
* @return defined global date string format
*/
protected DateFormat getGlobalDateFormat(ActionContext context, Locale locale) {
protected String getGlobalDateString(ActionContext context) {
final String dateTagProperty = org.apache.struts2.components.Date.DATETAG_PROPERTY;
SimpleDateFormat globalDateFormat = null;
String globalDateString = null;
final TextProvider tp = findProviderInStack(context.getValueStack());
@@ -130,23 +168,28 @@ public class DateConverter extends DefaultTypeConverter {
// is the same as input = DATETAG_PROPERTY
if (globalFormat != null && !dateTagProperty.equals(globalFormat)) {
LOG.debug("Found \"{}\" as \"{}\"", dateTagProperty, globalFormat);
globalDateFormat = new SimpleDateFormat(globalFormat, locale);
globalDateString = globalFormat;
} else {
LOG.debug("\"{}\" has not been defined, ignoring it", dateTagProperty);
}
}
return globalDateFormat;
return globalDateString;
}
/**
* Retrieves the list of date formats to be used when converting dates
*
* @param context the current ActionContext
* @param locale the current locale of the action
* @param locale the current locale of the action
* @return a list of DateFormat to be used for date conversion
*/
private DateFormat[] getDateFormats(ActionContext context, Locale locale) {
DateFormat globalDateFormat = getGlobalDateFormat(context, locale);
DateFormat globalDateFormat = null;
String globalFormat = getGlobalDateString(context);
if (globalFormat != null) {
globalDateFormat = new SimpleDateFormat(globalFormat, locale);
}
DateFormat dt1 = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.LONG, locale);
DateFormat dt2 = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM, locale);
@@ -156,15 +199,46 @@ public class DateConverter extends DefaultTypeConverter {
DateFormat d2 = DateFormat.getDateInstance(DateFormat.MEDIUM, locale);
DateFormat d3 = DateFormat.getDateInstance(DateFormat.LONG, locale);
DateFormat rfc3339 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
DateFormat rfc3339 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
DateFormat rfc3339dateOnly = new SimpleDateFormat("yyyy-MM-dd");
final DateFormat[] dateFormats;
if (globalDateFormat == null) {
dateFormats = new DateFormat[]{dt1, dt2, dt3, rfc3339, d1, d2, d3, rfc3339dateOnly};
dateFormats = new DateFormat[] { dt1, dt2, dt3, rfc3339, d1, d2, d3, rfc3339dateOnly };
} else {
dateFormats = new DateFormat[]{globalDateFormat, dt1, dt2, dt3, rfc3339, d1, d2, d3, rfc3339dateOnly};
dateFormats = new DateFormat[] { globalDateFormat, dt1, dt2, dt3, rfc3339, d1, d2, d3, rfc3339dateOnly };
}
return dateFormats;
}
/**
* Retrieves the list of date time formats to be used when converting dates
*
* @param context the current ActionContext
* @param locale the current locale of the action
*
* @return a list of DateTimeFormatter to be used for date conversion
*/
protected DateTimeFormatter[] getDateTimeFormats(ActionContext context, Locale locale) {
DateTimeFormatter globalDateFormat = null;
String globalFormat = getGlobalDateString(context);
if (globalFormat != null) {
globalDateFormat = DateTimeFormatter.ofPattern(globalFormat, locale);
}
DateTimeFormatter df1 = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
DateTimeFormatter df2 = DateTimeFormatter.ISO_LOCAL_DATE;
DateTimeFormatter df3 = DateTimeFormatter.ISO_LOCAL_TIME;
final DateTimeFormatter[] dateFormats;
if (globalDateFormat == null) {
dateFormats = new DateTimeFormatter[] { df1, df2, df3 };
} else {
dateFormats = new DateTimeFormatter[] { globalDateFormat, df1, df2, df3 };
}
return dateFormats;
@@ -25,6 +25,7 @@ import com.opensymphony.xwork2.inject.Inject;
import org.apache.struts2.StrutsConstants;
import java.lang.reflect.Member;
import java.time.LocalDateTime;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
@@ -99,6 +100,8 @@ public class XWorkBasicConverter extends DefaultTypeConverter {
result = doConvertToArray(context, o, member, propertyName, value, toType);
} else if (Date.class.isAssignableFrom(toType)) {
result = doConvertToDate(context, value, toType);
} else if (LocalDateTime.class.isAssignableFrom(toType)) {
result = doConvertToDate(context, value, toType);
} else if (Calendar.class.isAssignableFrom(toType)) {
result = doConvertToCalendar(context, value);
} else if (Collection.class.isAssignableFrom(toType)) {
@@ -201,7 +201,7 @@ public class ParametersInterceptor extends MethodFilterInterceptor {
ReflectionContextState.setReportingConversionErrors(context, true);
//keep locale from original context
newStack.getActionContext().withLocale(stack.getActionContext().getLocale());
newStack.getActionContext().withLocale(stack.getActionContext().getLocale()).withValueStack(stack);
}
boolean memberAccessStack = newStack instanceof MemberAccessValueStack;
@@ -73,7 +73,6 @@ public class OgnlUtil {
private Container container;
private boolean allowStaticFieldAccess = true;
private boolean allowStaticMethodAccess;
private boolean disallowProxyMemberAccess;
/**
@@ -250,11 +249,6 @@ public class OgnlUtil {
this.allowStaticFieldAccess = BooleanUtils.toBoolean(allowStaticFieldAccess);
}
@Inject(value = StrutsConstants.STRUTS_ALLOW_STATIC_METHOD_ACCESS, required = false)
protected void setAllowStaticMethodAccess(String allowStaticMethodAccess) {
this.allowStaticMethodAccess = BooleanUtils.toBoolean(allowStaticMethodAccess);
}
@Inject(value = StrutsConstants.STRUTS_DISALLOW_PROXY_MEMBER_ACCESS, required = false)
protected void setDisallowProxyMemberAccess(String disallowProxyMemberAccess) {
this.disallowProxyMemberAccess = BooleanUtils.toBoolean(disallowProxyMemberAccess);
@@ -836,7 +830,7 @@ public class OgnlUtil {
resolver = container.getInstance(CompoundRootAccessor.class);
}
SecurityMemberAccess memberAccess = new SecurityMemberAccess(allowStaticMethodAccess, allowStaticFieldAccess);
SecurityMemberAccess memberAccess = new SecurityMemberAccess(allowStaticFieldAccess);
memberAccess.setDisallowProxyMemberAccess(disallowProxyMemberAccess);
if (devMode) {
@@ -72,13 +72,13 @@ public class OgnlValueStack implements Serializable, ValueStack, ClearableValueS
private boolean devMode;
private boolean logMissingProperties;
protected OgnlValueStack(XWorkConverter xworkConverter, CompoundRootAccessor accessor, TextProvider prov, boolean allowStaticMethodAccess, boolean allowStaticFieldAccess) {
setRoot(xworkConverter, accessor, new CompoundRoot(), allowStaticMethodAccess, allowStaticFieldAccess);
protected OgnlValueStack(XWorkConverter xworkConverter, CompoundRootAccessor accessor, TextProvider prov, boolean allowStaticFieldAccess) {
setRoot(xworkConverter, accessor, new CompoundRoot(), allowStaticFieldAccess);
push(prov);
}
protected OgnlValueStack(ValueStack vs, XWorkConverter xworkConverter, CompoundRootAccessor accessor, boolean allowStaticMethodAccess, boolean allowStaticFieldAccess) {
setRoot(xworkConverter, accessor, new CompoundRoot(vs.getRoot()), allowStaticMethodAccess, allowStaticFieldAccess);
protected OgnlValueStack(ValueStack vs, XWorkConverter xworkConverter, CompoundRootAccessor accessor, boolean allowStaticFieldAccess) {
setRoot(xworkConverter, accessor, new CompoundRoot(vs.getRoot()), allowStaticFieldAccess);
}
@Inject
@@ -90,10 +90,9 @@ public class OgnlValueStack implements Serializable, ValueStack, ClearableValueS
securityMemberAccess.setDisallowProxyMemberAccess(ognlUtil.isDisallowProxyMemberAccess());
}
protected void setRoot(XWorkConverter xworkConverter, CompoundRootAccessor accessor, CompoundRoot compoundRoot,
boolean allowStaticMethodAccess, boolean allowStaticFieldAccess) {
protected void setRoot(XWorkConverter xworkConverter, CompoundRootAccessor accessor, CompoundRoot compoundRoot, boolean allowStaticFieldAccess) {
this.root = compoundRoot;
this.securityMemberAccess = new SecurityMemberAccess(allowStaticMethodAccess, allowStaticFieldAccess);
this.securityMemberAccess = new SecurityMemberAccess(allowStaticFieldAccess);
this.context = Ognl.createDefaultContext(this.root, securityMemberAccess, accessor, new OgnlTypeConverterWrapper(xworkConverter));
context.put(VALUE_STACK, this);
((OgnlContext) context).setTraceEvaluations(false);
@@ -219,7 +218,7 @@ public class OgnlValueStack implements Serializable, ValueStack, ClearableValueS
if (shouldLog) {
LOG.warn(msg, e);
}
if (throwExceptionOnFailure) {
throw new StrutsException(msg, e);
}
@@ -462,11 +461,10 @@ public class OgnlValueStack implements Serializable, ValueStack, ClearableValueS
XWorkConverter xworkConverter = cont.getInstance(XWorkConverter.class);
CompoundRootAccessor accessor = (CompoundRootAccessor) cont.getInstance(PropertyAccessor.class, CompoundRoot.class.getName());
TextProvider prov = cont.getInstance(TextProvider.class, "system");
final boolean allowStaticMethod = BooleanUtils.toBoolean(cont.getInstance(String.class, StrutsConstants.STRUTS_ALLOW_STATIC_METHOD_ACCESS));
final boolean allowStaticField = BooleanUtils.toBoolean(cont.getInstance(String.class, StrutsConstants.STRUTS_ALLOW_STATIC_FIELD_ACCESS));
OgnlValueStack aStack = new OgnlValueStack(xworkConverter, accessor, prov, allowStaticMethod, allowStaticField);
OgnlValueStack aStack = new OgnlValueStack(xworkConverter, accessor, prov, allowStaticField);
aStack.setOgnlUtil(cont.getInstance(OgnlUtil.class));
aStack.setRoot(xworkConverter, accessor, this.root, allowStaticMethod, allowStaticField);
aStack.setRoot(xworkConverter, accessor, this.root, allowStaticField);
return aStack;
}
@@ -43,8 +43,6 @@ import java.util.Set;
*/
public class OgnlValueStackFactory implements ValueStackFactory {
private static final Logger LOG = LogManager.getLogger(OgnlValueStackFactory.class);
protected XWorkConverter xworkConverter;
protected CompoundRootAccessor compoundRootAccessor;
protected TextProvider textProvider;
@@ -61,8 +59,7 @@ public class OgnlValueStackFactory implements ValueStackFactory {
}
public ValueStack createValueStack() {
ValueStack stack = new OgnlValueStack(xworkConverter, compoundRootAccessor, textProvider,
containerAllowsStaticMethodAccess(), containerAllowsStaticFieldAccess());
ValueStack stack = new OgnlValueStack(xworkConverter, compoundRootAccessor, textProvider, containerAllowsStaticFieldAccess());
container.inject(stack);
return stack.getActionContext()
.withContainer(container)
@@ -71,8 +68,7 @@ public class OgnlValueStackFactory implements ValueStackFactory {
}
public ValueStack createValueStack(ValueStack stack) {
ValueStack result = new OgnlValueStack(stack, xworkConverter, compoundRootAccessor,
containerAllowsStaticMethodAccess(), containerAllowsStaticFieldAccess());
ValueStack result = new OgnlValueStack(stack, xworkConverter, compoundRootAccessor, containerAllowsStaticFieldAccess());
container.inject(result);
return result.getActionContext()
.withContainer(container)
@@ -84,32 +80,23 @@ public class OgnlValueStackFactory implements ValueStackFactory {
protected void setContainer(Container container) throws ClassNotFoundException {
Set<String> names = container.getInstanceNames(PropertyAccessor.class);
for (String name : names) {
Class cls = Class.forName(name);
if (cls != null) {
if (Map.class.isAssignableFrom(cls)) {
PropertyAccessor acc = container.getInstance(PropertyAccessor.class, name);
}
OgnlRuntime.setPropertyAccessor(cls, container.getInstance(PropertyAccessor.class, name));
if (compoundRootAccessor == null && CompoundRoot.class.isAssignableFrom(cls)) {
compoundRootAccessor = (CompoundRootAccessor) container.getInstance(PropertyAccessor.class, name);
}
Class<?> cls = Class.forName(name);
OgnlRuntime.setPropertyAccessor(cls, container.getInstance(PropertyAccessor.class, name));
if (compoundRootAccessor == null && CompoundRoot.class.isAssignableFrom(cls)) {
compoundRootAccessor = (CompoundRootAccessor) container.getInstance(PropertyAccessor.class, name);
}
}
names = container.getInstanceNames(MethodAccessor.class);
for (String name : names) {
Class cls = Class.forName(name);
if (cls != null) {
OgnlRuntime.setMethodAccessor(cls, container.getInstance(MethodAccessor.class, name));
}
Class<?> cls = Class.forName(name);
OgnlRuntime.setMethodAccessor(cls, container.getInstance(MethodAccessor.class, name));
}
names = container.getInstanceNames(NullHandler.class);
for (String name : names) {
Class cls = Class.forName(name);
if (cls != null) {
OgnlRuntime.setNullHandler(cls, new OgnlNullHandlerWrapper(container.getInstance(NullHandler.class, name)));
}
Class<?> cls = Class.forName(name);
OgnlRuntime.setNullHandler(cls, new OgnlNullHandlerWrapper(container.getInstance(NullHandler.class, name)));
}
if (compoundRootAccessor == null) {
throw new IllegalStateException("Couldn't find the compound root accessor");
@@ -117,19 +104,8 @@ public class OgnlValueStackFactory implements ValueStackFactory {
this.container = container;
}
/**
* Retrieve allowsStaticMethodAccess state from the container (allows for lazy fetching)
*
* @return
*/
protected boolean containerAllowsStaticMethodAccess() {
return BooleanUtils.toBoolean(container.getInstance(String.class, StrutsConstants.STRUTS_ALLOW_STATIC_METHOD_ACCESS));
}
/**
* Retrieve allowStaticFieldAccess state from the container (allows for lazy fetching)
*
* @return
*/
protected boolean containerAllowsStaticFieldAccess() {
return BooleanUtils.toBoolean(container.getInstance(String.class, StrutsConstants.STRUTS_ALLOW_STATIC_FIELD_ACCESS));
@@ -42,7 +42,6 @@ public class SecurityMemberAccess implements MemberAccess {
private static final Logger LOG = LogManager.getLogger(SecurityMemberAccess.class);
private final boolean allowStaticFieldAccess;
private final boolean allowStaticMethodAccess;
private Set<Pattern> excludeProperties = Collections.emptySet();
private Set<Pattern> acceptProperties = Collections.emptySet();
private Set<Class<?>> excludedClasses = Collections.emptySet();
@@ -52,25 +51,15 @@ public class SecurityMemberAccess implements MemberAccess {
/**
* SecurityMemberAccess
* - access decisions based on whether member is static (or not)
* - block or allow access to properties (configurable-after-construction)
*
* @param allowStaticMethodAccess
* @param allowStaticFieldAccess
* - access decisions based on whether member is static (or not)
* - block or allow access to properties (configurable-after-construction)
*
* @param allowStaticFieldAccess if set to true static fields (constants) will be accessible
*/
public SecurityMemberAccess(boolean allowStaticMethodAccess, boolean allowStaticFieldAccess) {
this.allowStaticMethodAccess = allowStaticMethodAccess;
public SecurityMemberAccess(boolean allowStaticFieldAccess) {
this.allowStaticFieldAccess = allowStaticFieldAccess;
}
public final boolean getAllowStaticMethodAccess() {
return allowStaticMethodAccess;
}
public final boolean getAllowStaticFieldAccess() {
return allowStaticFieldAccess;
}
@Override
public Object setup(Map context, Object target, Member member, String propertyName) {
Object result = null;
@@ -90,13 +79,12 @@ public class SecurityMemberAccess implements MemberAccess {
public void restore(Map context, Object target, Member member, String propertyName, Object state) {
if (state != null) {
final AccessibleObject accessible = (AccessibleObject) member;
final boolean stateboolean = ((Boolean) state).booleanValue(); // Using twice (avoid unboxing)
if (!stateboolean) {
accessible.setAccessible(stateboolean);
}
else {
throw new IllegalArgumentException("Improper restore state [" + stateboolean + "] for target [" + target +
"], member [" + member + "], propertyName [" + propertyName + "]");
final boolean stateBoolean = ((Boolean) state).booleanValue(); // Using twice (avoid unboxing)
if (!stateBoolean) {
accessible.setAccessible(stateBoolean);
} else {
throw new IllegalArgumentException("Improper restore state [" + stateBoolean + "] for target [" + target +
"], member [" + member + "], propertyName [" + propertyName + "]");
}
}
}
@@ -117,6 +105,7 @@ public class SecurityMemberAccess implements MemberAccess {
return false;
}
// it needs to be before calling #checkStaticMethodAccess()
if (checkEnumAccess(target, member)) {
LOG.trace("Allowing access to enum: target [{}], member [{}]", target, member);
return true;
@@ -127,7 +116,7 @@ public class SecurityMemberAccess implements MemberAccess {
return false;
}
final Class memberClass = member.getDeclaringClass();
final Class<?> memberClass = member.getDeclaringClass();
if (isClassExcluded(memberClass)) {
LOG.warn("Declaring class of member type [{}] is excluded!", member);
@@ -135,11 +124,11 @@ public class SecurityMemberAccess implements MemberAccess {
}
// target can be null in case of accessing static fields, since OGNL 3.2.8
final Class targetClass = Modifier.isStatic(memberModifiers) ? memberClass : target.getClass();
final Class<?> targetClass = Modifier.isStatic(memberModifiers) ? memberClass : target.getClass();
if (isPackageExcluded(targetClass.getPackage(), memberClass.getPackage())) {
LOG.warn("Package [{}] of target class [{}] of target [{}] or package [{}] of member [{}] are excluded!", targetClass.getPackage(), targetClass,
target, memberClass.getPackage(), member);
target, memberClass.getPackage(), member);
return false;
}
@@ -158,33 +147,25 @@ public class SecurityMemberAccess implements MemberAccess {
/**
* Check access for static method (via modifiers).
*
*
* Note: For non-static members, the result is always true.
*
*
* @param member
* @param memberModifiers
*
*
* @return
*/
protected boolean checkStaticMethodAccess(Member member, int memberModifiers) {
if (Modifier.isStatic(memberModifiers) && !(member instanceof Field)) {
if (allowStaticMethodAccess) {
LOG.debug("Support for accessing static methods [member: {}] is deprecated!", member);
}
return allowStaticMethodAccess;
} else {
return true;
}
return !Modifier.isStatic(memberModifiers) || member instanceof Field;
}
/**
* Check access for static field (via modifiers).
*
* <p>
* Note: For non-static members, the result is always true.
*
*
* @param member
* @param memberModifiers
*
* @return
*/
protected boolean checkStaticFieldAccess(Member member, int memberModifiers) {
@@ -195,13 +176,12 @@ public class SecurityMemberAccess implements MemberAccess {
}
}
/**
/**
* Check access for public members (via modifiers)
*
* <p>
* Returns true if-and-only-if the member is public.
*
*
* @param memberModifiers
*
* @return
*/
protected boolean checkPublicMemberAccess(int memberModifiers) {
@@ -210,10 +190,8 @@ public class SecurityMemberAccess implements MemberAccess {
protected boolean checkEnumAccess(Object target, Member member) {
if (target instanceof Class) {
final Class clazz = (Class) target;
if (Enum.class.isAssignableFrom(clazz) && member.getName().equals("values")) {
return true;
}
final Class<?> clazz = (Class<?>) target;
return Enum.class.isAssignableFrom(clazz) && member.getName().equals("values");
}
return false;
}
@@ -222,7 +200,7 @@ public class SecurityMemberAccess implements MemberAccess {
if (targetPackage == null || memberPackage == null) {
LOG.warn("The use of the default (unnamed) package is discouraged!");
}
String targetPackageName = targetPackage == null ? "" : targetPackage.getName();
String memberPackageName = memberPackage == null ? "" : memberPackage.getName();
@@ -235,7 +213,7 @@ public class SecurityMemberAccess implements MemberAccess {
targetPackageName = targetPackageName + ".";
memberPackageName = memberPackageName + ".";
for (String packageName: excludedPackageNames) {
for (String packageName : excludedPackageNames) {
if (targetPackageName.startsWith(packageName) || memberPackageName.startsWith(packageName)) {
return true;
}
@@ -245,7 +223,7 @@ public class SecurityMemberAccess implements MemberAccess {
}
protected boolean isClassExcluded(Class<?> clazz) {
if (clazz == Object.class || (clazz == Class.class && !allowStaticMethodAccess)) {
if (clazz == Object.class || (clazz == Class.class && !allowStaticFieldAccess)) {
return true;
}
for (Class<?> excludedClass : excludedClasses) {
@@ -36,7 +36,7 @@ import java.util.Map;
* @author tmjee
*/
public class XWorkMethodAccessor extends ObjectMethodAccessor {
private static final Logger LOG = LogManager.getLogger(XWorkMethodAccessor.class);
@Override
@@ -58,9 +58,9 @@ public class XWorkMethodAccessor extends ObjectMethodAccessor {
//so that property strings are not cleared
//i.e. OgnlUtil should be used initially, OgnlRuntime
//thereafter
Object propVal=OgnlRuntime.getProperty(ogContext, object, string);
//use the Collection property accessor instead of the individual property accessor, because
//use the Collection property accessor instead of the individual property accessor, because
//in the case of Lists otherwise the index property could be used
PropertyAccessor accessor=OgnlRuntime.getPropertyAccessor(Collection.class);
ReflectionContextState.setGettingByKeyProperty(ogContext,true);
@@ -83,8 +83,8 @@ public class XWorkMethodAccessor extends ObjectMethodAccessor {
return callMethodWithDebugInfo(context, object, string, objects);
}
}
Boolean exec = (Boolean) context.get(ReflectionContextState.DENY_METHOD_EXECUTION);
boolean e = ((exec == null) ? false : exec.booleanValue());
Boolean exec = ReflectionContextState.isDenyMethodExecution(context);
boolean e = (exec != null && exec);
if (!e) {
return callMethodWithDebugInfo(context, object, string, objects);
@@ -110,7 +110,7 @@ public class XWorkMethodAccessor extends ObjectMethodAccessor {
@Override
public Object callStaticMethod(Map context, Class aClass, String string, Object[] objects) throws MethodFailedException {
Boolean exec = (Boolean) context.get(ReflectionContextState.DENY_METHOD_EXECUTION);
Boolean exec = ReflectionContextState.isDenyMethodExecution(context);
boolean e = ((exec == null) ? false : exec.booleanValue());
if (!e) {
@@ -226,9 +226,6 @@ public final class StrutsConstants {
/** The name of the parameter to determine whether static field access will be allowed in OGNL expressions or not */
public static final String STRUTS_ALLOW_STATIC_FIELD_ACCESS = "struts.ognl.allowStaticFieldAccess";
/** The name of the parameter to determine whether static method access will be allowed in OGNL expressions or not */
public static final String STRUTS_ALLOW_STATIC_METHOD_ACCESS = "struts.ognl.allowStaticMethodAccess";
/** The com.opensymphony.xwork2.validator.ActionValidatorManager implementation class */
public static final String STRUTS_ACTIONVALIDATORMANAGER = "struts.actionValidatorManager";
@@ -25,6 +25,7 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.struts2.RequestUtils;
import org.apache.struts2.StrutsConstants;
import org.apache.struts2.StrutsException;
import org.apache.struts2.util.FastByteArrayOutputStream;
import org.apache.struts2.views.annotations.StrutsTag;
import org.apache.struts2.views.annotations.StrutsTagAttribute;
@@ -33,6 +34,7 @@ import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
@@ -296,6 +298,19 @@ public class Include extends Component {
buffer = new FastByteArrayOutputStream();
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setWriteListener(WriteListener writeListener) {
try {
writeListener.onWritePossible();
} catch (IOException e) {
throw new StrutsException(e);
}
}
/**
* Return all data that has been written to this OutputStream.
@@ -321,7 +321,7 @@ public class ServletUrlRenderer implements UrlRenderer {
* @param parameters component parameters
* @param contextParameters request parameters
*/
protected void mergeRequestParameters(String value, Map<String, Object> parameters, Map<String, Object> contextParameters) {
protected void mergeRequestParameters(String value, Map<String, Object> parameters, Map<String, ?> contextParameters) {
Map<String, Object> mergedParams = new LinkedHashMap<>(contextParameters);
@@ -333,7 +333,7 @@ public class ServletUrlRenderer implements UrlRenderer {
String queryString = value.substring(value.indexOf('?') + 1);
mergedParams = urlHelper.parseQueryString(queryString, false);
for (Map.Entry<String, Object> entry : contextParameters.entrySet()) {
for (Map.Entry<String, ?> entry : contextParameters.entrySet()) {
if (!mergedParams.containsKey(entry.getKey())) {
mergedParams.put(entry.getKey(), entry.getValue());
}
@@ -90,7 +90,6 @@ public class ConstantConfig {
private BeanConfig localeProviderFactory;
private String mapperIdParameterName;
private Boolean ognlAllowStaticFieldAccess;
private Boolean ognlAllowStaticMethodAccess;
private BeanConfig actionValidatorManager;
private BeanConfig valueStackFactory;
private BeanConfig reflectionProvider;
@@ -222,7 +221,6 @@ public class ConstantConfig {
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));
map.put(StrutsConstants.STRUTS_REFLECTIONPROVIDER, beanConfToString(reflectionProvider));
@@ -810,14 +808,6 @@ public class ConstantConfig {
this.ognlAllowStaticFieldAccess = ognlAllowStaticFieldAccess;
}
public Boolean getOgnlAllowStaticMethodAccess() {
return ognlAllowStaticMethodAccess;
}
public void setOgnlAllowStaticMethodAccess(Boolean ognlAllowStaticMethodAccess) {
this.ognlAllowStaticMethodAccess = ognlAllowStaticMethodAccess;
}
public BeanConfig getActionValidatorManager() {
return actionValidatorManager;
}
@@ -1,91 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts2.util;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* A bean that can be used to format dates
*
* FIXME: remove or use to format Dates
*/
public class DateFormatter {
Date date;
DateFormat format;
// Attributes ----------------------------------------------------
DateFormat parser;
// Public --------------------------------------------------------
public DateFormatter() {
this.parser = new SimpleDateFormat();
this.format = new SimpleDateFormat();
this.date = new Date();
}
public void setDate(String date) {
try {
this.date = parser.parse(date);
} catch (ParseException e) {
throw new IllegalArgumentException(e.getMessage());
}
}
public void setDate(Date date) {
this.date = (date == null) ? null : (Date)date.clone();
}
public void setDate(int date) {
setDate(Integer.toString(date));
}
public Date getDate() {
return this.date;
}
public void setFormat(String format) {
this.format = new SimpleDateFormat(format);
}
public void setFormat(DateFormat format) {
this.format = format;
}
public String getFormattedDate() {
return format.format(date);
}
public void setParseFormat(String format) {
this.parser = new SimpleDateFormat(format);
}
public void setParser(DateFormat parser) {
this.parser = parser;
}
public void setTime(long time) {
date.setTime(time);
}
}
@@ -24,11 +24,13 @@ import com.opensymphony.xwork2.util.TextParseUtil;
import com.opensymphony.xwork2.util.ValueStack;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.struts2.StrutsException;
import org.apache.struts2.views.jsp.ui.OgnlTool;
import org.apache.struts2.views.util.UrlHelper;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
@@ -278,6 +280,20 @@ public class StrutsUtil {
public void write(int aByte) {
writer.write(aByte);
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setWriteListener(WriteListener writeListener) {
try {
writeListener.onWritePossible();
} catch (IOException e) {
throw new StrutsException(e);
}
}
}
}
@@ -19,7 +19,6 @@
package org.apache.struts2.util;
import com.opensymphony.xwork2.ActionContext;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.views.util.DefaultUrlHelper;
import org.apache.struts2.views.util.UrlHelper;
@@ -58,20 +57,10 @@ public class URLBean {
public String getURL() {
// all this trickier with maps is to reduce the number of objects created
Map<String, Object> fullParams = null;
if (params != null) {
fullParams = new HashMap<String, Object>();
}
Map<String, Object> fullParams = new HashMap<>();
if (page == null) {
// No particular page requested, so go to "same page"
// Add query params to parameters
if (fullParams != null) {
fullParams.putAll(request.getParameterMap());
} else {
fullParams = request.getParameterMap();
}
fullParams.putAll(request.getParameterMap());
}
// added parameters override, just like in URLTag
@@ -84,7 +73,7 @@ public class URLBean {
public URLBean addParameter(String name, Object value) {
if (params == null) {
params = new HashMap<String, String>();
params = new HashMap<>();
}
if (value == null) {
@@ -266,13 +266,12 @@ struts.handle.exception=true
### Applies maximum length allowed on OGNL expressions for security enhancement (optional)
###
### **WARNING**: If developers enable this option (by configuration) they should make sure that they understand the implications of setting
### struts.ognl.expressionMaxLength. They must choose a value large enough to permit ALL valid OGNL expressions used within the application.
### Values larger than the 200-400 range have diminishing security value (at which point it is really only a "style guard" for long OGNL
### expressions in an application. Setting a value of null or "" will also disable the feature.
###
### NOTE: The sample line below is *INTENTIONALLY* commented out, as this feature is disabled by default.
# struts.ognl.expressionMaxLength=256
### **WARNING**: If developers change this option (by configuration) they should make sure that they understand
### the implications of setting 'struts.ognl.expressionMaxLength'. They must choose a value large enough to permit
### ALL valid OGNL expressions used within the application. Values larger than the 200-400 range have diminishing
### security value (at which point it is really only a "style guard" for long OGNL expressions in an application.
### Setting a value of null or "" will also disable the feature.
struts.ognl.expressionMaxLength=256
### Defines which named instance of DateFormatter to use, there are two instances:
### - simpleDateFormatter (based on SimpleDateFormat)
@@ -28,6 +28,9 @@ import org.apache.struts2.conversion.TypeConversionException;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
@@ -43,14 +46,20 @@ public class DateConverterTest extends StrutsInternalTestCase {
private final static String DATE_STR = "2020-03-20";
private final static String DATE_CONVERTED = "Fri Mar 20 00:00:00";
private final static String INVALID_DATE = "99/99/2010";
private final static String LOCALDATETIME_STR = "2020-03-20T00:00:00.000000";
private final static String LOCALDATETIME1_STR = "12:00 AM Fri Mar 20, 2020";
private final static String LOCALDATETIME_CONVERTED = "2020-03-20T00:00";
private final static String LOCALDATE_STR = "2020-03-20";
private final static String LOCALTIME_STR = "01:59:10";
private final static String INVALID_LOCALDATETIME = "2010-99-99T00:00";
private final static String MESSAGE_PARSE_ERROR = "Could not parse date";
private final static String MESSAGE_DEFAULT_CONSTRUCTOR_ERROR = "Couldn't create class null using default (long) constructor";
public void testSqlTimeType() {
DateConverter converter = new DateConverter();
ActionContext context = ActionContext.of(new HashMap<>())
.withLocale(mxLocale);
ActionContext context = ActionContext.of(new HashMap<>()).withLocale(mxLocale);
Object value = converter.convertValue(context.getContextMap(), null, null, null, TIME_01_59_10, Time.class);
assertEquals("01:59:10", value.toString());
@@ -59,10 +68,10 @@ public class DateConverterTest extends StrutsInternalTestCase {
public void testSqlTimestampType() {
DateConverter converter = new DateConverter();
ActionContext context = ActionContext.of(new HashMap<>())
.withLocale(mxLocale);
ActionContext context = ActionContext.of(new HashMap<>()).withLocale(mxLocale);
Object value = converter.convertValue(context.getContextMap(), null, null, null, INPUT_TIME_STAMP_STR, Timestamp.class);
Object value = converter.convertValue(context.getContextMap(), null, null, null, INPUT_TIME_STAMP_STR,
Timestamp.class);
assertEquals(RES_TIME_STAMP_STR, value.toString());
}
@@ -74,9 +83,8 @@ public class DateConverterTest extends StrutsInternalTestCase {
ValueStack stack = new StubValueStack();
stack.push(new StubTextProvider(map));
ActionContext context = ActionContext.of(new HashMap<>())
.withLocale(new Locale("es_MX", "MX"))
.withValueStack(stack);
ActionContext context = ActionContext.of(new HashMap<>()).withLocale(new Locale("es_MX", "MX"))
.withValueStack(stack);
Object value = converter.convertValue(context.getContextMap(), null, null, null, DATE_STR, Date.class);
assertTrue(value.toString().startsWith(DATE_CONVERTED));
@@ -90,9 +98,8 @@ public class DateConverterTest extends StrutsInternalTestCase {
ValueStack stack = new StubValueStack();
stack.push(new StubTextProvider(map));
ActionContext context = ActionContext.of(new HashMap<>())
.withLocale(new Locale("es_MX", "MX"))
.withValueStack(stack);
ActionContext context = ActionContext.of(new HashMap<>()).withLocale(new Locale("es_MX", "MX"))
.withValueStack(stack);
try {
converter.convertValue(context.getContextMap(), null, null, null, INVALID_DATE, Date.class);
@@ -106,8 +113,7 @@ public class DateConverterTest extends StrutsInternalTestCase {
public void testTypeConversionExceptionWhenUsingLongConstructor() {
DateConverter converter = new DateConverter();
ActionContext context = ActionContext.of(new HashMap<>())
.withLocale(mxLocale);
ActionContext context = ActionContext.of(new HashMap<>()).withLocale(mxLocale);
try {
converter.convertValue(context.getContextMap(), null, null, null, INPUT_WHEN_LONG_CONSTRUCTOR_STR, null);
@@ -118,12 +124,73 @@ public class DateConverterTest extends StrutsInternalTestCase {
}
}
public void testLocalDateTimeType() {
DateConverter converter = new DateConverter();
ActionContext context = ActionContext.of(new HashMap<>());
Object value = converter.convertValue(context.getContextMap(), null, null, null, LOCALDATETIME_STR,
LocalDateTime.class);
assertTrue(value.toString().startsWith(LOCALDATETIME_CONVERTED));
}
public void testLocalDateTime1Type() {
DateConverter converter = new DateConverter();
Map<String, String> map = new HashMap<>();
map.put(org.apache.struts2.components.Date.DATETAG_PROPERTY, "hh:mm a EEE MMM dd, yyyy");
ValueStack stack = new StubValueStack();
stack.push(new StubTextProvider(map));
ActionContext context = ActionContext.of(new HashMap<>()).withLocale(mxLocale)
.withValueStack(stack);
Object value = converter.convertValue(context.getContextMap(), null, null, null, LOCALDATETIME1_STR,
LocalDateTime.class);
assertTrue(value.toString().startsWith(LOCALDATETIME_CONVERTED));
}
public void testLocalDateTimeTypeConversionExceptionWhenParseError() {
DateConverter converter = new DateConverter();
ActionContext context = ActionContext.of(new HashMap<>());
try {
converter.convertValue(context.getContextMap(), null, null, null, INVALID_LOCALDATETIME,
LocalDateTime.class);
fail("TypeConversionException expected - Conversion error occurred");
} catch (Exception ex) {
assertEquals(TypeConversionException.class, ex.getClass());
assertEquals(MESSAGE_PARSE_ERROR, ex.getMessage());
}
}
public void testLocalDateType() {
DateConverter converter = new DateConverter();
ActionContext context = ActionContext.of(new HashMap<>());
Object value = converter.convertValue(context.getContextMap(), null, null, null, LOCALDATE_STR,
LocalDate.class);
assertTrue(value.toString().startsWith(LOCALDATE_STR));
}
public void testLocalTimeType() {
DateConverter converter = new DateConverter();
ActionContext context = ActionContext.of(new HashMap<>());
Object value = converter.convertValue(context.getContextMap(), null, null, null, LOCALTIME_STR,
LocalTime.class);
assertTrue(value.toString().startsWith(LOCALTIME_STR));
}
@Override
protected void setUp() throws Exception {
super.setUp();
//Due to JEP 252: Use CLDR Locale Data by Default
// Due to JEP 252: Use CLDR Locale Data by Default
DateFormat dFormat = DateFormat.getDateInstance(DateFormat.SHORT, mxLocale);
if (dFormat.format(new Date()).contains("-")) { // Format when Java 9 or greater
if (dFormat.format(new Date()).contains("-")) { // Format when Java 9 or greater
INPUT_TIME_STAMP_STR = "2020-03-20 00:00:00.000";
INPUT_WHEN_LONG_CONSTRUCTOR_STR = "2020-03-20";
} else {// Format when Java 8 or lower
@@ -39,13 +39,17 @@ import com.opensymphony.xwork2.ognl.accessor.CompoundRootAccessor;
import com.opensymphony.xwork2.util.CompoundRoot;
import com.opensymphony.xwork2.util.ValueStack;
import com.opensymphony.xwork2.util.ValueStackFactory;
import com.opensymphony.xwork2.util.reflection.ReflectionContextState;
import ognl.OgnlContext;
import ognl.PropertyAccessor;
import org.apache.struts2.config.StrutsXmlConfigurationProvider;
import org.apache.struts2.dispatcher.HttpParameters;
import org.junit.Assert;
import org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -335,8 +339,8 @@ public class ParametersInterceptorTest extends XWorkTestCase {
// given
Map<String, Object> params = new HashMap<>();
params.put("blah", "This is blah");
params.put("('\\u0023_memberAccess[\\'allowStaticMethodAccess\\']')(meh)", "true");
params.put("('(aaa)(('\\u0023context[\\'xwork.MethodAccessor.denyMethodExecution\\']\\u003d\\u0023foo')(\\u0023foo\\u003dnew java.lang.Boolean(\"false\")))", "");
params.put("('\\u0023_memberAccess[\\'allowStaticFieldAccess\\']')(meh)", "true");
params.put("('(aaa)(('\\u0023context[\\'xwork.MethodAccessor.denyMethodExecution\\']\\u003d\\u0023foo')(\\u0023foo\\u003dnew java.lang.Boolean(\"true\")))", "");
params.put("(asdf)(('\\u0023rt.exit(1)')(\\u0023rt\\u003d@java.lang.Runtime@getRuntime()))", "1");
HashMap<String, Object> extraContext = new HashMap<>();
@@ -351,8 +355,9 @@ public class ParametersInterceptorTest extends XWorkTestCase {
//then
assertEquals("This is blah", ((SimpleAction) proxy.getAction()).getBlah());
boolean allowMethodAccess = ((SecurityMemberAccess) ((OgnlContext) stack.getContext()).getMemberAccess()).getAllowStaticMethodAccess();
assertFalse(allowMethodAccess);
Field field = ReflectionContextState.class.getField("DENY_METHOD_EXECUTION");
boolean allowStaticFieldAccess = ((OgnlContext) stack.getContext()).getMemberAccess().isAccessible(stack.getContext(), proxy.getAction(), field, "");
assertFalse(allowStaticFieldAccess);
}
public void testParameters() throws Exception {
@@ -806,7 +811,7 @@ public class ParametersInterceptorTest extends XWorkTestCase {
ValueStack stack = new OgnlValueStack(
container.getInstance(XWorkConverter.class),
(CompoundRootAccessor) container.getInstance(PropertyAccessor.class, CompoundRoot.class.getName()),
container.getInstance(TextProvider.class, "system"), true, true) {
container.getInstance(TextProvider.class, "system"), true) {
@Override
public void setValue(String expr, Object value) {
actual.put(expr, value);
@@ -1900,13 +1900,13 @@ public class OgnlUtilTest extends XWorkTestCase {
return result;
}
private void reloadTestContainerConfiguration(boolean devMode, boolean allowStaticMethod) {
private void reloadTestContainerConfiguration(boolean devMode, boolean allowStaticFieldAccess) {
loadConfigurationProviders(new StubConfigurationProvider() {
@Override
public void register(ContainerBuilder builder,
LocatableProperties props) throws ConfigurationException {
props.setProperty(StrutsConstants.STRUTS_DEVMODE, "" + devMode);
props.setProperty(StrutsConstants.STRUTS_ALLOW_STATIC_METHOD_ACCESS, "" + allowStaticMethod);
props.setProperty(StrutsConstants.STRUTS_ALLOW_STATIC_FIELD_ACCESS, "" + allowStaticFieldAccess);
}
});
ognlUtil = container.getInstance(OgnlUtil.class);
@@ -18,7 +18,10 @@
*/
package com.opensymphony.xwork2.ognl;
import com.opensymphony.xwork2.*;
import com.opensymphony.xwork2.SimpleAction;
import com.opensymphony.xwork2.TestBean;
import com.opensymphony.xwork2.TextProvider;
import com.opensymphony.xwork2.XWorkTestCase;
import com.opensymphony.xwork2.config.ConfigurationException;
import com.opensymphony.xwork2.conversion.impl.ConversionData;
import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
@@ -26,22 +29,17 @@ 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.Bar;
import com.opensymphony.xwork2.util.BarJunior;
import com.opensymphony.xwork2.util.Cat;
import com.opensymphony.xwork2.util.CompoundRoot;
import com.opensymphony.xwork2.util.Dog;
import com.opensymphony.xwork2.util.Foo;
import com.opensymphony.xwork2.util.ValueStackFactory;
import com.opensymphony.xwork2.util.location.LocatableProperties;
import com.opensymphony.xwork2.util.reflection.ReflectionContextState;
import ognl.OgnlException;
import ognl.PropertyAccessor;
import java.io.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import ognl.ParseException;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.LogEvent;
@@ -51,10 +49,18 @@ import org.apache.struts2.StrutsConstants;
import org.apache.struts2.StrutsException;
import org.apache.struts2.config.DefaultPropertiesProvider;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* Unit test for OgnlValueStack.
*/
public class OgnlValueStackTest extends XWorkTestCase {
// Fields for static field access test
@@ -85,16 +91,15 @@ public class OgnlValueStackTest extends XWorkTestCase {
}
private OgnlValueStack createValueStack() {
return createValueStack(true, true);
return createValueStack(true);
}
private OgnlValueStack createValueStack(boolean allowStaticMethodAccess, boolean allowStaticFieldAccess) {
private OgnlValueStack createValueStack(boolean allowStaticFieldAccess) {
OgnlValueStack stack = new OgnlValueStack(
container.getInstance(XWorkConverter.class),
(CompoundRootAccessor) container.getInstance(PropertyAccessor.class, CompoundRoot.class.getName()),
container.getInstance(TextProvider.class, "system"), allowStaticMethodAccess, allowStaticFieldAccess);
container.getInstance(XWorkConverter.class),
(CompoundRootAccessor) container.getInstance(PropertyAccessor.class, CompoundRoot.class.getName()),
container.getInstance(TextProvider.class, "system"), allowStaticFieldAccess);
container.inject(stack);
ognlUtil.setAllowStaticMethodAccess(Boolean.toString(allowStaticMethodAccess));
ognlUtil.setAllowStaticFieldAccess(Boolean.toString(allowStaticFieldAccess));
return stack;
}
@@ -111,16 +116,14 @@ public class OgnlValueStackTest extends XWorkTestCase {
* 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) {
private OgnlValueStackFactory reloadValueStackFactory(Boolean allowStaticField) {
try {
reloadTestContainerConfiguration(allowStaticMethod, allowStaticField);
}
catch (Exception ex) {
reloadTestContainerConfiguration(allowStaticField);
} catch (Exception ex) {
fail("Unable to reload container configuration and configure ognlValueStackFactory - exception: " + ex);
}
@@ -210,7 +213,7 @@ public class OgnlValueStackTest extends XWorkTestCase {
vs.findValue("barJunior.title", true);
}
public void testSuccessFailOnErrorOnInheritedPropertiesWithMethods() {
public void testSuccessFailOnErrorOnInheritedPropertiesWithMethods() {
//this shuld not fail as the property is defined on a parent class
OgnlValueStack vs = createValueStack();
@@ -254,6 +257,7 @@ public class OgnlValueStackTest extends XWorkTestCase {
/**
* monitors the resolution of WW-4999
*
* @since 2.5.21
*/
public void testLogMissingProperties() {
@@ -281,11 +285,11 @@ public class OgnlValueStackTest extends XWorkTestCase {
if (logMissingProperties) {
assertEquals(3, testAppender.logEvents.size());
assertEquals("Error setting value [missingProp1Value] with expression [missingProp1]",
testAppender.logEvents.get(0).getMessage().getFormattedMessage());
testAppender.logEvents.get(0).getMessage().getFormattedMessage());
assertEquals("Could not find property [missingProp2]!",
testAppender.logEvents.get(1).getMessage().getFormattedMessage());
testAppender.logEvents.get(1).getMessage().getFormattedMessage());
assertEquals("Could not find property [missingProp3]!",
testAppender.logEvents.get(2).getMessage().getFormattedMessage());
testAppender.logEvents.get(2).getMessage().getFormattedMessage());
} else {
assertEquals(0, testAppender.logEvents.size());
}
@@ -297,6 +301,7 @@ public class OgnlValueStackTest extends XWorkTestCase {
/**
* tests the correctness of distinguishing between user exception and NoSuchMethodException
*
* @since 2.5.21
*/
public void testNotLogUserExceptionsAsMissingProperties() {
@@ -364,7 +369,7 @@ public class OgnlValueStackTest extends XWorkTestCase {
}
});
Integer repeat = Integer.parseInt(
container.getInstance(String.class, StrutsConstants.STRUTS_OGNL_EXPRESSION_MAX_LENGTH));
container.getInstance(String.class, StrutsConstants.STRUTS_OGNL_EXPRESSION_MAX_LENGTH));
OgnlValueStack vs = createValueStack();
try {
@@ -383,65 +388,40 @@ public class OgnlValueStackTest extends XWorkTestCase {
public void testNotFailOnTooLongExpressionWithDefaultProperties() {
loadConfigurationProviders(new DefaultPropertiesProvider());
Object defaultMaxLengthFromConfiguration = container.getInstance(String.class, StrutsConstants.STRUTS_OGNL_EXPRESSION_MAX_LENGTH);
if (defaultMaxLengthFromConfiguration != null) {
assertTrue("non-null defaultMaxLengthFromConfiguration not a String ?", defaultMaxLengthFromConfiguration instanceof String);
assertTrue("non-null defaultMaxLengthFromConfiguration not empty string by default ?", ((String) defaultMaxLengthFromConfiguration).length() == 0);
} else {
assertNull("defaultMaxLengthFromConfiguration not null ?", defaultMaxLengthFromConfiguration);
}
// Original test logic was to confirm failure of exceeding the default value. Now the feature should be disabled by default,
// so this test's expectations are now changed.
Integer repeat = Integer.valueOf(256); // Since maxlength is disabled by default, just choose an arbitrary value for test
String defaultMaxLengthFromConfiguration = container.getInstance(String.class, StrutsConstants.STRUTS_OGNL_EXPRESSION_MAX_LENGTH);
assertNotNull(defaultMaxLengthFromConfiguration);
int defaultValue = 256;
OgnlValueStack vs = createValueStack();
try {
vs.findValue(StringUtils.repeat('.', repeat + 1), true);
vs.findValue(StringUtils.repeat('.', defaultValue + 1), true);
fail("findValue did not throw any exception (should either fail as invalid expression syntax or security exception) ?");
} catch (Exception ex) {
// If STRUTS_OGNL_EXPRESSION_MAX_LENGTH feature is disabled (default), the parse should fail due to a reason of invalid expression syntax
// with ParseException. Previously when it was enabled the reason for the failure would have been SecurityException.
assertTrue(ex.getCause() instanceof OgnlException);
assertTrue(((OgnlException) ex.getCause()).getReason() instanceof ParseException);
assertTrue(((OgnlException) ex.getCause()).getReason() instanceof SecurityException);
assertTrue(((OgnlException) ex.getCause()).getReason().getMessage().startsWith("This expression exceeded maximum allowed length"));
}
}
public void testNotFailOnTooLongValueWithDefaultProperties() {
try {
loadConfigurationProviders(new DefaultPropertiesProvider());
loadConfigurationProviders(new DefaultPropertiesProvider());
Object defaultMaxLengthFromConfiguration = container.getInstance(String.class, StrutsConstants.STRUTS_OGNL_EXPRESSION_MAX_LENGTH);
if (defaultMaxLengthFromConfiguration != null) {
assertTrue("non-null defaultMaxLengthFromConfiguration not a String ?", defaultMaxLengthFromConfiguration instanceof String);
assertTrue("non-null defaultMaxLengthFromConfiguration not empty string by default ?", ((String) defaultMaxLengthFromConfiguration).length() == 0);
} else {
assertNull("defaultMaxLengthFromConfiguration not null ?", defaultMaxLengthFromConfiguration);
}
// Original test logic is unchanged (testing that values can be larger than maximum expression length), but since the feature is disabled by
// default we will now have to enable it with an arbitrary value, test, and reset it to disabled.
Integer repeat = Integer.valueOf(256); // Since maxlength is disabled by default, just choose an arbitrary value for test
Object defaultMaxLengthFromConfiguration = container.getInstance(String.class, StrutsConstants.STRUTS_OGNL_EXPRESSION_MAX_LENGTH);
assertNotNull(defaultMaxLengthFromConfiguration);
// Apply a non-default value for expressionMaxLength (as it should be disabled by default)
try {
ognlUtil.applyExpressionMaxLength(repeat.toString());
} catch (Exception ex) {
fail ("applyExpressionMaxLength did not accept maxlength string " + repeat.toString() + " ?");
}
int defaultValue = 256;
OgnlValueStack vs = createValueStack();
OgnlValueStack vs = createValueStack();
Dog dog = new Dog();
vs.push(dog);
Dog dog = new Dog();
vs.push(dog);
String value = StringUtils.repeat('.', repeat + 1);
String value = StringUtils.repeat('.', defaultValue);
vs.setValue("name", value);
vs.setValue("name", value);
assertEquals(value, dog.getName());
} finally {
// Reset expressionMaxLength value to default (disabled)
ognlUtil.applyExpressionMaxLength(null);
}
assertEquals(value, dog.getName());
}
public void testFailsOnMethodThatThrowsException() {
@@ -502,7 +482,7 @@ public class OgnlValueStackTest extends XWorkTestCase {
Dog dog = new Dog();
dog.setDeity("fido");
vs.push(dog);
assertEquals("fido", vs.findValue("@com.opensymphony.xwork2.util.Dog@getDeity()", String.class));
assertNull(vs.findValue("@com.opensymphony.xwork2.util.Dog@getDeity()", String.class));
}
/**
@@ -517,7 +497,7 @@ public class OgnlValueStackTest extends XWorkTestCase {
}
public void testStaticMethodDisallow() {
OgnlValueStack vs = createValueStack(false, true);
OgnlValueStack vs = createValueStack(true);
Dog dog = new Dog();
dog.setDeity("fido");
@@ -845,8 +825,7 @@ public class OgnlValueStackTest extends XWorkTestCase {
try {
stack.setValue("bar", "3x");
fail("Attempt to set 'bar' int property to '3x' should result in RuntimeException");
}
catch (RuntimeException re) {
} catch (RuntimeException re) {
assertTrue(true);
}
@@ -1082,6 +1061,7 @@ public class OgnlValueStackTest extends XWorkTestCase {
/**
* Fails on 2.5.20 and earlier - tested on 2.5 (5/5/2016) and failed
*
* @since 2.5.21
*/
public void testNotThrowExceptionOnTopMissingProperty() {
@@ -1104,6 +1084,7 @@ public class OgnlValueStackTest extends XWorkTestCase {
/**
* Fails on 2.5.20 and earlier - tested on 2.5 (5/5/2016) and failed
*
* @since 2.5.21
*/
public void testNotSkipUserReturnedNullValues() {
@@ -1187,8 +1168,8 @@ public class OgnlValueStackTest extends XWorkTestCase {
stack.push("Hello World");
OgnlValueStack stack2 = new OgnlValueStack(stack,
container.getInstance(XWorkConverter.class),
(CompoundRootAccessor) container.getInstance(PropertyAccessor.class, CompoundRoot.class.getName()), true, true);
container.getInstance(XWorkConverter.class),
(CompoundRootAccessor) container.getInstance(PropertyAccessor.class, CompoundRoot.class.getName()), true);
container.inject(stack2);
assertEquals(stack.getRoot(), stack2.getRoot());
@@ -1260,7 +1241,7 @@ public class OgnlValueStackTest extends XWorkTestCase {
assertNull(stack.findValue("address.country.name", String.class));
}
/**
/**
* Test a default OgnlValueStackFactory and OgnlValueStack generated by it
* when a default configuration is used.
*/
@@ -1271,7 +1252,6 @@ public class OgnlValueStackTest extends XWorkTestCase {
// 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.
@@ -1300,7 +1280,7 @@ public class OgnlValueStackTest extends XWorkTestCase {
* when no static access flags are set (not present in configuration).
*/
public void testOgnlValueStackFromOgnlValueStackFactoryNoFlagsSet() {
OgnlValueStackFactory ognlValueStackFactory = reloadValueStackFactory(null, null);
OgnlValueStackFactory ognlValueStackFactory = reloadValueStackFactory(null);
OgnlValueStack ognlValueStack = (OgnlValueStack) ognlValueStackFactory.createValueStack();
Object accessedValue;
@@ -1309,7 +1289,6 @@ public class OgnlValueStackTest extends XWorkTestCase {
// 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.
@@ -1335,16 +1314,15 @@ public class OgnlValueStackTest extends XWorkTestCase {
/**
* Test a raw OgnlValueStackFactory and OgnlValueStack generated by it
* when both static access flags are set to false.
* when static access flag is set to false.
*/
public void testOgnlValueStackFromOgnlValueStackFactoryNoStaticAccess() {
OgnlValueStackFactory ognlValueStackFactory = reloadValueStackFactory(false, false);
OgnlValueStackFactory ognlValueStackFactory = reloadValueStackFactory(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.
@@ -1370,22 +1348,20 @@ public class OgnlValueStackTest extends XWorkTestCase {
/**
* Test a raw OgnlValueStackFactory and OgnlValueStack generated by it
* when both static access flags are set to true.
* when static access flag is set to true.
*/
public void testOgnlValueStackFromOgnlValueStackFactoryAllStaticAccess() {
OgnlValueStackFactory ognlValueStackFactory = reloadValueStackFactory(true, true);
OgnlValueStackFactory ognlValueStackFactory = reloadValueStackFactory(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());
assertNull("able to access static method (result non-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");
@@ -1404,93 +1380,14 @@ public class OgnlValueStackTest extends XWorkTestCase {
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 {
private void reloadTestContainerConfiguration(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);
}
props.remove(StrutsConstants.STRUTS_ALLOW_STATIC_FIELD_ACCESS);
if (allowStaticField != null) {
props.setProperty(StrutsConstants.STRUTS_ALLOW_STATIC_FIELD_ACCESS, "" + allowStaticField);
}
@@ -23,7 +23,6 @@ import junit.framework.TestCase;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
@@ -45,7 +44,7 @@ public class SecurityMemberAccessTest extends TestCase {
public void testWithoutClassExclusion() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false, true);
SecurityMemberAccess sma = new SecurityMemberAccess(true);
String propertyName = "stringField";
Member member = FooBar.class.getMethod("get" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1));
@@ -59,7 +58,7 @@ public class SecurityMemberAccessTest extends TestCase {
public void testClassExclusion() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false, true);
SecurityMemberAccess sma = new SecurityMemberAccess(true);
String propertyName = "stringField";
Member member = FooBar.class.getDeclaredMethod("get" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1));
@@ -77,7 +76,7 @@ public class SecurityMemberAccessTest extends TestCase {
public void testObjectClassExclusion() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false, true);
SecurityMemberAccess sma = new SecurityMemberAccess(true);
String propertyName = "toString";
Member member = FooBar.class.getMethod(propertyName);
@@ -91,7 +90,7 @@ public class SecurityMemberAccessTest extends TestCase {
public void testObjectOverwrittenMethodsExclusion() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false, true);
SecurityMemberAccess sma = new SecurityMemberAccess(true);
String propertyName = "hashCode";
Member member = FooBar.class.getMethod(propertyName);
@@ -105,7 +104,7 @@ public class SecurityMemberAccessTest extends TestCase {
public void testInterfaceInheritanceExclusion() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false, true);
SecurityMemberAccess sma = new SecurityMemberAccess(true);
String propertyName = "barLogic";
Member member = BarInterface.class.getMethod(propertyName);
@@ -123,7 +122,7 @@ public class SecurityMemberAccessTest extends TestCase {
public void testMiddleOfInheritanceExclusion1() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false, true);
SecurityMemberAccess sma = new SecurityMemberAccess(true);
String propertyName = "fooLogic";
Member member = FooBar.class.getMethod(propertyName);
@@ -141,7 +140,7 @@ public class SecurityMemberAccessTest extends TestCase {
public void testMiddleOfInheritanceExclusion3() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false, true);
SecurityMemberAccess sma = new SecurityMemberAccess(true);
String propertyName = "barLogic";
Member member = BarInterface.class.getMethod(propertyName);
@@ -155,7 +154,7 @@ public class SecurityMemberAccessTest extends TestCase {
public void testMiddleOfInheritanceExclusion4() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false, true);
SecurityMemberAccess sma = new SecurityMemberAccess(true);
String propertyName = "barLogic";
Member member = BarInterface.class.getMethod(propertyName);
@@ -173,7 +172,7 @@ public class SecurityMemberAccessTest extends TestCase {
public void testPackageExclusion() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false, true);
SecurityMemberAccess sma = new SecurityMemberAccess(true);
Set<Pattern> excluded = new HashSet<>();
excluded.add(Pattern.compile("^" + FooBar.class.getPackage().getName().replaceAll("\\.", "\\\\.") + ".*"));
@@ -188,10 +187,10 @@ public class SecurityMemberAccessTest extends TestCase {
// then
assertFalse("stringField is accessible!", actual);
}
public void testPackageNameExclusion() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false, true);
SecurityMemberAccess sma = new SecurityMemberAccess(true);
Set<String> excluded = new HashSet<>();
excluded.add(FooBar.class.getPackage().getName());
@@ -209,27 +208,27 @@ public class SecurityMemberAccessTest extends TestCase {
public void testDefaultPackageExclusion() {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false, true);
SecurityMemberAccess sma = new SecurityMemberAccess(true);
Set<Pattern> excluded = new HashSet<>();
excluded.add(Pattern.compile("^" + FooBar.class.getPackage().getName().replaceAll("\\.", "\\\\.") + ".*"));
sma.setExcludedPackageNamePatterns(excluded);
// when
boolean actual = sma.isPackageExcluded(null, null);
// then
assertFalse("default package is excluded!", actual);
}
public void testDefaultPackageExclusion2() {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false, true);
SecurityMemberAccess sma = new SecurityMemberAccess(true);
Set<Pattern> excluded = new HashSet<>();
excluded.add(Pattern.compile("^$"));
sma.setExcludedPackageNamePatterns(excluded);
// when
boolean actual = sma.isPackageExcluded(null, null);
@@ -239,7 +238,7 @@ public class SecurityMemberAccessTest extends TestCase {
public void testAccessEnum() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false, true);
SecurityMemberAccess sma = new SecurityMemberAccess(true);
// when
Member values = MyValues.class.getMethod("values");
@@ -249,23 +248,23 @@ public class SecurityMemberAccessTest extends TestCase {
assertTrue("Access to enums is blocked!", actual);
}
public void testAccessStatic() throws Exception {
public void testAccessStaticMethod() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(true, true);
sma.setExcludedClasses(new HashSet<Class<?>>(Collections.singletonList(Class.class)));
SecurityMemberAccess sma = new SecurityMemberAccess(true);
sma.setExcludedClasses(new HashSet<>(Collections.singletonList(Class.class)));
// when
Member method = StaticTester.class.getMethod("sayHello");
boolean actual = sma.isAccessible(context, Class.class, method, null);
// then
assertTrue("Access to static is blocked!", actual);
assertFalse("Access to static method is not blocked!", actual);
}
public void testAccessStaticField() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(true, true);
sma.setExcludedClasses(new HashSet<Class<?>>(Collections.singletonList(Class.class)));
SecurityMemberAccess sma = new SecurityMemberAccess(true);
sma.setExcludedClasses(new HashSet<>(Collections.singletonList(Class.class)));
// when
Member method = StaticTester.class.getField("MAX_VALUE");
@@ -277,8 +276,8 @@ public class SecurityMemberAccessTest extends TestCase {
public void testBlockedStaticFieldWhenFlagIsFalse() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false, true);
sma.setExcludedClasses(new HashSet<Class<?>>(Collections.singletonList(Class.class)));
SecurityMemberAccess sma = new SecurityMemberAccess(true);
sma.setExcludedClasses(new HashSet<>(Collections.singletonList(Class.class)));
// when
Member method = StaticTester.class.getField("MAX_VALUE");
@@ -289,8 +288,8 @@ public class SecurityMemberAccessTest extends TestCase {
// public static final test
// given
sma = new SecurityMemberAccess(false, true);
sma.setExcludedClasses(new HashSet<Class<?>>(Collections.singletonList(Class.class)));
sma = new SecurityMemberAccess(true);
sma.setExcludedClasses(new HashSet<>(Collections.singletonList(Class.class)));
// when
method = StaticTester.class.getField("MIN_VALUE");
@@ -301,8 +300,8 @@ public class SecurityMemberAccessTest extends TestCase {
// package static test
// given
sma = new SecurityMemberAccess(false, true);
sma.setExcludedClasses(new HashSet<Class<?>>(Collections.singletonList(Class.class)));
sma = new SecurityMemberAccess(true);
sma.setExcludedClasses(new HashSet<>(Collections.singletonList(Class.class)));
// when
method = StaticTester.getFieldByName("PACKAGE_STRING");
@@ -313,8 +312,8 @@ public class SecurityMemberAccessTest extends TestCase {
// package final static test
// given
sma = new SecurityMemberAccess(false, true);
sma.setExcludedClasses(new HashSet<Class<?>>(Collections.singletonList(Class.class)));
sma = new SecurityMemberAccess(true);
sma.setExcludedClasses(new HashSet<>(Collections.singletonList(Class.class)));
// when
method = StaticTester.getFieldByName("FINAL_PACKAGE_STRING");
@@ -325,8 +324,8 @@ public class SecurityMemberAccessTest extends TestCase {
// protected static test
// given
sma = new SecurityMemberAccess(false, true);
sma.setExcludedClasses(new HashSet<Class<?>>(Collections.singletonList(Class.class)));
sma = new SecurityMemberAccess(true);
sma.setExcludedClasses(new HashSet<>(Collections.singletonList(Class.class)));
// when
method = StaticTester.getFieldByName("PROTECTED_STRING");
@@ -337,8 +336,8 @@ public class SecurityMemberAccessTest extends TestCase {
// protected final static test
// given
sma = new SecurityMemberAccess(false, true);
sma.setExcludedClasses(new HashSet<Class<?>>(Collections.singletonList(Class.class)));
sma = new SecurityMemberAccess(true);
sma.setExcludedClasses(new HashSet<>(Collections.singletonList(Class.class)));
// when
method = StaticTester.getFieldByName("FINAL_PROTECTED_STRING");
@@ -349,8 +348,8 @@ public class SecurityMemberAccessTest extends TestCase {
// private static test
// given
sma = new SecurityMemberAccess(false, true);
sma.setExcludedClasses(new HashSet<Class<?>>(Collections.singletonList(Class.class)));
sma = new SecurityMemberAccess(true);
sma.setExcludedClasses(new HashSet<>(Collections.singletonList(Class.class)));
// when
method = StaticTester.getFieldByName("PRIVATE_STRING");
@@ -361,8 +360,8 @@ public class SecurityMemberAccessTest extends TestCase {
// private final static test
// given
sma = new SecurityMemberAccess(false, true);
sma.setExcludedClasses(new HashSet<Class<?>>(Collections.singletonList(Class.class)));
sma = new SecurityMemberAccess(true);
sma.setExcludedClasses(new HashSet<>(Collections.singletonList(Class.class)));
// when
method = StaticTester.getFieldByName("FINAL_PRIVATE_STRING");
@@ -374,7 +373,7 @@ public class SecurityMemberAccessTest extends TestCase {
public void testBlockedStaticFieldWhenClassIsExcluded() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(true, true);
SecurityMemberAccess sma = new SecurityMemberAccess(true);
sma.setExcludedClasses(new HashSet<>(Arrays.asList(Class.class, StaticTester.class)));
// when
@@ -385,10 +384,10 @@ public class SecurityMemberAccessTest extends TestCase {
assertFalse("Access to static field isn't blocked!", actual);
}
public void testBlockStaticAccess() throws Exception {
public void testBlockStaticMethodAccess() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false, true);
sma.setExcludedClasses(new HashSet<Class<?>>(Collections.singletonList(Class.class)));
SecurityMemberAccess sma = new SecurityMemberAccess(true);
sma.setExcludedClasses(new HashSet<>(Collections.singletonList(Class.class)));
// when
Member method = StaticTester.class.getMethod("sayHello");
@@ -400,8 +399,8 @@ public class SecurityMemberAccessTest extends TestCase {
public void testBlockStaticAccessIfClassIsExcluded() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false, true);
sma.setExcludedClasses(new HashSet<Class<?>>(Collections.singletonList(Class.class)));
SecurityMemberAccess sma = new SecurityMemberAccess(true);
sma.setExcludedClasses(new HashSet<>(Collections.singletonList(Class.class)));
// when
Member method = Class.class.getMethod("getClassLoader");
@@ -413,8 +412,8 @@ public class SecurityMemberAccessTest extends TestCase {
public void testAllowStaticAccessIfClassIsNotExcluded() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(true, true);
sma.setExcludedClasses(new HashSet<Class<?>>(Collections.singletonList(ClassLoader.class)));
SecurityMemberAccess sma = new SecurityMemberAccess(true);
sma.setExcludedClasses(new HashSet<>(Collections.singletonList(ClassLoader.class)));
// when
Member method = Class.class.getMethod("getClassLoader");
@@ -426,7 +425,7 @@ public class SecurityMemberAccessTest extends TestCase {
public void testAccessPrimitiveInt() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false, true);
SecurityMemberAccess sma = new SecurityMemberAccess(true);
sma.setExcludedPackageNames(TextParseUtil.commaDelimitedStringToSet("java.lang.,ognl,javax"));
String propertyName = "intField";
@@ -441,7 +440,7 @@ public class SecurityMemberAccessTest extends TestCase {
public void testAccessPrimitiveDoubleWithNames() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false, true);
SecurityMemberAccess sma = new SecurityMemberAccess(true);
sma.setExcludedPackageNames(TextParseUtil.commaDelimitedStringToSet("ognl.,javax."));
@@ -493,7 +492,7 @@ public class SecurityMemberAccessTest extends TestCase {
public void testAccessPrimitiveDoubleWithPackageRegExs() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false, true);
SecurityMemberAccess sma = new SecurityMemberAccess(true);
Set<Pattern> patterns = new HashSet<>();
patterns.add(Pattern.compile("^java\\.lang\\..*"));
sma.setExcludedPackageNamePatterns(patterns);
@@ -510,7 +509,7 @@ public class SecurityMemberAccessTest extends TestCase {
public void testAccessMemberAccessIsAccessible() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false, true);
SecurityMemberAccess sma = new SecurityMemberAccess(true);
Set<Class<?>> excluded = new HashSet<>();
excluded.add(ognl.MemberAccess.class);
sma.setExcludedClasses(excluded);
@@ -528,7 +527,7 @@ public class SecurityMemberAccessTest extends TestCase {
public void testAccessMemberAccessIsBlocked() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false, true);
SecurityMemberAccess sma = new SecurityMemberAccess(true);
Set<Class<?>> excluded = new HashSet<>();
excluded.add(SecurityMemberAccess.class);
sma.setExcludedClasses(excluded);
@@ -546,7 +545,7 @@ public class SecurityMemberAccessTest extends TestCase {
public void testPackageNameExclusionAsCommaDelimited() {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false, true);
SecurityMemberAccess sma = new SecurityMemberAccess(true);
sma.setExcludedPackageNames(TextParseUtil.commaDelimitedStringToSet("java.lang."));
@@ -46,9 +46,9 @@ import java.util.*;
* @author tm_jee
*/
public class SetPropertiesTest extends XWorkTestCase {
private OgnlUtil ognlUtil;
@Override
public void setUp() throws Exception {
super.setUp();
@@ -57,7 +57,7 @@ public class SetPropertiesTest extends XWorkTestCase {
}
public void testOgnlUtilEmptyStringAsLong() {
Bar bar = new Bar();
Map context = Ognl.createDefaultContext(bar, new SecurityMemberAccess(false, true));
Map context = Ognl.createDefaultContext(bar, new SecurityMemberAccess(true));
context.put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
bar.setId(null);
@@ -110,7 +110,7 @@ public class SetPropertiesTest extends XWorkTestCase {
assertEquals(Cat.class, foo.getCats().get(0).getClass());
assertEquals(Cat.class, foo.getCats().get(1).getClass());
}
public void testValueStackSetValueEmptyStringAsLong() {
Bar bar = new Bar();
ValueStack vs = ActionContext.getContext().getValueStack();
@@ -193,11 +193,11 @@ public class SetPropertiesTest extends XWorkTestCase {
}
public void testAddingToMapsWithObjectsTrue() throws Exception {
doTestAddingToMapsWithObjects(true);
}
public void testAddingToMapsWithObjectsFalse() throws Exception {
doTestAddingToMapsWithObjects(false);
@@ -227,8 +227,8 @@ public class SetPropertiesTest extends XWorkTestCase {
}
public void testAddingAndModifyingCollectionWithObjectsSet() {
doTestAddingAndModifyingCollectionWithObjects(new HashSet());
}
@@ -0,0 +1,651 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.test;
import com.opensymphony.xwork2.ognl.SecurityMemberAccess;
import com.opensymphony.xwork2.util.TextParseUtil;
import junit.framework.TestCase;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
public class SecurityMemberAccessTest extends TestCase {
private Map context;
private FooBar target;
@Override
public void setUp() throws Exception {
context = new HashMap();
target = new FooBar();
}
public void testWithoutClassExclusion() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(true);
String propertyName = "stringField";
Member member = FooBar.class.getMethod("get" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1));
// when
boolean accessible = sma.isAccessible(context, target, member, propertyName);
// then
assertTrue(accessible);
}
public void testClassExclusion() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(true);
String propertyName = "stringField";
Member member = FooBar.class.getDeclaredMethod("get" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1));
Set<Class<?>> excluded = new HashSet<>();
excluded.add(FooBar.class);
sma.setExcludedClasses(excluded);
// when
boolean accessible = sma.isAccessible(context, target, member, propertyName);
// then
assertFalse(accessible);
}
public void testObjectClassExclusion() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(true);
String propertyName = "toString";
Member member = FooBar.class.getMethod(propertyName);
// when
boolean accessible = sma.isAccessible(context, target, member, propertyName);
// then
assertFalse("toString() from Object is accessible!!!", accessible);
}
public void testObjectOverwrittenMethodsExclusion() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(true);
String propertyName = "hashCode";
Member member = FooBar.class.getMethod(propertyName);
// when
boolean accessible = sma.isAccessible(context, target, member, propertyName);
// then
assertTrue("hashCode() from FooBar isn't accessible!!!", accessible);
}
public void testInterfaceInheritanceExclusion() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(true);
String propertyName = "barLogic";
Member member = BarInterface.class.getMethod(propertyName);
Set<Class<?>> excluded = new HashSet<>();
excluded.add(BarInterface.class);
sma.setExcludedClasses(excluded);
// when
boolean accessible = sma.isAccessible(context, target, member, propertyName);
// then
assertFalse("barLogic() from BarInterface is accessible!!!", accessible);
}
public void testMiddleOfInheritanceExclusion1() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(true);
String propertyName = "fooLogic";
Member member = FooBar.class.getMethod(propertyName);
Set<Class<?>> excluded = new HashSet<>();
excluded.add(BarInterface.class);
sma.setExcludedClasses(excluded);
// when
boolean accessible = sma.isAccessible(context, target, member, propertyName);
// then
assertTrue("fooLogic() from FooInterface isn't accessible!!!", accessible);
}
public void testMiddleOfInheritanceExclusion3() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(true);
String propertyName = "barLogic";
Member member = BarInterface.class.getMethod(propertyName);
// when
boolean accessible = sma.isAccessible(context, target, member, propertyName);
// then
assertTrue("barLogic() from BarInterface isn't accessible!!!", accessible);
}
public void testMiddleOfInheritanceExclusion4() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(true);
String propertyName = "barLogic";
Member member = BarInterface.class.getMethod(propertyName);
Set<Class<?>> excluded = new HashSet<>();
excluded.add(FooBarInterface.class);
sma.setExcludedClasses(excluded);
// when
boolean accessible = sma.isAccessible(context, target, member, propertyName);
// then
assertFalse("barLogic() from BarInterface is accessible!!!", accessible);
}
public void testPackageExclusion() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(true);
Set<Pattern> excluded = new HashSet<>();
excluded.add(Pattern.compile("^" + FooBar.class.getPackage().getName().replaceAll("\\.", "\\\\.") + ".*"));
sma.setExcludedPackageNamePatterns(excluded);
String propertyName = "stringField";
Member member = FooBar.class.getMethod("get" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1));
// when
boolean actual = sma.isAccessible(context, target, member, propertyName);
// then
assertFalse("stringField is accessible!", actual);
}
public void testPackageNameExclusion() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(true);
Set<String> excluded = new HashSet<>();
excluded.add(FooBar.class.getPackage().getName());
sma.setExcludedPackageNames(excluded);
String propertyName = "stringField";
Member member = FooBar.class.getMethod("get" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1));
// when
boolean actual = sma.isAccessible(context, target, member, propertyName);
// then
assertFalse("stringField is accessible!", actual);
}
public void testDefaultPackageExclusion() {
// given
TestSecurityMemberAccess sma = new TestSecurityMemberAccess(true);
Set<Pattern> excluded = new HashSet<>();
excluded.add(Pattern.compile("^" + FooBar.class.getPackage().getName().replaceAll("\\.", "\\\\.") + ".*"));
sma.setExcludedPackageNamePatterns(excluded);
// when
boolean actual = sma.isPackageExcluded(null, null);
// then
assertFalse("default package is excluded!", actual);
}
public void testDefaultPackageExclusion2() {
// given
TestSecurityMemberAccess sma = new TestSecurityMemberAccess(true);
Set<Pattern> excluded = new HashSet<>();
excluded.add(Pattern.compile("^$"));
sma.setExcludedPackageNamePatterns(excluded);
// when
boolean actual = sma.isPackageExcluded(null, null);
// then
assertTrue("default package isn't excluded!", actual);
}
public void testAccessEnum() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(true);
// when
Member values = MyValues.class.getMethod("values");
boolean actual = sma.isAccessible(context, MyValues.class, values, null);
// then
assertTrue("Access to enums is blocked!", actual);
}
public void testAccessStaticMethod() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(true);
sma.setExcludedClasses(new HashSet<>(Collections.singletonList(Class.class)));
// when
Member method = StaticTester.class.getMethod("sayHello");
boolean actual = sma.isAccessible(context, Class.class, method, null);
// then
assertFalse("Access to static method is not blocked!", actual);
}
public void testAccessStaticField() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(true);
sma.setExcludedClasses(new HashSet<>(Collections.singletonList(Class.class)));
// when
Member method = StaticTester.class.getField("MAX_VALUE");
boolean actual = sma.isAccessible(context, null, method, null);
// then
assertTrue("Access to static field is blocked!", actual);
}
public void testBlockedStaticFieldWhenFlagIsFalse() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(true);
sma.setExcludedClasses(new HashSet<>(Collections.singletonList(Class.class)));
// when
Member method = StaticTester.class.getField("MAX_VALUE");
boolean actual = sma.isAccessible(context, null, method, null);
// then
assertTrue("Access to public static field is blocked?", actual);
// public static final test
// given
sma = new SecurityMemberAccess(true);
sma.setExcludedClasses(new HashSet<>(Collections.singletonList(Class.class)));
// when
method = StaticTester.class.getField("MIN_VALUE");
actual = sma.isAccessible(context, null, method, null);
// then
assertTrue("Access to public final static field is blocked?", actual);
// package static test
// given
sma = new SecurityMemberAccess(true);
sma.setExcludedClasses(new HashSet<>(Collections.singletonList(Class.class)));
// when
method = StaticTester.getFieldByName("PACKAGE_STRING");
actual = sma.isAccessible(context, null, method, null);
// then
assertFalse("Access to package static field is allowed?", actual);
// package final static test
// given
sma = new SecurityMemberAccess(true);
sma.setExcludedClasses(new HashSet<>(Collections.singletonList(Class.class)));
// when
method = StaticTester.getFieldByName("FINAL_PACKAGE_STRING");
actual = sma.isAccessible(context, null, method, null);
// then
assertFalse("Access to package final static field is allowed?", actual);
// protected static test
// given
sma = new SecurityMemberAccess(true);
sma.setExcludedClasses(new HashSet<>(Collections.singletonList(Class.class)));
// when
method = StaticTester.getFieldByName("PROTECTED_STRING");
actual = sma.isAccessible(context, null, method, null);
// then
assertFalse("Access to protected static field is allowed?", actual);
// protected final static test
// given
sma = new SecurityMemberAccess(true);
sma.setExcludedClasses(new HashSet<>(Collections.singletonList(Class.class)));
// when
method = StaticTester.getFieldByName("FINAL_PROTECTED_STRING");
actual = sma.isAccessible(context, null, method, null);
// then
assertFalse("Access to protected final static field is allowed?", actual);
// private static test
// given
sma = new SecurityMemberAccess(true);
sma.setExcludedClasses(new HashSet<>(Collections.singletonList(Class.class)));
// when
method = StaticTester.getFieldByName("PRIVATE_STRING");
actual = sma.isAccessible(context, null, method, null);
// then
assertFalse("Access to private static field is allowed?", actual);
// private final static test
// given
sma = new SecurityMemberAccess(true);
sma.setExcludedClasses(new HashSet<>(Collections.singletonList(Class.class)));
// when
method = StaticTester.getFieldByName("FINAL_PRIVATE_STRING");
actual = sma.isAccessible(context, null, method, null);
// then
assertFalse("Access to private final static field is allowed?", actual);
}
public void testBlockedStaticFieldWhenClassIsExcluded() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(true);
sma.setExcludedClasses(new HashSet<>(Arrays.asList(Class.class, StaticTester.class)));
// when
Member method = StaticTester.class.getField("MAX_VALUE");
boolean actual = sma.isAccessible(context, null, method, null);
// then
assertFalse("Access to static field isn't blocked!", actual);
}
public void testBlockStaticAccess() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(true);
sma.setExcludedClasses(new HashSet<>(Collections.singletonList(Class.class)));
// when
Member method = StaticTester.class.getMethod("sayHello");
boolean actual = sma.isAccessible(context, Class.class, method, null);
// then
assertFalse("Access to static isn't blocked!", actual);
}
public void testBlockStaticAccessIfClassIsExcluded() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(true);
sma.setExcludedClasses(new HashSet<>(Collections.singletonList(Class.class)));
// when
Member method = Class.class.getMethod("getClassLoader");
boolean actual = sma.isAccessible(context, Class.class, method, null);
// then
assertFalse("Access to static method of excluded class isn't blocked!", actual);
}
public void testAllowStaticAccessIfClassIsNotExcluded() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(true);
sma.setExcludedClasses(new HashSet<>(Collections.singletonList(ClassLoader.class)));
// when
Member method = Class.class.getMethod("getClassLoader");
boolean actual = sma.isAccessible(context, Class.class, method, null);
// then
assertTrue("Invalid test! Access to static method of excluded class is blocked!", actual);
}
public void testAccessPrimitiveInt() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(true);
sma.setExcludedPackageNames(TextParseUtil.commaDelimitedStringToSet("java.lang.,ognl,javax"));
String propertyName = "intField";
Member member = FooBar.class.getMethod("get" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1));
// when
boolean accessible = sma.isAccessible(context, target, member, propertyName);
// then
assertTrue(accessible);
}
public void testAccessPrimitiveDoubleWithNames() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(true);
sma.setExcludedPackageNames(TextParseUtil.commaDelimitedStringToSet("ognl.,javax."));
Set<Class<?>> excluded = new HashSet<>();
excluded.add(Object.class);
excluded.add(Runtime.class);
excluded.add(System.class);
excluded.add(Class.class);
excluded.add(ClassLoader.class);
sma.setExcludedClasses(excluded);
String propertyName = "doubleValue";
Member member = Double.class.getMethod(propertyName);
// when
boolean accessible = sma.isAccessible(context, target, member, propertyName);
// then
assertTrue(accessible);
// given
propertyName = "exit";
member = System.class.getMethod(propertyName, int.class);
// when
accessible = sma.isAccessible(context, target, member, propertyName);
// then
assertFalse(accessible);
// given
propertyName = "intField";
member = FooBar.class.getMethod("get" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1));
// when
accessible = sma.isAccessible(context, target, member, propertyName);
// then
assertTrue(accessible);
// given
propertyName = "doubleField";
member = FooBar.class.getMethod("get" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1));
// when
accessible = sma.isAccessible(context, target, member, propertyName);
// then
assertTrue(accessible);
}
public void testAccessPrimitiveDoubleWithPackageRegExs() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(true);
Set<Pattern> patterns = new HashSet<>();
patterns.add(Pattern.compile("^java\\.lang\\..*"));
sma.setExcludedPackageNamePatterns(patterns);
String propertyName = "doubleValue";
Member member = Double.class.getMethod(propertyName);
// when
boolean accessible = sma.isAccessible(context, target, member, propertyName);
// then
assertTrue(accessible);
}
public void testAccessMemberAccessIsAccessible() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(true);
Set<Class<?>> excluded = new HashSet<>();
excluded.add(ognl.MemberAccess.class);
sma.setExcludedClasses(excluded);
String propertyName = "excludedClasses";
String setter = "setExcludedClasses";
Member member = SecurityMemberAccess.class.getMethod(setter, Set.class);
// when
boolean accessible = sma.isAccessible(context, target, member, propertyName);
// then
assertTrue(accessible);
}
public void testAccessMemberAccessIsBlocked() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(true);
Set<Class<?>> excluded = new HashSet<>();
excluded.add(SecurityMemberAccess.class);
sma.setExcludedClasses(excluded);
String propertyName = "excludedClasses";
String setter = "setExcludedClasses";
Member member = SecurityMemberAccess.class.getMethod(setter, Set.class);
// when
boolean accessible = sma.isAccessible(context, target, member, propertyName);
// then
assertFalse(accessible);
}
public void testPackageNameExclusionAsCommaDelimited() {
// given
TestSecurityMemberAccess sma = new TestSecurityMemberAccess(true);
sma.setExcludedPackageNames(TextParseUtil.commaDelimitedStringToSet("java.lang."));
// when
boolean actual = sma.isPackageExcluded(String.class.getPackage(), null);
actual &= sma.isPackageExcluded(null, String.class.getPackage());
// then
assertTrue("package java.lang. is accessible!", actual);
}
}
class FooBar implements FooBarInterface {
private String stringField;
private int intField;
private Double doubleField;
public String getStringField() {
return stringField;
}
public void setStringField(String stringField) {
this.stringField = stringField;
}
public String fooLogic() {
return "fooLogic";
}
public String barLogic() {
return "barLogic";
}
@Override
public int hashCode() {
return 1;
}
public int getIntField() {
return intField;
}
public void setIntField(int intField) {
this.intField = intField;
}
public Double getDoubleField() {
return doubleField;
}
public void setDoubleField(Double doubleField) {
this.doubleField = doubleField;
}
}
interface FooInterface {
String fooLogic();
}
interface BarInterface {
String barLogic();
}
interface FooBarInterface extends FooInterface, BarInterface {
}
enum MyValues {
ONE, TWO, THREE
}
class StaticTester {
public static int MAX_VALUE = 0;
public static final int MIN_VALUE = 0;
static String PACKAGE_STRING = "package_string";
static final String FINAL_PACKAGE_STRING = "final_package_string";
static String PROTECTED_STRING = "protected_string";
static final String FINAL_PROTECTED_STRING = "final_protected_string";
static String PRIVATE_STRING = "private_string";
static final String FINAL_PRIVATE_STRING = "final_private_string";
public static String sayHello() {
return "Hello";
}
protected static Field getFieldByName(String fieldName) throws NoSuchFieldException {
if (fieldName != null && fieldName.length() > 0) {
return StaticTester.class.getDeclaredField(fieldName);
} else {
throw new NoSuchFieldException("field: " + fieldName + " does not exist");
}
}
}
@@ -0,0 +1,33 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.test;
import com.opensymphony.xwork2.ognl.SecurityMemberAccess;
class TestSecurityMemberAccess extends SecurityMemberAccess {
TestSecurityMemberAccess(boolean allowStaticFieldAccess) {
super(allowStaticFieldAccess);
}
@Override
public boolean isPackageExcluded(Package targetPackage, Package memberPackage) {
return super.isPackageExcluded(targetPackage, memberPackage);
}
}
@@ -18,25 +18,26 @@
*/
package org.apache.struts2.interceptor;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.Cookie;
import com.opensymphony.xwork2.security.DefaultAcceptedPatternsChecker;
import com.opensymphony.xwork2.security.DefaultExcludedPatternsChecker;
import com.opensymphony.xwork2.mock.MockActionInvocation;
import org.springframework.mock.web.MockHttpServletRequest;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.StrutsInternalTestCase;
import static org.easymock.EasyMock.*;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.mock.MockActionInvocation;
import com.opensymphony.xwork2.security.DefaultAcceptedPatternsChecker;
import com.opensymphony.xwork2.security.DefaultExcludedPatternsChecker;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.StrutsInternalTestCase;
import org.springframework.mock.web.MockHttpServletRequest;
import javax.servlet.http.Cookie;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
public class CookieInterceptorTest extends StrutsInternalTestCase {
@@ -44,9 +45,9 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
public void testIntercepDefault() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(
new Cookie("cookie1", "cookie1value"),
new Cookie("cookie2", "cookie2value"),
new Cookie("cookie3", "cookie3value")
new Cookie("cookie1", "cookie1value"),
new Cookie("cookie2", "cookie2value"),
new Cookie("cookie3", "cookie3value")
);
ServletActionContext.setRequest(request);
@@ -55,7 +56,7 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
ActionContext.getContext().getValueStack().push(action);
ActionInvocation invocation = (ActionInvocation) createMock(ActionInvocation.class);
expect(invocation.getAction()).andReturn(action);
expect(invocation.invoke()).andReturn(Action.SUCCESS);
@@ -75,16 +76,16 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
assertNull(ActionContext.getContext().getValueStack().findValue("cookie1"));
assertNull(ActionContext.getContext().getValueStack().findValue("cookie2"));
assertNull(ActionContext.getContext().getValueStack().findValue("cookie3"));
verify(invocation);
}
public void testInterceptAll1() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(
new Cookie("cookie1", "cookie1value"),
new Cookie("cookie2", "cookie2value"),
new Cookie("cookie3", "cookie3value")
new Cookie("cookie1", "cookie1value"),
new Cookie("cookie2", "cookie2value"),
new Cookie("cookie3", "cookie3value")
);
ServletActionContext.setRequest(request);
@@ -93,7 +94,7 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
ActionContext.getContext().getValueStack().push(action);
ActionInvocation invocation = (ActionInvocation) createMock(ActionInvocation.class);
expect(invocation.getAction()).andReturn(action);
expect(invocation.invoke()).andReturn(Action.SUCCESS);
@@ -117,7 +118,7 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie1"), "cookie1value");
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie2"), "cookie2value");
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie3"), "cookie3value");
verify(invocation);
}
@@ -125,9 +126,9 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
public void testInterceptAll2() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(
new Cookie("cookie1", "cookie1value"),
new Cookie("cookie2", "cookie2value"),
new Cookie("cookie3", "cookie3value")
new Cookie("cookie1", "cookie1value"),
new Cookie("cookie2", "cookie2value"),
new Cookie("cookie3", "cookie3value")
);
ServletActionContext.setRequest(request);
@@ -159,16 +160,16 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie1"), "cookie1value");
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie2"), "cookie2value");
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie3"), "cookie3value");
verify(invocation);
}
public void testInterceptSelectedCookiesNameOnly1() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(
new Cookie("cookie1", "cookie1value"),
new Cookie("cookie2", "cookie2value"),
new Cookie("cookie3", "cookie3value")
new Cookie("cookie1", "cookie1value"),
new Cookie("cookie2", "cookie2value"),
new Cookie("cookie3", "cookie3value")
);
ServletActionContext.setRequest(request);
@@ -200,16 +201,16 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie1"), "cookie1value");
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie2"), null);
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie3"), "cookie3value");
verify(invocation);
}
public void testInterceptSelectedCookiesNameOnly2() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(
new Cookie("cookie1", "cookie1value"),
new Cookie("cookie2", "cookie2value"),
new Cookie("cookie3", "cookie3value")
new Cookie("cookie1", "cookie1value"),
new Cookie("cookie2", "cookie2value"),
new Cookie("cookie3", "cookie3value")
);
ServletActionContext.setRequest(request);
@@ -218,7 +219,7 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
ActionContext.getContext().getValueStack().push(action);
ActionInvocation invocation = (ActionInvocation) createMock(ActionInvocation.class);
expect(invocation.getAction()).andReturn(action);
expect(invocation.invoke()).andReturn(Action.SUCCESS);
@@ -242,16 +243,16 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie1"), "cookie1value");
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie2"), null);
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie3"), "cookie3value");
verify(invocation);
}
public void testInterceptSelectedCookiesNameOnly3() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(
new Cookie("cookie1", "cookie1value"),
new Cookie("cookie2", "cookie2value"),
new Cookie("cookie3", "cookie3value")
new Cookie("cookie1", "cookie1value"),
new Cookie("cookie2", "cookie2value"),
new Cookie("cookie3", "cookie3value")
);
ServletActionContext.setRequest(request);
@@ -283,7 +284,7 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie1"), "cookie1value");
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie2"), null);
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie3"), "cookie3value");
verify(invocation);
}
@@ -291,9 +292,9 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
public void testInterceptSelectedCookiesNameAndValue() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(
new Cookie("cookie1", "cookie1value"),
new Cookie("cookie2", "cookie2value"),
new Cookie("cookie3", "cookie3value")
new Cookie("cookie1", "cookie1value"),
new Cookie("cookie2", "cookie2value"),
new Cookie("cookie3", "cookie3value")
);
ServletActionContext.setRequest(request);
@@ -325,7 +326,7 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie1"), "cookie1value");
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie2"), null);
assertEquals(ActionContext.getContext().getValueStack().findValue("cookie3"), null);
verify(invocation);
}
@@ -338,20 +339,44 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
String pollution5 = "model[\"class\"]['classLoader']['jarPath']";
String pollution6 = "class[\"classLoader\"]['jarPath']";
try {
new Cookie(pollution1, "pollution1");
fail("It shouldn't be possible to create cookie: " + pollution1);
} catch (IllegalArgumentException e) {
assertEquals(e.getMessage(), "Cookie name \"" + pollution1 + "\" is a reserved token");
}
try {
new Cookie(pollution4, "pollution4");
fail("It shouldn't be possible to create cookie: " + pollution4);
} catch (IllegalArgumentException e) {
assertEquals(e.getMessage(), "Cookie name \"" + pollution4 + "\" is a reserved token");
}
try {
new Cookie(pollution5, "pollution5");
fail("It shouldn't be possible to create cookie: " + pollution5);
} catch (IllegalArgumentException e) {
assertEquals(e.getMessage(), "Cookie name \"" + pollution5 + "\" is a reserved token");
}
try {
new Cookie(pollution6, "pollution6");
fail("It shouldn't be possible to create cookie: " + pollution6);
} catch (IllegalArgumentException e) {
assertEquals(e.getMessage(), "Cookie name \"" + pollution6 + "\" is a reserved token");
}
request.setCookies(
new Cookie(pollution1, "pollution1"),
new Cookie("pollution1", pollution1),
new Cookie(pollution2, "pollution2"),
new Cookie("pollution2", pollution2),
new Cookie(pollution3, "pollution3"),
new Cookie("pollution3", pollution3),
new Cookie(pollution4, "pollution4"),
new Cookie("pollution4", pollution4),
new Cookie(pollution5, "pollution5"),
new Cookie("pollution5", pollution5),
new Cookie(pollution6, "pollution6"),
new Cookie("pollution6", pollution6)
);
new Cookie("pollution1", pollution1),
new Cookie(pollution2, "pollution2"),
new Cookie("pollution2", pollution2),
new Cookie(pollution3, "pollution3"),
new Cookie("pollution3", pollution3),
new Cookie("pollution4", pollution4),
new Cookie("pollution5", pollution5),
new Cookie("pollution6", pollution6)
);
ServletActionContext.setRequest(request);
final Map<String, Boolean> excludedName = new HashMap<String, Boolean>();
@@ -375,12 +400,12 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
interceptor.intercept(invocation);
assertFalse(excludedName.get(pollution1));
//assertFalse(excludedName.get(pollution1));
assertFalse(excludedName.get(pollution2));
assertFalse(excludedName.get(pollution3));
assertFalse(excludedName.get(pollution4));
assertFalse(excludedName.get(pollution5));
assertFalse(excludedName.get(pollution6));
//assertFalse(excludedName.get(pollution4));
//assertFalse(excludedName.get(pollution5));
// assertFalse(excludedName.get(pollution6));
}
public void testCookiesWithStrutsInternalsAccess() throws Exception {
@@ -393,13 +418,13 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
String reqCookieValue = "request.userId=1";
request.setCookies(
new Cookie(sessionCookieName, "1"),
new Cookie("1", sessionCookieValue),
new Cookie(appCookieName, "1"),
new Cookie("1", appCookieValue),
new Cookie(reqCookieName, "1"),
new Cookie("1", reqCookieValue)
);
new Cookie(sessionCookieName, "1"),
new Cookie("1", sessionCookieValue),
new Cookie(appCookieName, "1"),
new Cookie("1", appCookieValue),
new Cookie(reqCookieName, "1"),
new Cookie("1", reqCookieValue)
);
ServletActionContext.setRequest(request);
final Map<String, Boolean> excludedName = new HashMap<String, Boolean>();
@@ -436,13 +461,13 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
String reqCookieValue = "request.userId=1";
request.setCookies(
new Cookie(sessionCookieName, "1"),
new Cookie("1", sessionCookieValue),
new Cookie(appCookieName, "1"),
new Cookie("1", appCookieValue),
new Cookie(reqCookieName, "1"),
new Cookie("1", reqCookieValue)
);
new Cookie(sessionCookieName, "1"),
new Cookie("1", sessionCookieValue),
new Cookie(appCookieName, "1"),
new Cookie("1", appCookieValue),
new Cookie(reqCookieName, "1"),
new Cookie("1", reqCookieValue)
);
ServletActionContext.setRequest(request);
final Map<String, Boolean> excludedName = new HashMap<>();
@@ -486,14 +511,29 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
return this.cookies;
}
public String getCookie1() { return cookie1; }
public void setCookie1(String cookie1) { this.cookie1 = cookie1; }
public String getCookie1() {
return cookie1;
}
public String getCookie2() { return cookie2; }
public void setCookie2(String cookie2) { this.cookie2 = cookie2; }
public void setCookie1(String cookie1) {
this.cookie1 = cookie1;
}
public String getCookie3() { return cookie3; }
public void setCookie3(String cookie3) { this.cookie3 = cookie3; }
public String getCookie2() {
return cookie2;
}
public void setCookie2(String cookie2) {
this.cookie2 = cookie2;
}
public String getCookie3() {
return cookie3;
}
public void setCookie3(String cookie3) {
this.cookie3 = cookie3;
}
}
public static class MockActionWithActionCookieAware extends ActionSupport implements org.apache.struts2.action.CookiesAware {
@@ -511,14 +551,29 @@ public class CookieInterceptorTest extends StrutsInternalTestCase {
return this.cookies;
}
public String getCookie1() { return cookie1; }
public void setCookie1(String cookie1) { this.cookie1 = cookie1; }
public String getCookie1() {
return cookie1;
}
public String getCookie2() { return cookie2; }
public void setCookie2(String cookie2) { this.cookie2 = cookie2; }
public void setCookie1(String cookie1) {
this.cookie1 = cookie1;
}
public String getCookie3() { return cookie3; }
public void setCookie3(String cookie3) { this.cookie3 = cookie3; }
public String getCookie2() {
return cookie2;
}
public void setCookie2(String cookie2) {
this.cookie2 = cookie2;
}
public String getCookie3() {
return cookie3;
}
public void setCookie3(String cookie3) {
this.cookie3 = cookie3;
}
}
}
@@ -58,7 +58,7 @@ public class PlainResultTest extends StrutsInternalTestCase {
result.execute(invocation);
assertEquals("{ 'value': 'test' }", response.getContentAsString());
assertEquals("application/json", response.getContentType());
assertEquals("application/json;charset=UTF-8", response.getContentType());
}
public void testWriteContentTypeCsvWithCookie() throws Exception {
@@ -72,7 +72,7 @@ public class PlainResultTest extends StrutsInternalTestCase {
result.execute(invocation);
assertEquals("name;value\nline;1\nline;2", response.getContentAsString());
assertEquals("text/csv", response.getContentType());
assertEquals("text/csv;charset=UTF-8", response.getContentType());
}
public void testHeaders() throws Exception {
@@ -146,4 +146,4 @@ public class PlainResultTest extends StrutsInternalTestCase {
ActionContext.getContext().withServletResponse(response).withActionInvocation(invocation);
}
}
}
@@ -41,7 +41,7 @@ public class SecurityMemberAccessInServletsTest extends StrutsInternalTestCase {
public void testJavaxServletPackageAccess() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false, true);
SecurityMemberAccess sma = new SecurityMemberAccess(true);
Set<Pattern> excluded = new HashSet<Pattern>();
excluded.add(Pattern.compile("^(?!javax\\.servlet\\..+)(javax\\..+)"));
@@ -59,7 +59,7 @@ public class SecurityMemberAccessInServletsTest extends StrutsInternalTestCase {
public void testJavaxServletPackageExclusion() throws Exception {
// given
SecurityMemberAccess sma = new SecurityMemberAccess(false, true);
SecurityMemberAccess sma = new SecurityMemberAccess(true);
Set<Pattern> excluded = new HashSet<Pattern>();
excluded.add(Pattern.compile("^javax\\..+"));
@@ -23,14 +23,21 @@ import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collections;
import java.util.Enumeration;
import java.util.EventListener;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.servlet.Filter;
import javax.servlet.FilterRegistration;
import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import javax.servlet.SessionCookieConfig;
import javax.servlet.SessionTrackingMode;
import javax.servlet.descriptor.JspConfigDescriptor;
/**
@@ -42,12 +49,12 @@ public class StrutsMockServletContext implements ServletContext {
String realPath;
String servletInfo;
String contextPath;
Map initParams = new HashMap();
Map attributes = new HashMap();
Map<String, String> initParams = new HashMap<>();
Map<String, Object> attributes = new HashMap<>();
InputStream resourceAsStream;
public void setInitParameter(String name, String value) {
initParams.put(name, value);
public boolean setInitParameter(String name, String value) {
return initParams.put(name, value) != null;
}
public void setRealPath(String value) {
@@ -74,7 +81,7 @@ public class StrutsMockServletContext implements ServletContext {
return null;
}
public Set getResourcePaths(String s) {
public Set<String> getResourcePaths(String s) {
return null;
}
@@ -105,11 +112,11 @@ public class StrutsMockServletContext implements ServletContext {
return null;
}
public Enumeration getServlets() {
public Enumeration<Servlet> getServlets() {
return null;
}
public Enumeration getServletNames() {
public Enumeration<String> getServletNames() {
return null;
}
@@ -130,7 +137,7 @@ public class StrutsMockServletContext implements ServletContext {
return (String) initParams.get(s);
}
public Enumeration getInitParameterNames() {
public Enumeration<String> getInitParameterNames() {
return Collections.enumeration(initParams.keySet());
}
@@ -138,7 +145,7 @@ public class StrutsMockServletContext implements ServletContext {
return attributes.get(s);
}
public Enumeration getAttributeNames() {
public Enumeration<String> getAttributeNames() {
return Collections.enumeration(attributes.keySet());
}
@@ -157,12 +164,142 @@ public class StrutsMockServletContext implements ServletContext {
public void setServletInfo(String servletInfo) {
this.servletInfo = servletInfo;
}
public String getContextPath() {
return contextPath;
}
}
public void setContextPath(String contextPath) {
this.contextPath = contextPath;
}
@Override
public int getEffectiveMajorVersion() {
return 0;
}
@Override
public int getEffectiveMinorVersion() {
return 0;
}
@Override
public ServletRegistration.Dynamic addServlet(String servletName, String className) {
return null;
}
@Override
public ServletRegistration.Dynamic addServlet(String servletName, Servlet servlet) {
return null;
}
@Override
public ServletRegistration.Dynamic addServlet(String servletName, Class<? extends Servlet> servletClass) {
return null;
}
@Override
public <T extends Servlet> T createServlet(Class<T> clazz) throws ServletException {
return null;
}
@Override
public ServletRegistration getServletRegistration(String servletName) {
return null;
}
@Override
public Map<String, ? extends ServletRegistration> getServletRegistrations() {
return null;
}
@Override
public FilterRegistration.Dynamic addFilter(String filterName, String className) {
return null;
}
@Override
public FilterRegistration.Dynamic addFilter(String filterName, Filter filter) {
return null;
}
@Override
public FilterRegistration.Dynamic addFilter(String filterName, Class<? extends Filter> filterClass) {
return null;
}
@Override
public <T extends Filter> T createFilter(Class<T> clazz) throws ServletException {
return null;
}
@Override
public FilterRegistration getFilterRegistration(String filterName) {
return null;
}
@Override
public Map<String, ? extends FilterRegistration> getFilterRegistrations() {
return null;
}
@Override
public SessionCookieConfig getSessionCookieConfig() {
return null;
}
@Override
public void setSessionTrackingModes(Set<SessionTrackingMode> sessionTrackingModes) {
}
@Override
public Set<SessionTrackingMode> getDefaultSessionTrackingModes() {
return null;
}
@Override
public Set<SessionTrackingMode> getEffectiveSessionTrackingModes() {
return null;
}
@Override
public void addListener(String className) {
}
@Override
public <T extends EventListener> void addListener(T t) {
}
@Override
public void addListener(Class<? extends EventListener> listenerClass) {
}
@Override
public <T extends EventListener> T createListener(Class<T> clazz) throws ServletException {
return null;
}
@Override
public JspConfigDescriptor getJspConfigDescriptor() {
return null;
}
@Override
public ClassLoader getClassLoader() {
return null;
}
@Override
public void declareRoles(String... roleNames) {
}
@Override
public String getVirtualServerName() {
return null;
}
}
@@ -26,4 +26,5 @@
<constant name="struts.excludedClasses" value="java.lang.Object,java.lang.Runtime,ognl.OgnlContext,ognl.MemberAccess,ognl.ClassResolver,ognl.TypeConverter,com.opensymphony.xwork2.ognl.SecurityMemberAccess" />
<constant name="struts.ognl.allowStaticFieldAccess" value="false"/>
</struts>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<artifactId>struts2-async-plugin</artifactId>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -25,7 +25,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<artifactId>struts2-cdi-plugin</artifactId>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<artifactId>struts2-config-browser-plugin</artifactId>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<artifactId>struts2-convention-plugin</artifactId>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<artifactId>struts2-dwr-plugin</artifactId>
+1 -10
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<artifactId>struts2-embeddedjsp-plugin</artifactId>
@@ -89,15 +89,6 @@
<artifactId>tomcat-jasper</artifactId>
<scope>provided</scope>
</dependency>
<!-- The Servlet API mocks in Spring Framework 4.x only supports Servlet 3.0 and higher.
This is only necessary in tests-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<artifactId>struts2-gxp-plugin</artifactId>
+1 -7
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<artifactId>struts2-jasperreports-plugin</artifactId>
@@ -63,12 +63,6 @@
<artifactId>jsp-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
+1 -1
View File
@@ -25,7 +25,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<artifactId>struts2-javatemplates-plugin</artifactId>
+4 -13
View File
@@ -24,8 +24,8 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>6.0.0-SNAPSHOT</version>
</parent>
<version>6.0.0</version>
</parent>
<artifactId>struts2-jfreechart-plugin</artifactId>
<packaging>jar</packaging>
@@ -71,18 +71,9 @@
<artifactId>easymock</artifactId>
<scope>test</scope>
</dependency>
<!-- The Servlet API mocks in Spring Framework 4.x only supports Servlet 3.0 and higher.
This is only necessary in tests-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
+4 -12
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<artifactId>struts2-json-plugin</artifactId>
@@ -105,18 +105,10 @@
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<!-- The Servlet API mocks in Spring Framework 4.x only supports Servlet 3.0 and higher.
This is only necessary in tests-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
+3 -11
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<artifactId>struts2-junit-plugin</artifactId>
@@ -85,17 +85,9 @@
<artifactId>struts2-portlet-mocks-plugin</artifactId>
<optional>true</optional>
</dependency>
<!-- The Servlet API mocks in Spring Framework 4.x only supports Servlet 3.0 and higher.
This is only necessary in tests-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
+1 -10
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<artifactId>struts2-osgi-plugin</artifactId>
@@ -106,15 +106,6 @@
<scope>test</scope>
</dependency>
<!-- The Servlet API mocks in Spring Framework 4.x only supports Servlet 3.0 and higher.
This is only necessary in tests-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<artifactId>struts2-oval-plugin</artifactId>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<artifactId>struts2-pell-multipart-plugin</artifactId>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<artifactId>struts2-plexus-plugin</artifactId>
+2 -2
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-parent</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<artifactId>struts2-plugins</artifactId>
@@ -76,7 +76,7 @@
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
+3 -10
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<artifactId>struts2-portlet-mocks-plugin</artifactId>
@@ -47,17 +47,10 @@
<artifactId>portlet-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- The Servlet API mocks in Spring Framework 4.x only supports Servlet 3.0 and higher.
This is only necessary in tests-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<spring.platformVersion>4.3.30.RELEASE</spring.platformVersion>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<artifactId>struts2-portlet-tiles-plugin</artifactId>
+6 -16
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<artifactId>struts2-portlet-plugin</artifactId>
@@ -129,27 +129,17 @@
<artifactId>spring-test</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc-portlet</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<scope>test</scope>
</dependency>
<!-- The Servlet API mocks in Spring Framework 4.x only supports Servlet 3.0 and higher.
This is only necessary in tests-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.platformVersion>4.3.30.RELEASE</spring.platformVersion>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
@@ -20,14 +20,22 @@ package org.apache.struts2.portlet.servlet;
import javax.portlet.PortletContext;
import javax.portlet.PortletRequestDispatcher;
import javax.servlet.Filter;
import javax.servlet.FilterRegistration;
import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import javax.servlet.SessionCookieConfig;
import javax.servlet.SessionTrackingMode;
import javax.servlet.descriptor.JspConfigDescriptor;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Enumeration;
import java.util.EventListener;
import java.util.Map;
import java.util.Set;
/**
@@ -86,6 +94,11 @@ public class PortletServletContext implements ServletContext {
return portletContext.getInitParameterNames();
}
@Override
public boolean setInitParameter(String name, String value) {
return false;
}
/* (non-Javadoc)
* @see javax.servlet.ServletContext#getMajorVersion()
*/
@@ -107,6 +120,16 @@ public class PortletServletContext implements ServletContext {
return portletContext.getMinorVersion();
}
@Override
public int getEffectiveMajorVersion() {
return 0;
}
@Override
public int getEffectiveMinorVersion() {
return 0;
}
/**
* Returns a {@link PortletServletRequestDispatcher} wrapping the {@link PortletRequestDispatcher}
* as a {@link RequestDispatcher} instance.
@@ -179,6 +202,126 @@ public class PortletServletContext implements ServletContext {
return portletContext.getPortletContextName();
}
@Override
public ServletRegistration.Dynamic addServlet(String servletName, String className) {
return null;
}
@Override
public ServletRegistration.Dynamic addServlet(String servletName, Servlet servlet) {
return null;
}
@Override
public ServletRegistration.Dynamic addServlet(String servletName, Class<? extends Servlet> servletClass) {
return null;
}
@Override
public <T extends Servlet> T createServlet(Class<T> clazz) throws ServletException {
return null;
}
@Override
public ServletRegistration getServletRegistration(String servletName) {
return null;
}
@Override
public Map<String, ? extends ServletRegistration> getServletRegistrations() {
return null;
}
@Override
public FilterRegistration.Dynamic addFilter(String filterName, String className) {
return null;
}
@Override
public FilterRegistration.Dynamic addFilter(String filterName, Filter filter) {
return null;
}
@Override
public FilterRegistration.Dynamic addFilter(String filterName, Class<? extends Filter> filterClass) {
return null;
}
@Override
public <T extends Filter> T createFilter(Class<T> clazz) throws ServletException {
return null;
}
@Override
public FilterRegistration getFilterRegistration(String filterName) {
return null;
}
@Override
public Map<String, ? extends FilterRegistration> getFilterRegistrations() {
return null;
}
@Override
public SessionCookieConfig getSessionCookieConfig() {
return null;
}
@Override
public void setSessionTrackingModes(Set<SessionTrackingMode> sessionTrackingModes) {
}
@Override
public Set<SessionTrackingMode> getDefaultSessionTrackingModes() {
return null;
}
@Override
public Set<SessionTrackingMode> getEffectiveSessionTrackingModes() {
return null;
}
@Override
public void addListener(String className) {
}
@Override
public <T extends EventListener> void addListener(T t) {
}
@Override
public void addListener(Class<? extends EventListener> listenerClass) {
}
@Override
public <T extends EventListener> T createListener(Class<T> clazz) throws ServletException {
return null;
}
@Override
public JspConfigDescriptor getJspConfigDescriptor() {
return null;
}
@Override
public ClassLoader getClassLoader() {
return null;
}
@Override
public void declareRoles(String... roleNames) {
}
@Override
public String getVirtualServerName() {
return null;
}
/**
* @throws IllegalStateException Not supported in a portlet.
* @see javax.servlet.ServletContext#getServletNames()
@@ -21,6 +21,7 @@ package org.apache.struts2.portlet.servlet;
import java.io.IOException;
import java.io.InputStream;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
/**
@@ -31,11 +32,11 @@ import javax.servlet.ServletInputStream;
public class PortletServletInputStream extends ServletInputStream {
private InputStream portletInputStream;
public PortletServletInputStream(InputStream portletInputStream) {
this.portletInputStream = portletInputStream;
}
/* (non-Javadoc)
* @see java.io.InputStream#read()
*/
@@ -107,7 +108,7 @@ public class PortletServletInputStream extends ServletInputStream {
public long skip(long n) throws IOException {
return portletInputStream.skip(n);
}
/**
* Get the wrapped {@link InputStream} instance.
* @return The wrapped {@link InputStream} instance.
@@ -116,4 +117,18 @@ public class PortletServletInputStream extends ServletInputStream {
return portletInputStream;
}
@Override
public boolean isFinished() {
return true;
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener readListener) {
// no-op
}
}
@@ -22,6 +22,7 @@ import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
/**
* Wrapper object exposing a {@link OutputStream} from a portlet as a {@link ServletOutputStream} instance.
@@ -31,7 +32,7 @@ import javax.servlet.ServletOutputStream;
public class PortletServletOutputStream extends ServletOutputStream {
private OutputStream portletOutputStream;
public PortletServletOutputStream(OutputStream portletOutputStream) {
this.portletOutputStream = portletOutputStream;
}
@@ -75,7 +76,7 @@ public class PortletServletOutputStream extends ServletOutputStream {
public void write(byte[] b, int off, int len) throws IOException {
portletOutputStream.write(b, off, len);
}
/**
* Get the wrapped {@link OutputStream} instance.
* @return The wrapped {@link OutputStream} instance.
@@ -83,4 +84,14 @@ public class PortletServletOutputStream extends ServletOutputStream {
public OutputStream getOutputStream() {
return portletOutputStream;
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setWriteListener(WriteListener writeListener) {
// no-op
}
}
@@ -23,6 +23,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.Principal;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Locale;
@@ -34,12 +35,20 @@ import javax.portlet.PortletContext;
import javax.portlet.PortletRequest;
import javax.portlet.PortletRequestDispatcher;
import javax.portlet.PortletSession;
import javax.servlet.AsyncContext;
import javax.servlet.DispatcherType;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpUpgradeHandler;
import javax.servlet.http.Part;
import static org.apache.struts2.portlet.PortletConstants.*;
@@ -71,7 +80,7 @@ public class PortletServletRequest implements HttpServletRequest {
/*
* (non-Javadoc)
*
*
* @see javax.servlet.http.HttpServletRequest#getAuthType()
*/
public String getAuthType() {
@@ -80,7 +89,7 @@ public class PortletServletRequest implements HttpServletRequest {
/*
* (non-Javadoc)
*
*
* @see javax.servlet.http.HttpServletRequest#getContextPath()
*/
public String getContextPath() {
@@ -89,7 +98,7 @@ public class PortletServletRequest implements HttpServletRequest {
/**
* Not allowed in a portlet.
*
*
* @throws IllegalStateException
* Not allowed in a portlet.
*/
@@ -102,7 +111,7 @@ public class PortletServletRequest implements HttpServletRequest {
/**
* Not allowed in a portlet.
*
*
* @throws IllegalStateException
* Not allowed in a portlet.
*/
@@ -113,7 +122,7 @@ public class PortletServletRequest implements HttpServletRequest {
/**
* Gets a property from the {@link PortletRequest}. Note that a
* {@link PortletRequest} is not guaranteed to map properties to headers.
*
*
* @see PortletRequest#getProperty(String)
* @see javax.servlet.http.HttpServletRequest#getHeader(java.lang.String)
*/
@@ -124,7 +133,7 @@ public class PortletServletRequest implements HttpServletRequest {
/**
* Gets the property names from the {@link PortletRequest}. Note that a
* {@link PortletRequest} is not guaranteed to map properties to headers.
*
*
* @see PortletRequest#getPropertyNames()
* @see javax.servlet.http.HttpServletRequest#getHeaderNames()
*/
@@ -136,7 +145,7 @@ public class PortletServletRequest implements HttpServletRequest {
* Gets the values for the specified property from the
* {@link PortletRequest}. Note that a {@link PortletRequest} is not
* guaranteed to map properties to headers.
*
*
* @see PortletRequest#getProperties(String)
* @see HttpServletRequest#getHeaders(String)
*/
@@ -146,7 +155,7 @@ public class PortletServletRequest implements HttpServletRequest {
/**
* Not allowed in a portlet.
*
*
* @throws IllegalStateException
* Not allowed in a portlet.
*/
@@ -156,7 +165,7 @@ public class PortletServletRequest implements HttpServletRequest {
/*
* (non-Javadoc)
*
*
* @see javax.servlet.http.HttpServletRequest#getMethod()
*/
public String getMethod() {
@@ -170,7 +179,7 @@ public class PortletServletRequest implements HttpServletRequest {
/*
* (non-Javadoc)
*
*
* @see javax.servlet.http.HttpServletRequest#getPathInfo()
*/
public String getPathInfo() {
@@ -179,7 +188,7 @@ public class PortletServletRequest implements HttpServletRequest {
/*
* (non-Javadoc)
*
*
* @see javax.servlet.http.HttpServletRequest#getPathTranslated()
*/
public String getPathTranslated() {
@@ -188,7 +197,7 @@ public class PortletServletRequest implements HttpServletRequest {
/*
* (non-Javadoc)
*
*
* @see javax.servlet.http.HttpServletRequest#getQueryString()
*/
public String getQueryString() {
@@ -197,7 +206,7 @@ public class PortletServletRequest implements HttpServletRequest {
/*
* (non-Javadoc)
*
*
* @see javax.servlet.http.HttpServletRequest#getRemoteUser()
*/
public String getRemoteUser() {
@@ -206,7 +215,7 @@ public class PortletServletRequest implements HttpServletRequest {
/**
* Not allowed in a portlet.
*
*
* @throws IllegalStateException
* Not allowed in a portlet.
*/
@@ -216,7 +225,7 @@ public class PortletServletRequest implements HttpServletRequest {
/**
* Not allowed in a portlet.
*
*
* @throws IllegalStateException
* Not allowed in a portlet.
*/
@@ -226,7 +235,7 @@ public class PortletServletRequest implements HttpServletRequest {
/*
* (non-Javadoc)
*
*
* @see javax.servlet.http.HttpServletRequest#getRequestedSessionId()
*/
public String getRequestedSessionId() {
@@ -237,7 +246,7 @@ public class PortletServletRequest implements HttpServletRequest {
* A {@link PortletRequest} has no servlet path. But for compatibility with
* Struts 2 components and interceptors, the action parameter on the request
* is mapped to the servlet path.
*
*
* @see javax.servlet.http.HttpServletRequest#getServletPath()
*/
public String getServletPath() {
@@ -250,16 +259,21 @@ public class PortletServletRequest implements HttpServletRequest {
/**
* Get the {@link PortletSession} as a {@link PortletHttpSession} instance.
*
*
* @see javax.servlet.http.HttpServletRequest#getSession()
*/
public HttpSession getSession() {
return new PortletHttpSession(portletRequest.getPortletSession());
}
@Override
public String changeSessionId() {
return null;
}
/**
* Get the {@link PortletSession} as a {@link PortletHttpSession} instance.
*
*
* @see javax.servlet.http.HttpServletRequest#getSession(boolean)
*/
public HttpSession getSession(boolean create) {
@@ -268,7 +282,7 @@ public class PortletServletRequest implements HttpServletRequest {
/*
* (non-Javadoc)
*
*
* @see javax.servlet.http.HttpServletRequest#getUserPrincipal()
*/
public Principal getUserPrincipal() {
@@ -277,7 +291,7 @@ public class PortletServletRequest implements HttpServletRequest {
/**
* Not allowed in a portlet.
*
*
* @throws IllegalStateException
* Not allowed in a portlet.
*/
@@ -287,7 +301,7 @@ public class PortletServletRequest implements HttpServletRequest {
/**
* Not allowed in a portlet.
*
*
* @throws IllegalStateException
* Not allowed in a portlet.
*/
@@ -297,7 +311,7 @@ public class PortletServletRequest implements HttpServletRequest {
/**
* Not allowed in a portlet.
*
*
* @throws IllegalStateException
* Not allowed in a portlet.
*/
@@ -305,9 +319,39 @@ public class PortletServletRequest implements HttpServletRequest {
throw new IllegalStateException("Not allowed in a portlet");
}
@Override
public boolean authenticate(HttpServletResponse response) throws IOException, ServletException {
return false;
}
@Override
public void login(String username, String password) throws ServletException {
}
@Override
public void logout() throws ServletException {
}
@Override
public Collection<Part> getParts() throws IOException, ServletException {
return null;
}
@Override
public Part getPart(String name) throws IOException, ServletException {
return null;
}
@Override
public <T extends HttpUpgradeHandler> T upgrade(Class<T> handlerClass) throws IOException, ServletException {
return null;
}
/*
* (non-Javadoc)
*
*
* @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdValid()
*/
public boolean isRequestedSessionIdValid() {
@@ -316,7 +360,7 @@ public class PortletServletRequest implements HttpServletRequest {
/*
* (non-Javadoc)
*
*
* @see javax.servlet.http.HttpServletRequest#isUserInRole(java.lang.String)
*/
public boolean isUserInRole(String role) {
@@ -327,7 +371,7 @@ public class PortletServletRequest implements HttpServletRequest {
* Gets an attribute value on the {@link PortletRequest}. If the attribute
* name is <tt>javax.servlet.include.servlet_path</tt>, it returns the
* same as {@link PortletServletRequest#getServletPath()}
*
*
* @see javax.servlet.ServletRequest#getAttribute(java.lang.String)
*/
public Object getAttribute(String name) {
@@ -340,7 +384,7 @@ public class PortletServletRequest implements HttpServletRequest {
/*
* (non-Javadoc)
*
*
* @see javax.servlet.ServletRequest#getAttributeNames()
*/
public Enumeration getAttributeNames() {
@@ -349,7 +393,7 @@ public class PortletServletRequest implements HttpServletRequest {
/**
* Can only be invoked in the event phase.
*
*
* @see ServletRequest#getCharacterEncoding()
* @throws IllegalStateException
* If the portlet is not in the event phase.
@@ -364,7 +408,7 @@ public class PortletServletRequest implements HttpServletRequest {
/**
* Can only be invoked in the event phase.
*
*
* @see ServletRequest#getContentLength()
* @throws IllegalStateException
* If the portlet is not in the event phase.
@@ -377,9 +421,14 @@ public class PortletServletRequest implements HttpServletRequest {
}
}
@Override
public long getContentLengthLong() {
return 0;
}
/**
* Can only be invoked in the event phase.
*
*
* @see ServletRequest#getContentType()
* @throws IllegalStateException
* If the portlet is not in the event phase.
@@ -396,7 +445,7 @@ public class PortletServletRequest implements HttpServletRequest {
* Can only be invoked in the event phase. When invoked in the event phase,
* it will wrap the portlet's {@link InputStream} as a
* {@link PortletServletInputStream}.
*
*
* @see ServletRequest#getInputStream()
* @throws IllegalStateException
* If the portlet is not in the event phase.
@@ -412,7 +461,7 @@ public class PortletServletRequest implements HttpServletRequest {
/**
* Not allowed in a portlet.
*
*
* @throws IllegalStateException
* Not allowed in a portlet.
*/
@@ -425,7 +474,7 @@ public class PortletServletRequest implements HttpServletRequest {
/**
* Not allowed in a portlet.
*
*
* @throws IllegalStateException
* Not allowed in a portlet.
*/
@@ -438,7 +487,7 @@ public class PortletServletRequest implements HttpServletRequest {
/**
* Not allowed in a portlet.
*
*
* @throws IllegalStateException
* Not allowed in a portlet.
*/
@@ -449,9 +498,44 @@ public class PortletServletRequest implements HttpServletRequest {
throw new IllegalStateException("Not allowed in a portlet");
}
@Override
public ServletContext getServletContext() {
return null;
}
@Override
public AsyncContext startAsync() throws IllegalStateException {
return null;
}
@Override
public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) throws IllegalStateException {
return null;
}
@Override
public boolean isAsyncStarted() {
return false;
}
@Override
public boolean isAsyncSupported() {
return false;
}
@Override
public AsyncContext getAsyncContext() {
return null;
}
@Override
public DispatcherType getDispatcherType() {
return null;
}
/*
* (non-Javadoc)
*
*
* @see javax.servlet.ServletRequest#getLocale()
*/
public Locale getLocale() {
@@ -460,7 +544,7 @@ public class PortletServletRequest implements HttpServletRequest {
/*
* (non-Javadoc)
*
*
* @see javax.servlet.ServletRequest#getLocales()
*/
public Enumeration getLocales() {
@@ -469,7 +553,7 @@ public class PortletServletRequest implements HttpServletRequest {
/*
* (non-Javadoc)
*
*
* @see javax.servlet.ServletRequest#getParameter(java.lang.String)
*/
public String getParameter(String name) {
@@ -485,7 +569,7 @@ public class PortletServletRequest implements HttpServletRequest {
/*
* (non-Javadoc)
*
*
* @see javax.servlet.ServletRequest#getParameterMap()
*/
public Map getParameterMap() {
@@ -494,7 +578,7 @@ public class PortletServletRequest implements HttpServletRequest {
/*
* (non-Javadoc)
*
*
* @see javax.servlet.ServletRequest#getParameterNames()
*/
public Enumeration getParameterNames() {
@@ -503,7 +587,7 @@ public class PortletServletRequest implements HttpServletRequest {
/*
* (non-Javadoc)
*
*
* @see javax.servlet.ServletRequest#getParameterValues(java.lang.String)
*/
public String[] getParameterValues(String name) {
@@ -512,7 +596,7 @@ public class PortletServletRequest implements HttpServletRequest {
/**
* Not allowed in a portlet.
*
*
* @throws IllegalStateException
* Not allowed in a portlet.
*/
@@ -525,7 +609,7 @@ public class PortletServletRequest implements HttpServletRequest {
/**
* Can only be invoked in the event phase.
*
*
* @see ServletRequest#getReader()
* @throws IllegalStateException
* If the portlet is not in the event phase.
@@ -540,7 +624,7 @@ public class PortletServletRequest implements HttpServletRequest {
/*
* (non-Javadoc)
*
*
* @see javax.servlet.ServletRequest#getRealPath(java.lang.String)
*/
public String getRealPath(String path) {
@@ -549,7 +633,7 @@ public class PortletServletRequest implements HttpServletRequest {
/**
* Not allowed in a portlet.
*
*
* @throws IllegalStateException
* Not allowed in a portlet.
*/
@@ -562,7 +646,7 @@ public class PortletServletRequest implements HttpServletRequest {
/**
* Not allowed in a portlet.
*
*
* @throws IllegalStateException
* Not allowed in a portlet.
*/
@@ -575,7 +659,7 @@ public class PortletServletRequest implements HttpServletRequest {
/**
* Not allowed in a portlet.
*
*
* @throws IllegalStateException
* Not allowed in a portlet.
*/
@@ -589,7 +673,7 @@ public class PortletServletRequest implements HttpServletRequest {
/**
* Get the {@link PortletRequestDispatcher} as a
* {@link PortletServletRequestDispatcher} instance.
*
*
* @see javax.servlet.ServletRequest#getRequestDispatcher(java.lang.String)
*/
public RequestDispatcher getRequestDispatcher(String path) {
@@ -599,7 +683,7 @@ public class PortletServletRequest implements HttpServletRequest {
/*
* (non-Javadoc)
*
*
* @see javax.servlet.ServletRequest#getScheme()
*/
public String getScheme() {
@@ -608,7 +692,7 @@ public class PortletServletRequest implements HttpServletRequest {
/*
* (non-Javadoc)
*
*
* @see javax.servlet.ServletRequest#getServerName()
*/
public String getServerName() {
@@ -617,7 +701,7 @@ public class PortletServletRequest implements HttpServletRequest {
/**
* Not allowed in a portlet.
*
*
* @throws IllegalStateException
* Not allowed in a portlet.
*/
@@ -630,7 +714,7 @@ public class PortletServletRequest implements HttpServletRequest {
/*
* (non-Javadoc)
*
*
* @see javax.servlet.ServletRequest#isSecure()
*/
public boolean isSecure() {
@@ -639,7 +723,7 @@ public class PortletServletRequest implements HttpServletRequest {
/*
* (non-Javadoc)
*
*
* @see javax.servlet.ServletRequest#removeAttribute(java.lang.String)
*/
public void removeAttribute(String name) {
@@ -648,7 +732,7 @@ public class PortletServletRequest implements HttpServletRequest {
/*
* (non-Javadoc)
*
*
* @see javax.servlet.ServletRequest#setAttribute(java.lang.String,
* java.lang.Object)
*/
@@ -658,7 +742,7 @@ public class PortletServletRequest implements HttpServletRequest {
/**
* Can only be invoked in the event phase.
*
*
* @see ServletRequest#setCharacterEncoding(String)
* @throws IllegalStateException
* If the portlet is not in the event phase.
@@ -674,7 +758,7 @@ public class PortletServletRequest implements HttpServletRequest {
/**
* Get the wrapped {@link PortletRequest} instance.
*
*
* @return The wrapped {@link PortletRequest} instance.
*/
public PortletRequest getPortletRequest() {
@@ -20,6 +20,7 @@ package org.apache.struts2.portlet.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.Locale;
import javax.portlet.PortletResponse;
@@ -31,11 +32,11 @@ import javax.servlet.http.HttpServletResponse;
public class PortletServletResponse implements HttpServletResponse {
protected PortletResponse portletResponse;
public PortletServletResponse(PortletResponse portletResponse) {
this.portletResponse = portletResponse;
}
public void addCookie(Cookie cookie) {
throw new IllegalStateException("Not allowed in a portlet");
}
@@ -104,6 +105,26 @@ public class PortletServletResponse implements HttpServletResponse {
throw new IllegalStateException("Not allowed in a portlet");
}
@Override
public int getStatus() {
return 0;
}
@Override
public String getHeader(String name) {
return null;
}
@Override
public Collection<String> getHeaders(String name) {
return null;
}
@Override
public Collection<String> getHeaderNames() {
return null;
}
public void flushBuffer() throws IOException {
if(portletResponse instanceof RenderResponse) {
((RenderResponse)portletResponse).flushBuffer();
@@ -211,6 +232,11 @@ public class PortletServletResponse implements HttpServletResponse {
throw new IllegalStateException("Not allowed in a portlet");
}
@Override
public void setContentLengthLong(long len) {
}
public void setContentType(String type) {
if(portletResponse instanceof RenderResponse) {
((RenderResponse)portletResponse).setContentType(type);
+1 -11
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<artifactId>struts2-rest-plugin</artifactId>
@@ -96,16 +96,6 @@
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<!-- The Servlet API mocks in Spring Framework 4.x only supports Servlet 3.0 and higher.
This is only necessary in tests-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
@@ -34,23 +34,22 @@ import java.io.InputStreamReader;
*/
public class ContentTypeInterceptor extends AbstractInterceptor {
private static final long serialVersionUID = 1L;
ContentTypeHandlerManager selector;
private final ContentTypeHandlerManager selector;
@Inject
public void setContentTypeHandlerSelector(ContentTypeHandlerManager sel) {
this.selector = sel;
public ContentTypeInterceptor(ContentTypeHandlerManager selector) {
this.selector = selector;
}
public String intercept(ActionInvocation invocation) throws Exception {
HttpServletRequest request = ServletActionContext.getRequest();
ContentTypeHandler handler = selector.getHandlerForRequest(request);
Object target = invocation.getAction();
if (target instanceof ModelDriven) {
target = ((ModelDriven)target).getModel();
target = ((ModelDriven<?>)target).getModel();
}
if (request.getContentLength() > 0) {
InputStream is = request.getInputStream();
InputStreamReader reader = new InputStreamReader(is);
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<artifactId>struts2-sitemesh-plugin</artifactId>
+7 -16
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<artifactId>struts2-spring-plugin</artifactId>
@@ -51,13 +51,13 @@
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
@@ -80,30 +80,21 @@
<artifactId>commons-jci-fam</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<scope>test</scope>
</dependency>
<!-- The Servlet API mocks in Spring Framework 4.0 support Servlet 3.0 and higher
So this is only necessary in tests-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
@@ -45,7 +45,7 @@ public class SecurityMemberAccessProxyTest extends XWorkTestCase {
ActionProxy proxy = actionProxyFactory.createActionProxy(null,
"chaintoAOPedTestSubBeanAction", null, context);
SecurityMemberAccess sma = new SecurityMemberAccess(false, true);
SecurityMemberAccess sma = new SecurityMemberAccess(true);
sma.setDisallowProxyMemberAccess(true);
Member member = proxy.getAction().getClass().getMethod("isExposeProxy");
@@ -58,7 +58,7 @@ public class SecurityMemberAccessProxyTest extends XWorkTestCase {
ActionProxy proxy = actionProxyFactory.createActionProxy(null,
"chaintoAOPedTestSubBeanAction", null, context);
SecurityMemberAccess sma = new SecurityMemberAccess(false, true);
SecurityMemberAccess sma = new SecurityMemberAccess(true);
Member member = proxy.getAction().getClass().getMethod("isExposeProxy");
@@ -0,0 +1,69 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.test;
import com.opensymphony.xwork2.ActionProxy;
import com.opensymphony.xwork2.XWorkTestCase;
import com.opensymphony.xwork2.config.providers.XmlConfigurationProvider;
import com.opensymphony.xwork2.ognl.SecurityMemberAccess;
import org.apache.struts2.config.StrutsXmlConfigurationProvider;
import java.lang.reflect.Member;
import java.util.HashMap;
import java.util.Map;
public class SecurityMemberAccessProxyTest extends XWorkTestCase {
private Map<String, Object> context;
@Override
public void setUp() throws Exception {
super.setUp();
context = new HashMap<>();
// Set up XWork
XmlConfigurationProvider provider = new StrutsXmlConfigurationProvider("com/opensymphony/xwork2/spring/actionContext-xwork.xml");
container.inject(provider);
loadConfigurationProviders(provider);
}
public void testProxyAccessIsBlocked() throws Exception {
ActionProxy proxy = actionProxyFactory.createActionProxy(null,
"chaintoAOPedTestSubBeanAction", null, context);
SecurityMemberAccess sma = new SecurityMemberAccess(true);
sma.setDisallowProxyMemberAccess(true);
Member member = proxy.getAction().getClass().getMethod("isExposeProxy");
boolean accessible = sma.isAccessible(context, proxy.getAction(), member, "");
assertFalse(accessible);
}
public void testProxyAccessIsAccessible() throws Exception {
ActionProxy proxy = actionProxyFactory.createActionProxy(null,
"chaintoAOPedTestSubBeanAction", null, context);
SecurityMemberAccess sma = new SecurityMemberAccess(true);
Member member = proxy.getAction().getClass().getMethod("isExposeProxy");
boolean accessible = sma.isAccessible(context, proxy.getAction(), member, "");
assertTrue(accessible);
}
}
+4 -12
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<artifactId>struts2-testng-plugin</artifactId>
@@ -51,18 +51,10 @@
<artifactId>jsp-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- The Servlet API mocks in Spring Framework 4.x only supports Servlet 3.0 and higher.
This is only necessary in tests-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
+1 -1
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<artifactId>struts2-tiles-plugin</artifactId>
+2 -11
View File
@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-plugins</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</version>
</parent>
<artifactId>struts2-velocity-plugin</artifactId>
@@ -51,7 +51,7 @@
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<dependency>
@@ -59,15 +59,6 @@
<artifactId>jsp-api</artifactId>
</dependency>
<!-- The Servlet API mocks in Spring Framework 4.0 support Servlet 3.0 and higher
So this is only necessary in tests-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mockobjects</groupId>
<artifactId>mockobjects-core</artifactId>
+29 -32
View File
@@ -29,7 +29,7 @@
<modelVersion>4.0.0</modelVersion>
<artifactId>struts2-parent</artifactId>
<version>6.0.0-SNAPSHOT</version>
<version>6.0.0</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>HEAD</tag>
<tag>STRUTS_6_0_0</tag>
</scm>
<issueManagement>
@@ -104,17 +104,18 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.outputTimestamp>2022-02-24T06:11:22Z</project.build.outputTimestamp>
<java.version>1.8</java.version>
<project.build.outputTimestamp>2022-06-02T07:06:42Z</project.build.outputTimestamp>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<!-- dependency versions in alphanumeric order -->
<asm.version>9.2</asm.version>
<jackson.version>2.10.5</jackson.version>
<jackson-databind.version>2.10.5.1</jackson-databind.version>
<jackson.version>2.13.2</jackson.version>
<jackson-databind.version>2.13.2.1</jackson-databind.version>
<log4j2.version>2.17.2</log4j2.version>
<ognl.version>3.3.2</ognl.version>
<slf4j.version>1.7.32</slf4j.version>
<spring.platformVersion>4.3.30.RELEASE</spring.platformVersion>
<spring.platformVersion>5.3.20</spring.platformVersion>
<tiles.version>3.0.8</tiles.version>
<tiles-request.version>1.0.7</tiles-request.version>
<maven-surefire-plugin.version>3.0.0-M4</maven-surefire-plugin.version>
@@ -235,7 +236,7 @@
</configuration>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<configuration>
<jvmArgs>${argLine}</jvmArgs>
@@ -247,7 +248,7 @@
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.5</version>
<version>0.8.8</version>
<executions>
<execution>
<id>prepare-agent</id>
@@ -264,9 +265,9 @@
</executions>
</plugin>
<plugin>
<groupId>org.eluder.coveralls</groupId>
<groupId>io.jsonwebtoken.coveralls</groupId>
<artifactId>coveralls-maven-plugin</artifactId>
<version>4.3.0</version>
<version>4.4.1</version>
</plugin>
</plugins>
</build>
@@ -316,7 +317,7 @@
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>5.1.3</version>
<version>5.1.6</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -377,7 +378,7 @@
<plugin>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<version>6.5.1</version>
<version>7.0.1</version>
<configuration>
<suppressionFiles>
<suppressionFile>src/etc/project-suppression.xml</suppressionFile>
@@ -405,18 +406,15 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-wrapper-plugin</artifactId>
<version>3.1.0</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
@@ -480,7 +478,11 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-wrapper-plugin</artifactId>
<version>3.1.0</version>
</plugin>
</plugins>
<defaultGoal>install</defaultGoal>
@@ -704,7 +706,7 @@
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.30</version>
<version>2.3.31</version>
</dependency>
<dependency>
@@ -795,7 +797,7 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<version>4.13.1</version>
</dependency>
<dependency>
@@ -807,8 +809,8 @@
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
@@ -986,11 +988,6 @@
<artifactId>spring-core</artifactId>
<version>${spring.platformVersion}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc-portlet</artifactId>
<version>${spring.platformVersion}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
@@ -1218,7 +1215,7 @@
<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>2.12.0</version>
<version>2.12.2</version>
<scope>test</scope>
</dependency>