This is an automated email from the ASF dual-hosted git repository.
lukaszlenart pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/struts.git
The following commit(s) were added to refs/heads/main by this push:
new 972fd8a02 WW-5751 Treat a negative maximumSize as no upload size limit
(#1976)
972fd8a02 is described below
commit 972fd8a02320834ab73082b68cc7baef22f13595
Author: Lukasz Lenart <[email protected]>
AuthorDate: Thu Oct 1 20:45:16 2026 +0200
WW-5751 Treat a negative maximumSize as no upload size limit (#1976)
* WW-5751 fix(core): treat a negative maximumSize as no upload size limit
Since 7.3.0 a maximumSize param that cannot be applied marks the upload
policy unresolved and the upload is rejected. The literal "null" some
configurations used to lift the limit only worked in 7.2.1 because its
conversion error was silently ignored, so it now rejects every upload.
A negative maximumSize, e.g. -1, is now the explicit way to disable the
size check. Before this change -1 rejected every upload.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
* WW-5751 refactor(core): extract the upload size check into a protected
method
exceedsMaximumSize(UploadPolicy, UploadedFile) lets a subclass of the
upload interceptor replace the per-file size check.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
* WW-5751 fix(core): format the too-large message without a maximum size
An overridden exceedsMaximumSize can reject a file when no maximumSize is
configured; formatting the null size then threw IllegalArgumentException
instead of reporting the validation error.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
---------
Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>
---
.../interceptor/AbstractFileUploadInterceptor.java | 17 ++++++-
.../interceptor/ActionFileUploadInterceptor.java | 2 +-
.../apache/struts2/interceptor/UploadPolicy.java | 2 +-
.../ActionFileUploadInterceptorTest.java | 56 ++++++++++++++++++++++
4 files changed, 73 insertions(+), 4 deletions(-)
diff --git
a/core/src/main/java/org/apache/struts2/interceptor/AbstractFileUploadInterceptor.java
b/core/src/main/java/org/apache/struts2/interceptor/AbstractFileUploadInterceptor.java
index dac450b45..4761d2c5b 100644
---
a/core/src/main/java/org/apache/struts2/interceptor/AbstractFileUploadInterceptor.java
+++
b/core/src/main/java/org/apache/struts2/interceptor/AbstractFileUploadInterceptor.java
@@ -98,7 +98,7 @@ public abstract class AbstractFileUploadInterceptor extends
AbstractInterceptor
* effective policy for an invocation is a copy, see
* {@link ActionFileUploadInterceptor#newLazyParams()}.
*
- * @param maximumSize The maximum size in bytes
+ * @param maximumSize The maximum size in bytes, or a negative value for
no limit
*/
public void setMaximumSize(Long maximumSize) {
configuredPolicy.setMaximumSize(maximumSize);
@@ -152,7 +152,7 @@ public abstract class AbstractFileUploadInterceptor extends
AbstractInterceptor
return false;
}
- if (policy.getMaximumSize() != null && policy.getMaximumSize() <
file.length()) {
+ if (exceedsMaximumSize(policy, file)) {
String errMsg = getTextMessage(action,
STRUTS_MESSAGES_ERROR_FILE_TOO_LARGE_KEY, new String[]{
inputName, originalFilename, file.getName(), "" +
file.length(), getMaximumSizeStr(action, policy.getMaximumSize())
});
@@ -182,7 +182,20 @@ public abstract class AbstractFileUploadInterceptor
extends AbstractInterceptor
return errorMessages.isEmpty();
}
+ /**
+ * @param policy - the effective upload policy for this invocation.
+ * @param file - proposed upload file.
+ * @return true if the file is larger than the policy allows; a null or
negative maximum size means no limit.
+ */
+ protected boolean exceedsMaximumSize(UploadPolicy policy, UploadedFile
file) {
+ Long maximumSize = policy.getMaximumSize();
+ return maximumSize != null && maximumSize >= 0 && maximumSize <
file.length();
+ }
+
private String getMaximumSizeStr(Object action, Long maximumSize) {
+ if (maximumSize == null) {
+ return "";
+ }
return
NumberFormat.getNumberInstance(getLocaleProvider(action).getLocale()).format(maximumSize);
}
diff --git
a/core/src/main/java/org/apache/struts2/interceptor/ActionFileUploadInterceptor.java
b/core/src/main/java/org/apache/struts2/interceptor/ActionFileUploadInterceptor.java
index c898275f0..d08bb4173 100644
---
a/core/src/main/java/org/apache/struts2/interceptor/ActionFileUploadInterceptor.java
+++
b/core/src/main/java/org/apache/struts2/interceptor/ActionFileUploadInterceptor.java
@@ -64,7 +64,7 @@ import java.util.List;
* <ul>
* <li>maximumSize (optional) - the maximum size (in bytes) that the
interceptor will allow a file reference to be set
* on the action. Note, this is <b>not</b> related to the various properties
found in struts.properties.
- * Default to approximately 2MB.</li>
+ * Default to approximately 2MB. A negative value, e.g. -1, means no
limit.</li>
* <li>allowedTypes (optional) - a comma separated list of content types (ie:
text/html) that the interceptor will allow
* a file reference to be set on the action. If none is specified allow all
types to be uploaded.</li>
* <li>allowedExtensions (optional) - a comma separated list of file
extensions (ie: .html) that the interceptor will allow
diff --git
a/core/src/main/java/org/apache/struts2/interceptor/UploadPolicy.java
b/core/src/main/java/org/apache/struts2/interceptor/UploadPolicy.java
index 4d03f711a..f9f333dab 100644
--- a/core/src/main/java/org/apache/struts2/interceptor/UploadPolicy.java
+++ b/core/src/main/java/org/apache/struts2/interceptor/UploadPolicy.java
@@ -67,7 +67,7 @@ public class UploadPolicy extends DisableParams {
}
/**
- * @param maximumSize the maximum size in bytes, or null for no limit
+ * @param maximumSize the maximum size in bytes, or null or a negative
value for no limit
*/
public void setMaximumSize(Long maximumSize) {
this.maximumSize = maximumSize;
diff --git
a/core/src/test/java/org/apache/struts2/interceptor/ActionFileUploadInterceptorTest.java
b/core/src/test/java/org/apache/struts2/interceptor/ActionFileUploadInterceptorTest.java
index 22f448408..2d6c4a87d 100644
---
a/core/src/test/java/org/apache/struts2/interceptor/ActionFileUploadInterceptorTest.java
+++
b/core/src/test/java/org/apache/struts2/interceptor/ActionFileUploadInterceptorTest.java
@@ -243,6 +243,62 @@ public class ActionFileUploadInterceptorTest extends
StrutsInternalTestCase {
.contains("The file is too large to be uploaded", "inputName",
"log4j2.xml", "allowed mx size is 10");
}
+ public void testAcceptFileWithNegativeMaxSizeHasNoLimit() throws Exception
{
+ interceptor.setMaximumSize(-1L);
+ ValidationAwareSupport validation = new ValidationAwareSupport();
+
+ URL url = ClassLoaderUtil.getResource("log4j2.xml",
ActionFileUploadInterceptorTest.class);
+ File file = new File(new URI(url.toString()));
+ UploadedFile uploadedFile =
StrutsUploadedFile.Builder.create(file).withContentType("text/html").withOriginalName("filename").build();
+ boolean ok =
interceptor.acceptFile(interceptor.copyConfiguredPolicy(), validation,
uploadedFile, "filename", "text/html", "inputName");
+
+ assertThat(ok).isTrue();
+ assertThat(validation.hasErrors()).isFalse();
+ }
+
+ public void testAcceptFileUsesOverriddenMaximumSizeCheck() throws
Exception {
+ ActionFileUploadInterceptor lenient = new
ActionFileUploadInterceptor() {
+ @Override
+ protected boolean exceedsMaximumSize(UploadPolicy policy,
UploadedFile file) {
+ return false;
+ }
+ };
+ container.inject(lenient);
+ lenient.setMaximumSize(10L);
+ ValidationAwareSupport validation = new ValidationAwareSupport();
+
+ URL url = ClassLoaderUtil.getResource("log4j2.xml",
ActionFileUploadInterceptorTest.class);
+ File file = new File(new URI(url.toString()));
+ UploadedFile uploadedFile =
StrutsUploadedFile.Builder.create(file).withContentType("text/html").withOriginalName("filename").build();
+ boolean ok = lenient.acceptFile(lenient.copyConfiguredPolicy(),
validation, uploadedFile, "filename", "text/html", "inputName");
+
+ assertThat(ok).isTrue();
+ assertThat(validation.hasErrors()).isFalse();
+ }
+
+ public void
testAcceptFileRejectsWithoutMaximumSizeWhenOverrideSaysTooLarge() throws
Exception {
+ ActionFileUploadInterceptor strict = new ActionFileUploadInterceptor()
{
+ @Override
+ protected boolean exceedsMaximumSize(UploadPolicy policy,
UploadedFile file) {
+ return true;
+ }
+ };
+ container.inject(strict);
+ ValidationAwareSupport validation = new ValidationAwareSupport();
+
+ URL url = ClassLoaderUtil.getResource("log4j2.xml",
ActionFileUploadInterceptorTest.class);
+ File file = new File(new URI(url.toString()));
+ UploadedFile uploadedFile =
StrutsUploadedFile.Builder.create(file).withContentType("text/html").withOriginalName("filename").build();
+ boolean ok = strict.acceptFile(strict.copyConfiguredPolicy(),
validation, uploadedFile, "filename", "text/html", "inputName");
+
+ assertThat(ok).isFalse();
+ assertThat(validation.getFieldErrors().get("inputName"))
+ .hasSize(1)
+ .first()
+ .asString()
+ .contains("The file is too large to be uploaded");
+ }
+
public void testNoMultipartRequest() throws Exception {
MyFileUploadAction action = new MyFileUploadAction();