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 857543359501ef9eefea4f8593e8c45ceff80292 Author: Andriy Redko <[email protected]> AuthorDate: Wed Sep 2 20:11:00 2026 -0400 Make sure attachment-max-headers-count property is respected for repeated headers (#3430) (cherry picked from commit 93075df9757feb203ee64e1b2e21ce6a650488bc) --- .../cxf/attachment/AttachmentDeserializerUtil.java | 21 ++++++++++++----- .../cxf/attachment/AttachmentDeserializerTest.java | 26 ++++++++++++++++++++++ 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/org/apache/cxf/attachment/AttachmentDeserializerUtil.java b/core/src/main/java/org/apache/cxf/attachment/AttachmentDeserializerUtil.java index 155bc4d9597..c2d4d2bffed 100644 --- a/core/src/main/java/org/apache/cxf/attachment/AttachmentDeserializerUtil.java +++ b/core/src/main/java/org/apache/cxf/attachment/AttachmentDeserializerUtil.java @@ -85,6 +85,7 @@ final class AttachmentDeserializerUtil { 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)) { @@ -105,7 +106,12 @@ final class AttachmentDeserializerUtil { } 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 @@ -114,8 +120,11 @@ final class AttachmentDeserializerUtil { } // 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; } @@ -149,12 +158,12 @@ final class AttachmentDeserializerUtil { 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; @@ -185,7 +194,7 @@ final class AttachmentDeserializerUtil { LOG.fine("The attachment header size has exceeded the configured parameter: " + maxHeaderLength); throw new HeaderSizeExceededException(); } - v.add(value); + return v.add(value); } 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 b9f14b2bc38..11ad4f25244 100644 --- a/core/src/test/java/org/apache/cxf/attachment/AttachmentDeserializerTest.java +++ b/core/src/test/java/org/apache/cxf/attachment/AttachmentDeserializerTest.java @@ -742,6 +742,32 @@ public class AttachmentDeserializerTest { () -> 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();
