Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ static Map<String, List<String>> loadPartHeaders(InputStream in, int maxHeaderLe
StringBuilder buffer = new StringBuilder(128);
StringBuilder b = new StringBuilder(128);
Map<String, List<String>> heads = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
int totalHeadersCollected = 0;

// loop until we hit the end or a null line
while (readLine(in, b, maxHeaderLength)) {
Expand All @@ -105,7 +106,12 @@ static Map<String, List<String>> loadPartHeaders(InputStream in, int maxHeaderLe
} else {
// if we have a line pending in the buffer, flush it
if (buffer.length() > 0) {
addHeaderLine(heads, buffer, maxHeadersCount, maxHeaderLength);
if (addHeaderLine(heads, buffer, maxHeadersCount, maxHeaderLength)) {
totalHeadersCollected += 1;
if (totalHeadersCollected > maxHeadersCount) {
throw new IOException("The attachment contains more headers than are permitted");
}
}
buffer.setLength(0);
}
// add this to the accumulator
Expand All @@ -114,8 +120,11 @@ static Map<String, List<String>> loadPartHeaders(InputStream in, int maxHeaderLe
}

// if we have a line pending in the buffer, flush it
if (buffer.length() > 0) {
addHeaderLine(heads, buffer, maxHeadersCount, maxHeaderLength);
if (buffer.length() > 0 && addHeaderLine(heads, buffer, maxHeadersCount, maxHeaderLength)) {
totalHeadersCollected += 1;
if (totalHeadersCollected > maxHeadersCount) {
throw new IOException("The attachment contains more headers than are permitted");
}
}
return heads;
}
Expand Down Expand Up @@ -149,12 +158,12 @@ private static boolean readLine(InputStream in, StringBuilder buffer, int maxHea
return buffer.length() != 0;
}

private static void addHeaderLine(Map<String, List<String>> heads, StringBuilder line,
private static boolean addHeaderLine(Map<String, List<String>> heads, StringBuilder line,
int maxHeadersCount, int maxHeaderLength) throws IOException {
// null lines are a nop
final int size = line.length();
if (size == 0) {
return;
return false;
}
int separator = line.indexOf(":");
final String name;
Expand Down Expand Up @@ -185,7 +194,7 @@ private static void addHeaderLine(Map<String, List<String>> heads, StringBuilder
LOG.fine("The attachment header size has exceeded the configured parameter: " + maxHeaderLength);
throw new HeaderSizeExceededException();
}
v.add(value);
return v.add(value);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,32 @@ public void testAttachmentHeaderSize() throws Exception {
() -> ad.initializeAttachments());
}

@Test
public void testManyAttachmentRepeatedHeaders() throws Exception {
StringBuilder sb = new StringBuilder(10000);
// Add many attachment headers
sb.append("------=_Part_34950_1098328613.1263781527359\n");
IntStream.range(0, 100).forEach(i -> sb.append("Header1").append(": ").append(i).append('\n'));
IntStream.range(0, 100).forEach(i -> sb.append("Header2").append(": ").append(i).append('\n'));
IntStream.range(0, 100).forEach(i -> sb.append("Header3").append(": ").append(i).append('\n'));
IntStream.range(0, 100).forEach(i -> sb.append("Header4").append(": ").append(i).append('\n'));
IntStream.range(0, 100).forEach(i -> sb.append("Header5").append(": ").append(i).append('\n'));
IntStream.range(0, 100).forEach(i -> sb.append("Header6").append(": ").append(i).append('\n'));
sb.append("Content-Type: text/xml; charset=UTF-8\n")
.append("Content-Transfer-Encoding: binary\n")
.append("Content-Id: <318731183421.1263781527359.IBM.WEBSERVICES@auhpap02>\n")
.append('\n')
.append("<envelope/>\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);

assertThrows("Failure expected on too many attachment headers", IOException.class,
() -> ad.initializeAttachments());
}

@Test
public void testAttachmentRepeatedHeaderSize() throws Exception {
final Random random = new Random();
Expand Down
Loading