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

reta pushed a commit to branch 3.6.x-fixes
in repository https://gitbox.apache.org/repos/asf/cxf.git

commit 35d62a6d4a3fc369f95f87367f25332895db20c2
Author: Andriy Redko <[email protected]>
AuthorDate: Mon Jun 8 12:05:45 2026 -0400

    Add sensible default value to attachment-max-size property (#3188)
    
    * Add sensible default value to attachment-max-size property
    
    * Address code review comments
---
 .../cxf/attachment/AttachmentDeserializer.java     |  2 +
 .../org/apache/cxf/attachment/AttachmentUtil.java  | 33 ++++++++-------
 .../cxf/attachment/AttachmentDeserializerTest.java | 22 ++++++++++
 .../jaxrs/provider/FormEncodingProviderTest.java   | 49 ++++++++++++++++++++++
 4 files changed, 90 insertions(+), 16 deletions(-)

diff --git 
a/core/src/main/java/org/apache/cxf/attachment/AttachmentDeserializer.java 
b/core/src/main/java/org/apache/cxf/attachment/AttachmentDeserializer.java
index dfe76e6b4b1..71fdbd080ba 100644
--- a/core/src/main/java/org/apache/cxf/attachment/AttachmentDeserializer.java
+++ b/core/src/main/java/org/apache/cxf/attachment/AttachmentDeserializer.java
@@ -62,6 +62,8 @@ public class AttachmentDeserializer {
      * The maximum size of the attachment. Allowed value is any of {@link 
Number} or {@link String}.
      */
     public static final String ATTACHMENT_MAX_SIZE = "attachment-max-size";
+    public static final long DEFAULT_ATTACHMENT_MAX_SIZE =
+        SystemPropertyAction.getInteger("org.apache.cxf.attachment-max-size", 
50 * 1024 * 1024 /* 50 Mb */);
 
     /**
      * The maximum number of attachments permitted in a message. The default 
is 50.
diff --git a/core/src/main/java/org/apache/cxf/attachment/AttachmentUtil.java 
b/core/src/main/java/org/apache/cxf/attachment/AttachmentUtil.java
index f8fdd69216c..ff4bc10584c 100644
--- a/core/src/main/java/org/apache/cxf/attachment/AttachmentUtil.java
+++ b/core/src/main/java/org/apache/cxf/attachment/AttachmentUtil.java
@@ -215,24 +215,25 @@ public final class AttachmentUtil {
         }
 
         Object maxSize = 
message.getContextualProperty(AttachmentDeserializer.ATTACHMENT_MAX_SIZE);
-        if (maxSize != null) {
-            if (maxSize instanceof Number) {
-                long size = ((Number) maxSize).longValue();
-                if (size >= 0) {
-                    bos.setMaxSize(size);
-                } else {
-                    LOG.warning("Max size value overflowed long. Do not set 
max size!");
-                }
-            } else if (maxSize instanceof String) {
-                try {
-                    bos.setMaxSize(Long.parseLong((String) maxSize));
-                } catch (NumberFormatException e) {
-                    throw new IOException("Provided threshold String is not a 
number", e);
-                }
+        if (maxSize == null) {
+            maxSize = AttachmentDeserializer.DEFAULT_ATTACHMENT_MAX_SIZE;
+        }
+        if (maxSize instanceof Number) {
+            long size = ((Number) maxSize).longValue();
+            if (size >= 0) {
+                bos.setMaxSize(size);
             } else {
-                throw new IOException("The value set as " + 
AttachmentDeserializer.ATTACHMENT_MAX_SIZE
-                        + " should be either an instance of Number or String");
+                LOG.warning("The max size value is set to unlimited.");
             }
+        } else if (maxSize instanceof String) {
+            try {
+                bos.setMaxSize(Long.parseLong((String) maxSize));
+            } catch (NumberFormatException e) {
+                throw new IOException("Provided max size String is not a 
number", e);
+            }
+        } else {
+            throw new IOException("The value set as " + 
AttachmentDeserializer.ATTACHMENT_MAX_SIZE
+                    + " should be either an instance of Number or String");
         }
     }
 
diff --git 
a/core/src/test/java/org/apache/cxf/attachment/AttachmentDeserializerTest.java 
b/core/src/test/java/org/apache/cxf/attachment/AttachmentDeserializerTest.java
index a244f44a2d4..7f1c3c7d50c 100644
--- 
a/core/src/test/java/org/apache/cxf/attachment/AttachmentDeserializerTest.java
+++ 
b/core/src/test/java/org/apache/cxf/attachment/AttachmentDeserializerTest.java
@@ -31,7 +31,9 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 import java.util.stream.IntStream;
+import java.util.stream.LongStream;
 
 import javax.activation.DataSource;
 import javax.activation.URLDataSource;
@@ -41,6 +43,7 @@ import javax.xml.parsers.SAXParserFactory;
 import org.xml.sax.helpers.DefaultHandler;
 
 import org.apache.cxf.helpers.IOUtils;
+import org.apache.cxf.io.CacheSizeExceededException;
 import org.apache.cxf.message.Attachment;
 import org.apache.cxf.message.Exchange;
 import org.apache.cxf.message.ExchangeImpl;
@@ -377,6 +380,25 @@ public class AttachmentDeserializerTest {
         assertEquals(-1, m.read(new byte[1000]));
         m.close();
     }
+    
+    @Test
+    public void testDefaultAttachmentMaxSize() throws Exception {
+        final byte[] messageBytes = 
("------=_Part_1\n\nJJJJ\n------=_Part_1\n\n"
+                + "Content-Transfer-Encoding: binary\n\n" +  LongStream
+                    .range(0, 
AttachmentDeserializer.DEFAULT_ATTACHMENT_MAX_SIZE / 3 + 1)
+                    .mapToObj(i -> "=3D")
+                    .collect(Collectors.joining())
+                + "\n------=_Part_1\n").getBytes();
+
+        msg = new MessageImpl();
+        msg.setContent(InputStream.class, new 
ByteArrayInputStream(messageBytes));
+        msg.put(Message.CONTENT_TYPE, "multipart/related");
+        AttachmentDeserializer ad = new AttachmentDeserializer(msg);
+        ad.initializeAttachments();
+
+        // Force it to load the attachments
+        assertThrows(CacheSizeExceededException.class, () -> 
msg.getAttachments().size());
+    }
 
     @Test
     public void testCXF2542() throws Exception {
diff --git 
a/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/FormEncodingProviderTest.java
 
b/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/FormEncodingProviderTest.java
index aa225d34582..99b44bfcfa0 100644
--- 
a/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/FormEncodingProviderTest.java
+++ 
b/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/FormEncodingProviderTest.java
@@ -25,20 +25,35 @@ import java.io.InputStream;
 import java.lang.annotation.Annotation;
 import java.nio.charset.StandardCharsets;
 import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.LongStream;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.Encoded;
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.Form;
 import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedHashMap;
 import javax.ws.rs.core.MultivaluedMap;
 
+import org.apache.cxf.Bus;
+import org.apache.cxf.attachment.AttachmentDeserializer;
+import org.apache.cxf.bus.extension.ExtensionManagerBus;
+import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
 import org.apache.cxf.jaxrs.impl.MetadataMap;
+import org.apache.cxf.jaxrs.model.ProviderInfo;
 import org.apache.cxf.jaxrs.utils.HttpUtils;
+import org.apache.cxf.jaxrs.utils.InjectionUtils;
+import org.apache.cxf.message.ExchangeImpl;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageImpl;
 
 import org.junit.Test;
 
+import static org.hamcrest.CoreMatchers.equalTo;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -142,6 +157,40 @@ public class FormEncodingProviderTest {
         assertEquals("Wrong entry for baz", "4", mvMap.getFirst("baz"));
 
     }
+    
+    @Test
+    public void testWriteMultipartTooLarge() throws Exception {
+        final MultivaluedMap<String, String> headers = new 
MultivaluedHashMap<>();
+        headers.add("Content-Transfer-Encoding", "binary");
+
+        final Bus bus = new ExtensionManagerBus();
+        final Message m = new MessageImpl();
+        m.put(AttachmentDeserializer.ATTACHMENT_PART_HEADERS, headers);
+        m.put(Message.CONTENT_TYPE, "multipart/related");
+
+        final ExchangeImpl exchange = new ExchangeImpl();
+        m.setExchange(exchange);
+        exchange.setInMessage(m);
+
+        FormEncodingProvider<MultipartBody> ferp = new 
FormEncodingProvider<>();
+        InjectionUtils.injectContextFields(ferp, new ProviderInfo<>(ferp, bus, 
false), m);
+        
+        final byte[] messageBytes = 
("------=_Part_1\n\nJJJJ\n------=_Part_1\n\n"
+                + "Content-Transfer-Encoding: binary\n\n" +  LongStream
+                    .range(0, 
AttachmentDeserializer.DEFAULT_ATTACHMENT_MAX_SIZE / 3 + 1)
+                    .mapToObj(i -> "=3D")
+                    .collect(Collectors.joining())
+                + "\n------=_Part_1\n").getBytes();
+        try (ByteArrayInputStream in = new ByteArrayInputStream(messageBytes)) 
{
+            m.setContent(InputStream.class, in);
+   
+            final WebApplicationException ex = 
assertThrows(WebApplicationException.class, 
+                () -> ferp.readFrom(MultipartBody.class, null, new 
Annotation[]{}, 
+                    MediaType.MULTIPART_FORM_DATA_TYPE, null, in));
+            
+            assertThat(ex.getResponse().getStatus(), equalTo(413) /* Request 
Entity Too Large */); 
+        }
+    }
 
     @Test
     public void testWriteMultipleValues() throws Exception {

Reply via email to