diff --git a/apps/pom.xml b/apps/pom.xml index 072f8f3495..c8104be666 100644 --- a/apps/pom.xml +++ b/apps/pom.xml @@ -24,7 +24,7 @@ org.apache.struts struts2-parent - 2.5.30 + 2.5.31 struts2-apps pom diff --git a/apps/rest-showcase/pom.xml b/apps/rest-showcase/pom.xml index 8e22644334..ea071d1548 100644 --- a/apps/rest-showcase/pom.xml +++ b/apps/rest-showcase/pom.xml @@ -24,12 +24,12 @@ org.apache.struts struts2-apps - 2.5.30 + 2.5.31 struts2-rest-showcase war - 2.5.30 + 2.5.31 Struts 2 Rest Showcase Webapp Struts 2 Rest Showcase Example diff --git a/apps/showcase/pom.xml b/apps/showcase/pom.xml index 5a14232ed6..de37179a36 100644 --- a/apps/showcase/pom.xml +++ b/apps/showcase/pom.xml @@ -24,7 +24,7 @@ org.apache.struts struts2-apps - 2.5.30 + 2.5.31 struts2-showcase diff --git a/assembly/pom.xml b/assembly/pom.xml index bc9d787110..bad2a2ce1d 100644 --- a/assembly/pom.xml +++ b/assembly/pom.xml @@ -24,7 +24,7 @@ org.apache.struts struts2-parent - 2.5.30 + 2.5.31 struts2-assembly diff --git a/bom/pom.xml b/bom/pom.xml index cd1f5ff656..0aafe393da 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -30,7 +30,7 @@ struts2-bom - 2.5.30 + 2.5.31 pom Struts 2 Bill of Materials @@ -45,7 +45,7 @@ - 2.5.30 + 2.5.31 true true @@ -181,7 +181,7 @@ - STRUTS_2_5_30 + STRUTS_2_5_31 scm:git:https://gitbox.apache.org/repos/asf/struts.git scm:git:https://gitbox.apache.org/repos/asf/struts.git https://github.com/apache/struts/ diff --git a/bundles/admin/pom.xml b/bundles/admin/pom.xml index 1f7c2a8280..80bb51e6a4 100644 --- a/bundles/admin/pom.xml +++ b/bundles/admin/pom.xml @@ -24,7 +24,7 @@ org.apache.struts struts2-osgi-bundles - 2.5.30 + 2.5.31 struts2-osgi-admin-bundle diff --git a/bundles/demo/pom.xml b/bundles/demo/pom.xml index 7d4973c28c..2ce9cc10b8 100644 --- a/bundles/demo/pom.xml +++ b/bundles/demo/pom.xml @@ -24,7 +24,7 @@ org.apache.struts struts2-osgi-bundles - 2.5.30 + 2.5.31 struts2-osgi-demo-bundle diff --git a/bundles/pom.xml b/bundles/pom.xml index 1bdf7b4b10..9122ba34c2 100755 --- a/bundles/pom.xml +++ b/bundles/pom.xml @@ -24,7 +24,7 @@ org.apache.struts struts2-parent - 2.5.30 + 2.5.31 struts2-osgi-bundles diff --git a/core/pom.xml b/core/pom.xml index cb1d90e185..827b0d244f 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -24,7 +24,7 @@ org.apache.struts struts2-parent - 2.5.30 + 2.5.31 struts2-core jar diff --git a/core/src/main/java/com/opensymphony/xwork2/ognl/accessor/XWorkListPropertyAccessor.java b/core/src/main/java/com/opensymphony/xwork2/ognl/accessor/XWorkListPropertyAccessor.java index 242d097729..e844c1a0b6 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ognl/accessor/XWorkListPropertyAccessor.java +++ b/core/src/main/java/com/opensymphony/xwork2/ognl/accessor/XWorkListPropertyAccessor.java @@ -115,6 +115,11 @@ public Object getProperty(Map context, Object target, Object name) throws OgnlEx if (listSize <= index) { Object result; + if (index > autoGrowCollectionLimit) { + throw new OgnlException("Error auto growing collection size to " + index + " which limited to " + + autoGrowCollectionLimit); + } + for (int i = listSize; i < index; i++) { list.add(null); } diff --git a/core/src/main/java/org/apache/struts2/StrutsConstants.java b/core/src/main/java/org/apache/struts2/StrutsConstants.java index 8c076d24e5..30c1bb6856 100644 --- a/core/src/main/java/org/apache/struts2/StrutsConstants.java +++ b/core/src/main/java/org/apache/struts2/StrutsConstants.java @@ -96,13 +96,13 @@ public final class StrutsConstants { /** Update freemarker templates cache in seconds */ public static final String STRUTS_FREEMARKER_TEMPLATES_CACHE_UPDATE_DELAY = "struts.freemarker.templatesCache.updateDelay"; - + /** Cache model instances at BeanWrapper level */ public static final String STRUTS_FREEMARKER_BEANWRAPPER_CACHE = "struts.freemarker.beanwrapperCache"; - + /** Maximum strong sizing for MruCacheStorage for freemarker */ public static final String STRUTS_FREEMARKER_MRU_MAX_STRONG_SIZE = "struts.freemarker.mru.max.strong.size"; - + /** org.apache.struts2.views.velocity.VelocityManager implementation class */ public static final String STRUTS_VELOCITY_MANAGER_CLASSNAME = "struts.velocity.manager.classname"; @@ -127,6 +127,9 @@ public final class StrutsConstants { /** The maximize size of a multipart request (file upload) */ public static final String STRUTS_MULTIPART_MAXSIZE = "struts.multipart.maxSize"; + /** The maximum length of a string parameter in a multipart request. */ + public static final String STRUTS_MULTIPART_MAX_STRING_LENGTH = "struts.multipart.maxStringLength"; + /** The directory to use for storing uploaded files */ public static final String STRUTS_MULTIPART_SAVEDIR = "struts.multipart.saveDir"; @@ -180,7 +183,7 @@ public final class StrutsConstants { * You can specify different prefixes that will be handled by different mappers */ public static final String PREFIX_BASED_MAPPER_CONFIGURATION = "struts.mapper.prefixMapping"; - + /** Whether the Struts filter should serve static content or not */ public static final String STRUTS_SERVE_STATIC_CONTENT = "struts.serve.static"; diff --git a/core/src/main/java/org/apache/struts2/dispatcher/multipart/AbstractMultiPartRequest.java b/core/src/main/java/org/apache/struts2/dispatcher/multipart/AbstractMultiPartRequest.java index 700364047b..76cf75ba82 100644 --- a/core/src/main/java/org/apache/struts2/dispatcher/multipart/AbstractMultiPartRequest.java +++ b/core/src/main/java/org/apache/struts2/dispatcher/multipart/AbstractMultiPartRequest.java @@ -54,6 +54,11 @@ public abstract class AbstractMultiPartRequest implements MultiPartRequest { protected long maxSize; protected boolean maxSizeProvided; + /** + * Specifies the maximum length of a string parameter in a multipart request. + */ + protected Long maxStringLength; + /** * Specifies the buffer size to use during streaming. */ @@ -88,6 +93,11 @@ public void setMaxSize(String maxSize) { this.maxSize = Long.parseLong(maxSize); } + @Inject(StrutsConstants.STRUTS_MULTIPART_MAX_STRING_LENGTH) + public void setMaxStringLength(String maxStringLength) { + this.maxStringLength = Long.parseLong(maxStringLength); + } + @Inject public void setLocaleProviderFactory(LocaleProviderFactory localeProviderFactory) { defaultLocale = localeProviderFactory.createLocaleProvider().getLocale(); @@ -134,9 +144,9 @@ protected String getCanonicalName(final String originalFileName) { int forwardSlash = fileName.lastIndexOf('/'); int backwardSlash = fileName.lastIndexOf('\\'); if (forwardSlash != -1 && forwardSlash > backwardSlash) { - fileName = fileName.substring(forwardSlash + 1, fileName.length()); + fileName = fileName.substring(forwardSlash + 1); } else { - fileName = fileName.substring(backwardSlash + 1, fileName.length()); + fileName = fileName.substring(backwardSlash + 1); } return fileName; } diff --git a/core/src/main/java/org/apache/struts2/dispatcher/multipart/JakartaMultiPartRequest.java b/core/src/main/java/org/apache/struts2/dispatcher/multipart/JakartaMultiPartRequest.java index 800d542802..5b03a262ea 100644 --- a/core/src/main/java/org/apache/struts2/dispatcher/multipart/JakartaMultiPartRequest.java +++ b/core/src/main/java/org/apache/struts2/dispatcher/multipart/JakartaMultiPartRequest.java @@ -25,6 +25,7 @@ import org.apache.commons.fileupload.disk.DiskFileItem; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; +import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.struts2.dispatcher.LocalizedMessage; @@ -55,9 +56,8 @@ public class JakartaMultiPartRequest extends AbstractMultiPartRequest { * * @param saveDir the directory to save off the file * @param request the request containing the multipart - * @throws java.io.IOException is thrown if encoding fails. */ - public void parse(HttpServletRequest request, String saveDir) throws IOException { + public void parse(HttpServletRequest request, String saveDir) { try { setLocale(request); processUpload(request, saveDir); @@ -126,13 +126,26 @@ protected void processNormalFormField(FileItem item, String charset) throws Unsu values = new ArrayList<>(); } - // note: see http://jira.opensymphony.com/browse/WW-633 - // basically, in some cases the charset may be null, so - // we're just going to try to "other" method (no idea if this - // will work) - if (charset != null) { + long size = item.getSize(); + if (size == 0) { + values.add(StringUtils.EMPTY); + } else if (size > maxStringLength) { + String errorKey = "struts.messages.upload.error.parameter.too.long"; + LocalizedMessage localizedMessage = new LocalizedMessage(this.getClass(), errorKey, null, + new Object[] { item.getFieldName(), maxStringLength, size }); + + if (!errors.contains(localizedMessage)) { + errors.add(localizedMessage); + } + return; + + } else if (charset != null) { values.add(item.getString(charset)); } else { + // note: see http://jira.opensymphony.com/browse/WW-633 + // basically, in some cases the charset may be null, so + // we're just going to try to "other" method (no idea if this + // will work) values.add(item.getString()); } params.put(item.getFieldName(), values); @@ -183,7 +196,7 @@ public String[] getContentType(String fieldName) { contentTypes.add(fileItem.getContentType()); } - return contentTypes.toArray(new String[contentTypes.size()]); + return contentTypes.toArray(new String[0]); } /* (non-Javadoc) @@ -209,7 +222,7 @@ public UploadedFile[] getFile(String fieldName) { fileList.add(new StrutsUploadedFile(storeLocation)); } - return fileList.toArray(new UploadedFile[fileList.size()]); + return fileList.toArray(new UploadedFile[0]); } /* (non-Javadoc) @@ -227,7 +240,7 @@ public String[] getFileNames(String fieldName) { fileNames.add(getCanonicalName(fileItem.getName())); } - return fileNames.toArray(new String[fileNames.size()]); + return fileNames.toArray(new String[0]); } /* (non-Javadoc) @@ -245,7 +258,7 @@ public String[] getFilesystemName(String fieldName) { fileNames.add(((DiskFileItem) fileItem).getStoreLocation().getName()); } - return fileNames.toArray(new String[fileNames.size()]); + return fileNames.toArray(new String[0]); } /* (non-Javadoc) @@ -253,7 +266,7 @@ public String[] getFilesystemName(String fieldName) { */ public String getParameter(String name) { List v = params.get(name); - if (v != null && v.size() > 0) { + if (v != null && !v.isEmpty()) { return v.get(0); } @@ -272,8 +285,8 @@ public Enumeration getParameterNames() { */ public String[] getParameterValues(String name) { List v = params.get(name); - if (v != null && v.size() > 0) { - return v.toArray(new String[v.size()]); + if (v != null && !v.isEmpty()) { + return v.toArray(new String[0]); } return null; diff --git a/core/src/main/resources/org/apache/struts2/default.properties b/core/src/main/resources/org/apache/struts2/default.properties index c84452d2e1..3e2ef95bb5 100644 --- a/core/src/main/resources/org/apache/struts2/default.properties +++ b/core/src/main/resources/org/apache/struts2/default.properties @@ -68,6 +68,7 @@ struts.multipart.parser=jakarta # uses javax.servlet.context.tempdir by default struts.multipart.saveDir= struts.multipart.maxSize=2097152 +struts.multipart.maxStringLength=4096 ### Load custom property files (does not override struts.properties!) # struts.custom.properties=application,org/apache/struts2/extension/custom diff --git a/core/src/main/resources/org/apache/struts2/struts-messages.properties b/core/src/main/resources/org/apache/struts2/struts-messages.properties index aa6e842e40..3a01420f64 100644 --- a/core/src/main/resources/org/apache/struts2/struts-messages.properties +++ b/core/src/main/resources/org/apache/struts2/struts-messages.properties @@ -26,6 +26,7 @@ struts.messages.invalid.content.type=Could not find a Content-Type for {0}. Veri struts.messages.removing.file=Removing file {0} {1} struts.messages.error.uploading=Error uploading: {0} struts.messages.error.file.too.large=File {0} is too large to be uploaded. Maximum allowed size is {4} bytes! +struts.messages.upload.error.parameter.too.long=The request parameter "{0}" was too long. Max length allowed is {1}, but found {2}! struts.messages.error.content.type.not.allowed=Content-Type not allowed: {0} "{1}" "{2}" {3} struts.messages.error.file.extension.not.allowed=File extension not allowed: {0} "{1}" "{2}" {3} diff --git a/core/src/test/java/com/opensymphony/xwork2/ognl/accessor/XWorkListPropertyAccessorTest.java b/core/src/test/java/com/opensymphony/xwork2/ognl/accessor/XWorkListPropertyAccessorTest.java index 542efda777..a5da080a09 100644 --- a/core/src/test/java/com/opensymphony/xwork2/ognl/accessor/XWorkListPropertyAccessorTest.java +++ b/core/src/test/java/com/opensymphony/xwork2/ognl/accessor/XWorkListPropertyAccessorTest.java @@ -22,7 +22,7 @@ import com.opensymphony.xwork2.XWorkTestCase; import com.opensymphony.xwork2.util.ListHolder; import com.opensymphony.xwork2.util.ValueStack; -import ognl.ListPropertyAccessor; +import com.opensymphony.xwork2.util.reflection.ReflectionContextState; import ognl.PropertyAccessor; import java.util.ArrayList; @@ -42,11 +42,11 @@ public void testContains() { assertNotNull(listHolder.getLongs()); assertEquals(3, listHolder.getLongs().size()); - assertEquals(new Long(1), (Long) listHolder.getLongs().get(0)); - assertEquals(new Long(2), (Long) listHolder.getLongs().get(1)); - assertEquals(new Long(3), (Long) listHolder.getLongs().get(2)); + assertEquals(new Long(1), listHolder.getLongs().get(0)); + assertEquals(new Long(2), listHolder.getLongs().get(1)); + assertEquals(new Long(3), listHolder.getLongs().get(2)); - assertTrue(((Boolean) vs.findValue("longs.contains(1)")).booleanValue()); + assertTrue((Boolean) vs.findValue("longs.contains(1)")); } public void testCanAccessListSizeProperty() { @@ -60,8 +60,8 @@ public void testCanAccessListSizeProperty() { vs.push(listHolder); - assertEquals(new Integer(myList.size()), vs.findValue("strings.size()")); - assertEquals(new Integer(myList.size()), vs.findValue("strings.size")); + assertEquals(myList.size(), vs.findValue("strings.size()")); + assertEquals(myList.size(), vs.findValue("strings.size")); } public void testAutoGrowthCollectionLimit() { @@ -73,12 +73,14 @@ public void testAutoGrowthCollectionLimit() { listHolder.setStrings(myList); ValueStack vs = ActionContext.getContext().getValueStack(); + ReflectionContextState.setCreatingNullObjects(vs.getContext(), true); vs.push(listHolder); vs.setValue("strings[0]", "a"); vs.setValue("strings[1]", "b"); vs.setValue("strings[2]", "c"); vs.setValue("strings[3]", "d"); + vs.findValue("strings[3]"); assertEquals(3, vs.findValue("strings.size()")); } diff --git a/core/src/test/java/org/apache/struts2/interceptor/FileUploadInterceptorTest.java b/core/src/test/java/org/apache/struts2/interceptor/FileUploadInterceptorTest.java index 3e621b1a4b..14d2feb0ea 100644 --- a/core/src/test/java/org/apache/struts2/interceptor/FileUploadInterceptorTest.java +++ b/core/src/test/java/org/apache/struts2/interceptor/FileUploadInterceptorTest.java @@ -89,7 +89,7 @@ public byte[] getContent() { private File tempDir; private TestAction action; - public void testAcceptFileWithEmptyAllowedTypesAndExtensions() throws Exception { + public void testAcceptFileWithEmptyAllowedTypesAndExtensions() { // when allowed type is empty ValidationAwareSupport validation = new ValidationAwareSupport(); boolean ok = interceptor.acceptFile(action, EMPTY_FILE, "filename", "text/plain", "inputName", validation); @@ -99,7 +99,7 @@ public void testAcceptFileWithEmptyAllowedTypesAndExtensions() throws Exception assertFalse(validation.hasErrors()); } - public void testAcceptFileWithoutEmptyTypes() throws Exception { + public void testAcceptFileWithoutEmptyTypes() { interceptor.setAllowedTypes("text/plain"); // when file is of allowed types @@ -120,7 +120,7 @@ public void testAcceptFileWithoutEmptyTypes() throws Exception { } - public void testAcceptFileWithWildcardContent() throws Exception { + public void testAcceptFileWithWildcardContent() { interceptor.setAllowedTypes("text/*"); ValidationAwareSupport validation = new ValidationAwareSupport(); @@ -139,7 +139,7 @@ public void testAcceptFileWithWildcardContent() throws Exception { assertTrue(validation.hasErrors()); } - public void testAcceptFileWithoutEmptyExtensions() throws Exception { + public void testAcceptFileWithoutEmptyExtensions() { interceptor.setAllowedExtensions(".txt"); // when file is of allowed extensions @@ -168,7 +168,7 @@ public void testAcceptFileWithoutEmptyExtensions() throws Exception { assertFalse(validation.hasErrors()); } - public void testAcceptFileWithNoFile() throws Exception { + public void testAcceptFileWithNoFile() { FileUploadInterceptor interceptor = new FileUploadInterceptor(); interceptor.setAllowedTypes("text/plain"); @@ -188,7 +188,7 @@ public void testAcceptFileWithNoFile() throws Exception { public void testAcceptFileWithMaxSize() throws Exception { interceptor.setAllowedTypes("text/plain"); - interceptor.setMaximumSize(new Long(10)); + interceptor.setMaximumSize(10L); // when file is not of allowed types ValidationAwareSupport validation = new ValidationAwareSupport(); @@ -201,7 +201,7 @@ public void testAcceptFileWithMaxSize() throws Exception { assertFalse(notOk); assertFalse(validation.getFieldErrors().isEmpty()); assertTrue(validation.hasErrors()); - List errors = (List) validation.getFieldErrors().get("inputName"); + List errors = validation.getFieldErrors().get("inputName"); assertEquals(1, errors.size()); String msg = (String) errors.get(0); // the error message should contain at least this test @@ -235,7 +235,7 @@ public void testInvalidContentTypeMultipartRequest() throws Exception { mai.setInvocationContext(ActionContext.getContext()); ActionContext.getContext().setParameters(HttpParameters.create().build()); - ActionContext.getContext().put(ServletActionContext.HTTP_REQUEST, createMultipartRequest(req, 2000)); + ActionContext.getContext().put(ServletActionContext.HTTP_REQUEST, createMultipartRequest(req, 2000, -1)); interceptor.intercept(mai); @@ -257,7 +257,7 @@ public void testNoContentMultipartRequest() throws Exception { mai.setInvocationContext(ActionContext.getContext()); ActionContext.getContext().setParameters(HttpParameters.create().build()); - ActionContext.getContext().put(ServletActionContext.HTTP_REQUEST, createMultipartRequest(req, 2000)); + ActionContext.getContext().put(ServletActionContext.HTTP_REQUEST, createMultipartRequest(req, 2000, -1)); interceptor.intercept(mai); @@ -278,7 +278,7 @@ public void testSuccessUploadOfATextFileMultipartRequest() throws Exception { "Unit test of FileUploadInterceptor" + "\r\n" + "-----1234--\r\n"); - req.setContent(content.getBytes("US-ASCII")); + req.setContent(content.getBytes(StandardCharsets.US_ASCII)); MyFileupAction action = new MyFileupAction(); @@ -288,14 +288,14 @@ public void testSuccessUploadOfATextFileMultipartRequest() throws Exception { mai.setInvocationContext(ActionContext.getContext()); Map param = new HashMap<>(); ActionContext.getContext().setParameters(HttpParameters.create(param).build()); - ActionContext.getContext().put(ServletActionContext.HTTP_REQUEST, createMultipartRequest(req, 2000)); + ActionContext.getContext().put(ServletActionContext.HTTP_REQUEST, createMultipartRequest(req, 2000, -1)); interceptor.intercept(mai); - assertTrue(!action.hasErrors()); + assertFalse(action.hasErrors()); HttpParameters parameters = mai.getInvocationContext().getParameters(); - assertTrue(parameters.keySet().size() == 3); + assertEquals(3, parameters.keySet().size()); UploadedFile[] files = (UploadedFile[]) parameters.get("file").getObject(); String[] fileContentTypes = parameters.get("fileContentType").getMultipleValues(); String[] fileRealFilenames = parameters.get("fileFileName").getMultipleValues(); @@ -303,9 +303,9 @@ public void testSuccessUploadOfATextFileMultipartRequest() throws Exception { assertNotNull(files); assertNotNull(fileContentTypes); assertNotNull(fileRealFilenames); - assertTrue(files.length == 1); - assertTrue(fileContentTypes.length == 1); - assertTrue(fileRealFilenames.length == 1); + assertEquals(1, files.length); + assertEquals(1, fileContentTypes.length); + assertEquals(1, fileRealFilenames.length); assertEquals("text/html", fileContentTypes[0]); assertNotNull("deleteme.txt", fileRealFilenames[0]); } @@ -349,7 +349,7 @@ public void testMultipleAccept() throws Exception { mai.setInvocationContext(ActionContext.getContext()); Map param = new HashMap(); ActionContext.getContext().setParameters(HttpParameters.create(param).build()); - ActionContext.getContext().put(ServletActionContext.HTTP_REQUEST, createMultipartRequest(req, 2000)); + ActionContext.getContext().put(ServletActionContext.HTTP_REQUEST, createMultipartRequest(req, 2000, -1)); interceptor.setAllowedTypes("text/html"); interceptor.intercept(mai); @@ -370,6 +370,54 @@ public void testMultipleAccept() throws Exception { assertNotNull("test1.html", fileRealFilenames[0]); } + public void testMultipartRequestMaxStringLength() throws Exception { + MockHttpServletRequest req = new MockHttpServletRequest(); + req.setCharacterEncoding(StandardCharsets.UTF_8.name()); + req.setMethod("post"); + req.addHeader("Content-type", "multipart/form-data; boundary=---1234"); + + // inspired by the unit tests for jakarta commons fileupload + String content = ("-----1234\r\n" + + "Content-Disposition: form-data; name=\"file\"; filename=\"deleteme.txt\"\r\n" + + "Content-Type: text/html\r\n" + + "\r\n" + + "Unit test of FileUploadInterceptor" + + "\r\n" + + "-----1234\r\n" + + "Content-Disposition: form-data; name=\"normalFormField1\"\r\n" + + "\r\n" + + "it works" + + "\r\n" + + "-----1234\r\n" + + "Content-Disposition: form-data; name=\"normalFormField2\"\r\n" + + "\r\n" + + "long string should not work" + + "\r\n" + + "-----1234--\r\n"); + req.setContent(content.getBytes(StandardCharsets.US_ASCII)); + + MyFileupAction action = container.inject(MyFileupAction.class); + + MockActionInvocation mai = new MockActionInvocation(); + mai.setAction(action); + mai.setResultCode("success"); + mai.setInvocationContext(ActionContext.getContext()); + Map param = new HashMap<>(); + ActionContext.getContext().setParameters(HttpParameters.create(param).build()); + ActionContext.getContext().put(ServletActionContext.HTTP_REQUEST, createMultipartRequest(req, -1, 20)); + + interceptor.intercept(mai); + + assertTrue(action.hasActionErrors()); + + Collection errors = action.getActionErrors(); + assertEquals(1, errors.size()); + String msg = errors.iterator().next(); + assertEquals( + "The request parameter \"normalFormField2\" was too long. Max length allowed is 20, but found 27!", + msg); + } + public void testMultipartRequestLocalizedError() throws Exception { MockHttpServletRequest req = new MockHttpServletRequest(); req.setCharacterEncoding(StandardCharsets.UTF_8.name()); @@ -384,7 +432,7 @@ public void testMultipartRequestLocalizedError() throws Exception { "Unit test of FileUploadInterceptor" + "\r\n" + "-----1234--\r\n"); - req.setContent(content.getBytes("US-ASCII")); + req.setContent(content.getBytes(StandardCharsets.US_ASCII)); MyFileupAction action = container.inject(MyFileupAction.class); @@ -396,7 +444,7 @@ public void testMultipartRequestLocalizedError() throws Exception { ActionContext.getContext().setParameters(HttpParameters.create(param).build()); // set German locale ActionContext.getContext().setLocale(Locale.GERMAN); - ActionContext.getContext().put(ServletActionContext.HTTP_REQUEST, createMultipartRequest(req, 10)); + ActionContext.getContext().put(ServletActionContext.HTTP_REQUEST, createMultipartRequest(req, 10, -1)); interceptor.intercept(mai); @@ -429,9 +477,10 @@ private String encodeTextFile(String bondary, String endline, String name, Strin return sb.toString(); } - private MultiPartRequestWrapper createMultipartRequest(HttpServletRequest req, int maxsize) throws IOException { + private MultiPartRequestWrapper createMultipartRequest(HttpServletRequest req, int maxsize, int maxStringLength) { JakartaMultiPartRequest jak = new JakartaMultiPartRequest(); jak.setMaxSize(String.valueOf(maxsize)); + jak.setMaxStringLength(String.valueOf(maxStringLength)); return new MultiPartRequestWrapper(jak, req, tempDir.getAbsolutePath(), new DefaultLocaleProvider()); } diff --git a/plugins/bean-validation/pom.xml b/plugins/bean-validation/pom.xml index 247b5b0db3..434bb2681b 100644 --- a/plugins/bean-validation/pom.xml +++ b/plugins/bean-validation/pom.xml @@ -24,7 +24,7 @@ org.apache.struts struts2-plugins - 2.5.30 + 2.5.31 4.0.0 diff --git a/plugins/cdi/pom.xml b/plugins/cdi/pom.xml index cecfe2ed18..55a352b8c6 100644 --- a/plugins/cdi/pom.xml +++ b/plugins/cdi/pom.xml @@ -25,7 +25,7 @@ org.apache.struts struts2-plugins - 2.5.30 + 2.5.31 struts2-cdi-plugin diff --git a/plugins/config-browser/pom.xml b/plugins/config-browser/pom.xml index 81b8af5523..07637bcbdf 100644 --- a/plugins/config-browser/pom.xml +++ b/plugins/config-browser/pom.xml @@ -24,7 +24,7 @@ org.apache.struts struts2-plugins - 2.5.30 + 2.5.31 struts2-config-browser-plugin diff --git a/plugins/convention/pom.xml b/plugins/convention/pom.xml index fff48c8058..7eaff285c5 100644 --- a/plugins/convention/pom.xml +++ b/plugins/convention/pom.xml @@ -24,7 +24,7 @@ org.apache.struts struts2-plugins - 2.5.30 + 2.5.31 struts2-convention-plugin diff --git a/plugins/dwr/pom.xml b/plugins/dwr/pom.xml index d12b0fda97..92877711e6 100644 --- a/plugins/dwr/pom.xml +++ b/plugins/dwr/pom.xml @@ -24,7 +24,7 @@ org.apache.struts struts2-plugins - 2.5.30 + 2.5.31 struts2-dwr-plugin diff --git a/plugins/embeddedjsp/pom.xml b/plugins/embeddedjsp/pom.xml index f41e9f2f26..1105900680 100644 --- a/plugins/embeddedjsp/pom.xml +++ b/plugins/embeddedjsp/pom.xml @@ -24,7 +24,7 @@ org.apache.struts struts2-plugins - 2.5.30 + 2.5.31 struts2-embeddedjsp-plugin diff --git a/plugins/gxp/pom.xml b/plugins/gxp/pom.xml index da1a189257..799cf32cb6 100644 --- a/plugins/gxp/pom.xml +++ b/plugins/gxp/pom.xml @@ -24,7 +24,7 @@ org.apache.struts struts2-plugins - 2.5.30 + 2.5.31 struts2-gxp-plugin diff --git a/plugins/jasperreports/pom.xml b/plugins/jasperreports/pom.xml index 1c84526f2b..0b7d1467eb 100644 --- a/plugins/jasperreports/pom.xml +++ b/plugins/jasperreports/pom.xml @@ -24,7 +24,7 @@ org.apache.struts struts2-plugins - 2.5.30 + 2.5.31 struts2-jasperreports-plugin diff --git a/plugins/javatemplates/pom.xml b/plugins/javatemplates/pom.xml index b4c8282d89..5024df4a76 100644 --- a/plugins/javatemplates/pom.xml +++ b/plugins/javatemplates/pom.xml @@ -25,7 +25,7 @@ org.apache.struts struts2-plugins - 2.5.30 + 2.5.31 struts2-javatemplates-plugin diff --git a/plugins/jfreechart/pom.xml b/plugins/jfreechart/pom.xml index 6160573666..45d706ac40 100644 --- a/plugins/jfreechart/pom.xml +++ b/plugins/jfreechart/pom.xml @@ -24,7 +24,7 @@ org.apache.struts struts2-plugins - 2.5.30 + 2.5.31 struts2-jfreechart-plugin diff --git a/plugins/json/pom.xml b/plugins/json/pom.xml index 0516b34a39..8995d0c42d 100644 --- a/plugins/json/pom.xml +++ b/plugins/json/pom.xml @@ -24,7 +24,7 @@ org.apache.struts struts2-plugins - 2.5.30 + 2.5.31 struts2-json-plugin diff --git a/plugins/junit/pom.xml b/plugins/junit/pom.xml index 2afd486998..7b2bc82f83 100644 --- a/plugins/junit/pom.xml +++ b/plugins/junit/pom.xml @@ -24,7 +24,7 @@ org.apache.struts struts2-plugins - 2.5.30 + 2.5.31 struts2-junit-plugin diff --git a/plugins/osgi/pom.xml b/plugins/osgi/pom.xml index 2baed9deca..50e4af79e2 100644 --- a/plugins/osgi/pom.xml +++ b/plugins/osgi/pom.xml @@ -24,7 +24,7 @@ org.apache.struts struts2-plugins - 2.5.30 + 2.5.31 struts2-osgi-plugin diff --git a/plugins/oval/pom.xml b/plugins/oval/pom.xml index f1a5eebf13..c9a3d19d9a 100644 --- a/plugins/oval/pom.xml +++ b/plugins/oval/pom.xml @@ -24,7 +24,7 @@ org.apache.struts struts2-plugins - 2.5.30 + 2.5.31 struts2-oval-plugin diff --git a/plugins/pell-multipart/pom.xml b/plugins/pell-multipart/pom.xml index c67db3118f..00e3f0a1e3 100644 --- a/plugins/pell-multipart/pom.xml +++ b/plugins/pell-multipart/pom.xml @@ -24,7 +24,7 @@ org.apache.struts struts2-plugins - 2.5.30 + 2.5.31 struts2-pell-multipart-plugin diff --git a/plugins/plexus/pom.xml b/plugins/plexus/pom.xml index 0219682b6b..37e41468cd 100644 --- a/plugins/plexus/pom.xml +++ b/plugins/plexus/pom.xml @@ -24,7 +24,7 @@ org.apache.struts struts2-plugins - 2.5.30 + 2.5.31 struts2-plexus-plugin diff --git a/plugins/pom.xml b/plugins/pom.xml index 8e328ffb15..ed1cfa68c7 100644 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -24,7 +24,7 @@ org.apache.struts struts2-parent - 2.5.30 + 2.5.31 struts2-plugins diff --git a/plugins/portlet-tiles/pom.xml b/plugins/portlet-tiles/pom.xml index 6688f0d594..eea101e096 100644 --- a/plugins/portlet-tiles/pom.xml +++ b/plugins/portlet-tiles/pom.xml @@ -24,7 +24,7 @@ org.apache.struts struts2-plugins - 2.5.30 + 2.5.31 struts2-portlet-tiles-plugin diff --git a/plugins/portlet/pom.xml b/plugins/portlet/pom.xml index d03245c35f..c4d4379c8e 100644 --- a/plugins/portlet/pom.xml +++ b/plugins/portlet/pom.xml @@ -24,7 +24,7 @@ org.apache.struts struts2-plugins - 2.5.30 + 2.5.31 struts2-portlet-plugin diff --git a/plugins/rest/pom.xml b/plugins/rest/pom.xml index 9afbf5ef3d..dad9e2d0ff 100644 --- a/plugins/rest/pom.xml +++ b/plugins/rest/pom.xml @@ -24,7 +24,7 @@ org.apache.struts struts2-plugins - 2.5.30 + 2.5.31 struts2-rest-plugin diff --git a/plugins/sitegraph/pom.xml b/plugins/sitegraph/pom.xml index 5ac9967cb6..f58fc415d5 100644 --- a/plugins/sitegraph/pom.xml +++ b/plugins/sitegraph/pom.xml @@ -24,7 +24,7 @@ org.apache.struts struts2-plugins - 2.5.30 + 2.5.31 struts2-sitegraph-plugin diff --git a/plugins/sitemesh/pom.xml b/plugins/sitemesh/pom.xml index 61e2106357..82c845cf73 100644 --- a/plugins/sitemesh/pom.xml +++ b/plugins/sitemesh/pom.xml @@ -24,7 +24,7 @@ org.apache.struts struts2-plugins - 2.5.30 + 2.5.31 struts2-sitemesh-plugin diff --git a/plugins/spring/pom.xml b/plugins/spring/pom.xml index 77c8961c58..999e2f6cc8 100644 --- a/plugins/spring/pom.xml +++ b/plugins/spring/pom.xml @@ -24,7 +24,7 @@ org.apache.struts struts2-plugins - 2.5.30 + 2.5.31 struts2-spring-plugin diff --git a/plugins/testng/pom.xml b/plugins/testng/pom.xml index c3f4ff7f72..281815a408 100644 --- a/plugins/testng/pom.xml +++ b/plugins/testng/pom.xml @@ -24,7 +24,7 @@ org.apache.struts struts2-plugins - 2.5.30 + 2.5.31 struts2-testng-plugin diff --git a/plugins/tiles/pom.xml b/plugins/tiles/pom.xml index cffb292033..42ed29fffd 100644 --- a/plugins/tiles/pom.xml +++ b/plugins/tiles/pom.xml @@ -24,7 +24,7 @@ org.apache.struts struts2-plugins - 2.5.30 + 2.5.31 struts2-tiles-plugin diff --git a/pom.xml b/pom.xml index f4751c757b..74c002c8c7 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ 4.0.0 struts2-parent - 2.5.30 + 2.5.31 pom Struts 2 http://struts.apache.org/ @@ -51,7 +51,7 @@ scm:git:https://gitbox.apache.org/repos/asf/struts.git scm:git:https://gitbox.apache.org/repos/asf/struts.git https://github.com/apache/struts/ - STRUTS_2_5_30 + STRUTS_2_5_31 @@ -96,7 +96,7 @@ UTF-8 - 2022-03-15T13:49:51Z + 2023-06-13T08:01:38Z 3.1.29 @@ -159,7 +159,7 @@ org.apache.maven.plugins maven-javadoc-plugin - -Xdoclint:none + -Xdoclint:none