You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by co...@apache.org on 2019/09/03 14:45:52 UTC
[cxf] branch 3.3.x-fixes updated: Restrict the number of message
attachments
This is an automated email from the ASF dual-hosted git repository.
coheigea pushed a commit to branch 3.3.x-fixes
in repository https://gitbox.apache.org/repos/asf/cxf.git
The following commit(s) were added to refs/heads/3.3.x-fixes by this push:
new fd85803 Restrict the number of message attachments
fd85803 is described below
commit fd85803a73ad46f36816bcb55ed1c4f4b4c4312d
Author: Colm O hEigeartaigh <co...@apache.org>
AuthorDate: Tue Sep 3 15:45:20 2019 +0100
Restrict the number of message attachments
(cherry picked from commit 6c3990144b56097502aa9f3ec9c06f3031109022)
---
.../cxf/attachment/AttachmentDeserializer.java | 17 +++-
.../cxf/attachment/LazyAttachmentCollection.java | 9 +-
.../cxf/attachment/AttachmentDeserializerTest.java | 109 +++++++++++++++++----
3 files changed, 115 insertions(+), 20 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 60c6f59..aaa299d 100644
--- a/core/src/main/java/org/apache/cxf/attachment/AttachmentDeserializer.java
+++ b/core/src/main/java/org/apache/cxf/attachment/AttachmentDeserializer.java
@@ -54,6 +54,11 @@ public class AttachmentDeserializer {
public static final String ATTACHMENT_MAX_SIZE = "attachment-max-size";
/**
+ * The maximum number of attachments permitted in a message. The default is 50.
+ */
+ public static final String ATTACHMENT_MAX_COUNT = "attachment-max-count";
+
+ /**
* The maximum MIME Header Length. The default is 300.
*/
public static final String ATTACHMENT_MAX_HEADER_SIZE = "attachment-max-header-size";
@@ -109,7 +114,17 @@ public class AttachmentDeserializer {
public void initializeAttachments() throws IOException {
initializeRootMessage();
- attachments = new LazyAttachmentCollection(this);
+ Object maxCountProperty = message.getContextualProperty(AttachmentDeserializer.ATTACHMENT_MAX_COUNT);
+ int maxCount = 50;
+ if (maxCountProperty != null) {
+ if (maxCountProperty instanceof Integer) {
+ maxCount = (Integer)maxCountProperty;
+ } else {
+ maxCount = Integer.parseInt((String)maxCountProperty);
+ }
+ }
+
+ attachments = new LazyAttachmentCollection(this, maxCount);
message.setAttachments(attachments);
}
diff --git a/core/src/main/java/org/apache/cxf/attachment/LazyAttachmentCollection.java b/core/src/main/java/org/apache/cxf/attachment/LazyAttachmentCollection.java
index c44ea21..d866029 100644
--- a/core/src/main/java/org/apache/cxf/attachment/LazyAttachmentCollection.java
+++ b/core/src/main/java/org/apache/cxf/attachment/LazyAttachmentCollection.java
@@ -37,10 +37,12 @@ public class LazyAttachmentCollection
private AttachmentDeserializer deserializer;
private final List<Attachment> attachments = new ArrayList<>();
+ private final int maxAttachmentCount;
- public LazyAttachmentCollection(AttachmentDeserializer deserializer) {
+ public LazyAttachmentCollection(AttachmentDeserializer deserializer, int maxAttachmentCount) {
super();
this.deserializer = deserializer;
+ this.maxAttachmentCount = maxAttachmentCount;
}
public List<Attachment> getLoadedAttachments() {
@@ -50,8 +52,13 @@ public class LazyAttachmentCollection
private void loadAll() {
try {
Attachment a = deserializer.readNext();
+ int count = 0;
while (a != null) {
attachments.add(a);
+ count++;
+ if (count > maxAttachmentCount) {
+ throw new IOException("The message contains more attachments than are permitted");
+ }
a = deserializer.readNext();
}
} catch (IOException e) {
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 48cfc1b..8f32fa3 100644
--- a/core/src/test/java/org/apache/cxf/attachment/AttachmentDeserializerTest.java
+++ b/core/src/test/java/org/apache/cxf/attachment/AttachmentDeserializerTest.java
@@ -20,7 +20,6 @@ package org.apache.cxf.attachment;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
-import java.io.IOException;
import java.io.InputStream;
import java.io.PushbackInputStream;
import java.nio.charset.StandardCharsets;
@@ -31,6 +30,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import java.util.stream.IntStream;
import javax.activation.DataSource;
import javax.xml.parsers.SAXParser;
@@ -53,6 +53,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
public class AttachmentDeserializerTest {
@@ -466,32 +467,17 @@ public class AttachmentDeserializerTest {
ad.initializeAttachments();
- String s = getString(message.getContent(InputStream.class));
+ String s = IOUtils.toString(message.getContent(InputStream.class));
assertEquals("JJJJ", s.trim());
int count = 1;
for (Attachment a : message.getAttachments()) {
- s = getString(a.getDataHandler().getInputStream());
+ s = IOUtils.toString(a.getDataHandler().getInputStream());
assertEquals("ABCD" + count++, s);
}
in.close();
}
- private String getString(InputStream ins) throws Exception {
- try (ByteArrayOutputStream bout = new ByteArrayOutputStream(100)) {
- byte[] b = new byte[100];
- int i = ins.read(b);
- while (i > 0) {
- bout.write(b, 0, i);
- i = ins.read(b);
- }
- if (i == 0) {
- throw new IOException("Should not be 0");
- }
- return bout.toString();
- }
- }
-
@Test
public void testCXF3383() throws Exception {
String contentType = "multipart/related; type=\"application/xop+xml\";"
@@ -677,4 +663,91 @@ public class AttachmentDeserializerTest {
assertEquals(-1, ins.read(new byte[1000], 100, 600));
ins.close();
}
+
+ @Test
+ public void testManyAttachments() throws Exception {
+ StringBuilder sb = new StringBuilder(1000);
+ sb.append("SomeHeader: foo\n")
+ .append("------=_Part_34950_1098328613.1263781527359\n")
+ .append("Content-Type: text/xml; charset=UTF-8\n")
+ .append("Content-Transfer-Encoding: binary\n")
+ .append("Content-Id: <31...@auhpap02>\n")
+ .append('\n')
+ .append("<envelope/>\n");
+
+ // Add many attachments
+ IntStream.range(0, 100000).forEach(i -> {
+ sb.append("------=_Part_34950_1098328613.1263781527359\n")
+ .append("Content-Type: text/xml\n")
+ .append("Content-Transfer-Encoding: binary\n")
+ .append("Content-Id: <b86a5f2d-e7af-4e5e-b71a-9f6f2307cab0>\n")
+ .append('\n')
+ .append("<message>\n")
+ .append("------=_Part_34950_1098328613.1263781527359--\n");
+ });
+
+ msg = new MessageImpl();
+ msg.setContent(InputStream.class, new ByteArrayInputStream(sb.toString().getBytes(StandardCharsets.UTF_8)));
+ msg.put(Message.CONTENT_TYPE, "multipart/related");
+ AttachmentDeserializer ad = new AttachmentDeserializer(msg);
+ ad.initializeAttachments();
+
+ // Force it to load the attachments
+ try {
+ msg.getAttachments().size();
+ fail("Failure expected on too many attachments");
+ } catch (RuntimeException ex) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testChangingMaxAttachmentCount() throws Exception {
+ StringBuilder sb = new StringBuilder(1000);
+ sb.append("SomeHeader: foo\n")
+ .append("------=_Part_34950_1098328613.1263781527359\n")
+ .append("Content-Type: text/xml; charset=UTF-8\n")
+ .append("Content-Transfer-Encoding: binary\n")
+ .append("Content-Id: <31...@auhpap02>\n")
+ .append('\n')
+ .append("<envelope/>\n");
+
+ // Add many attachments
+ IntStream.range(0, 40).forEach(i -> {
+ sb.append("------=_Part_34950_1098328613.1263781527359\n")
+ .append("Content-Type: text/xml\n")
+ .append("Content-Transfer-Encoding: binary\n")
+ .append("Content-Id: <b86a5f2d-e7af-4e5e-b71a-9f6f2307cab0>\n")
+ .append('\n')
+ .append("<message>\n")
+ .append("------=_Part_34950_1098328613.1263781527359--\n");
+ });
+
+ msg = new MessageImpl();
+ msg.put(AttachmentDeserializer.ATTACHMENT_MAX_COUNT, "30");
+ msg.setContent(InputStream.class, new ByteArrayInputStream(sb.toString().getBytes(StandardCharsets.UTF_8)));
+ msg.put(Message.CONTENT_TYPE, "multipart/related");
+ AttachmentDeserializer ad = new AttachmentDeserializer(msg);
+ ad.initializeAttachments();
+
+ // Force it to load the attachments
+ try {
+ msg.getAttachments().size();
+ fail("Failure expected on too many attachments");
+ } catch (RuntimeException ex) {
+ // expected
+ }
+
+ // Now we'll allow it
+ msg = new MessageImpl();
+ msg.put(AttachmentDeserializer.ATTACHMENT_MAX_COUNT, "60");
+ msg.setContent(InputStream.class, new ByteArrayInputStream(sb.toString().getBytes(StandardCharsets.UTF_8)));
+ msg.put(Message.CONTENT_TYPE, "multipart/related");
+ ad = new AttachmentDeserializer(msg);
+ ad.initializeAttachments();
+
+ // Force it to load the attachments
+ assertEquals(40, msg.getAttachments().size());
+ }
+
}