From a3b2e20af288269a11046a51c0ab9d5107fabc2a Mon Sep 17 00:00:00 2001 From: Chenjp Date: Fri, 20 Jun 2025 10:11:46 +0800 Subject: [PATCH 1/2] comply rfc7578 section 4.8 per spec, only listed part header fields are supported. ignore others. Should review JIRA 130 - https://issues.apache.org/jira/browse/FILEUPLOAD-130 --- .../fileupload2/core/AbstractFileUpload.java | 19 ++++- .../core/AbstractFileUploadTest.java | 74 ++++++------------- 2 files changed, 38 insertions(+), 55 deletions(-) diff --git a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/AbstractFileUpload.java b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/AbstractFileUpload.java index eb676039b..fea5667a2 100644 --- a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/AbstractFileUpload.java +++ b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/AbstractFileUpload.java @@ -71,6 +71,14 @@ public abstract class AbstractFileUpload, F extends Fil */ public static final String CONTENT_DISPOSITION = "Content-disposition"; + /** + * HTTP content transfer encoding header name.Add commentMore actions + * + * @deprecated per rfc7578 Section 4.7 + */ + @Deprecated + public static final String CONTENT_TRANSFER_ENCODING = "Content-Transfer-Encoding"; + /** * HTTP content length header name. */ @@ -397,7 +405,8 @@ private int parseEndOfLine(final String headerPart, final int end) { } /** - * Parses the next header line. + * Parses the next header line. Per RFC 7578 section 4.8, only + * listed part header fields are supported, others MUST be ignored. * * @param headers String with all headers. * @param header Map where to store the current header. @@ -410,7 +419,13 @@ private void parseHeaderLine(final FileItemHeaders headers, final String header) } final var headerName = header.substring(0, colonOffset).trim(); final var headerValue = header.substring(colonOffset + 1).trim(); - headers.addHeader(headerName, headerValue); + // see rfc7578 section 4.8 + if (CONTENT_DISPOSITION.equalsIgnoreCase(headerName) || CONTENT_TYPE.equalsIgnoreCase(headerName) || + CONTENT_TRANSFER_ENCODING.equalsIgnoreCase(headerName)) { + // Only listed part header fields are supported + // Other header fields MUST be ignored. + headers.addHeader(headerName, headerValue); + } } /** diff --git a/commons-fileupload2-core/src/test/java/org/apache/commons/fileupload2/core/AbstractFileUploadTest.java b/commons-fileupload2-core/src/test/java/org/apache/commons/fileupload2/core/AbstractFileUploadTest.java index 14c55defc..e6ed32237 100644 --- a/commons-fileupload2-core/src/test/java/org/apache/commons/fileupload2/core/AbstractFileUploadTest.java +++ b/commons-fileupload2-core/src/test/java/org/apache/commons/fileupload2/core/AbstractFileUploadTest.java @@ -18,6 +18,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -52,7 +53,27 @@ private void assertHeaders(final String[] headerNames, final String[] headerValu } } } + @Test + void testIgnoreUnsupportedPartField() throws IOException { + // @formatter:off + final var fileItems = parseUpload(upload, + "-----1234\r\n" + + "content-disposition: form-data; name=\"field1\"\r\n" + + "content-id: field1\r\n" + + "x-souce-id: field1\r\n" + + "\r\n" + + "Joe Blow\r\n" + + "-----1234--\r\n"); + // @formatter:on + assertEquals(1, fileItems.size()); + final var field = fileItems.get(0); + assertEquals("field1", field.getFieldName()); + assertTrue(field.isFormField()); + assertNotNull(field.getHeaders().getHeader("content-disposition")); + assertNull(field.getHeaders().getHeader("content-id")); + assertNull(field.getHeaders().getHeader("x-souce-id")); + } /** * Tests FILEUPLOAD-239 * @@ -186,59 +207,6 @@ public void testFileUpload() throws IOException { assertEquals("value2", multi1.getString()); } - /** - * Test case for FILEUPLOAD-130. - * - * @throws IOException Test failure. - */ - @Test - void testFileUpload130() throws IOException { - final String[] headerNames = { "SomeHeader", "OtherHeader", "YetAnotherHeader", "WhatAHeader" }; - final String[] headerValues = { "present", "Is there", "Here", "Is That" }; - // @formatter:off - final var fileItems = parseUpload(upload, - "-----1234\r\n" + - "Content-Disposition: form-data; name=\"file\"; " - + "filename=\"foo.tab\"\r\n" + - "Content-Type: text/whatever\r\n" + - headerNames[0] + ": " + headerValues[0] + "\r\n" + - "\r\n" + - "This is the content of the file\n" + - "\r\n" + - "-----1234\r\n" + - "Content-Disposition: form-data; \r\n" + - "\tname=\"field\"\r\n" + - headerNames[1] + ": " + headerValues[1] + "\r\n" + - "\r\n" + - "fieldValue\r\n" + - "-----1234\r\n" + - "Content-Disposition: form-data;\r\n" + - " name=\"multi\"\r\n" + - headerNames[2] + ": " + headerValues[2] + "\r\n" + - "\r\n" + - "value1\r\n" + - "-----1234\r\n" + - "Content-Disposition: form-data; name=\"multi\"\r\n" + - headerNames[3] + ": " + headerValues[3] + "\r\n" + - "\r\n" + - "value2\r\n" + - "-----1234--\r\n"); - // @formatter:on - assertEquals(4, fileItems.size()); - - final var file = fileItems.get(0); - assertHeaders(headerNames, headerValues, file, 0); - - final var field = fileItems.get(1); - assertHeaders(headerNames, headerValues, field, 1); - - final var multi0 = fileItems.get(2); - assertHeaders(headerNames, headerValues, multi0, 2); - - final var multi1 = fileItems.get(3); - assertHeaders(headerNames, headerValues, multi1, 3); - } - /** * Test for FILEUPLOAD-62 * From 67a66197247c8b99f5a2b876c7333462ee867378 Mon Sep 17 00:00:00 2001 From: Chenjp Date: Fri, 20 Jun 2025 10:20:58 +0800 Subject: [PATCH 2/2] fix codestyle fix codestyle --- .../apache/commons/fileupload2/core/AbstractFileUpload.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/AbstractFileUpload.java b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/AbstractFileUpload.java index fea5667a2..98edd643d 100644 --- a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/AbstractFileUpload.java +++ b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/core/AbstractFileUpload.java @@ -72,7 +72,7 @@ public abstract class AbstractFileUpload, F extends Fil public static final String CONTENT_DISPOSITION = "Content-disposition"; /** - * HTTP content transfer encoding header name.Add commentMore actions + * HTTP content transfer encoding header name. * * @deprecated per rfc7578 Section 4.7 */ @@ -420,8 +420,8 @@ private void parseHeaderLine(final FileItemHeaders headers, final String header) final var headerName = header.substring(0, colonOffset).trim(); final var headerValue = header.substring(colonOffset + 1).trim(); // see rfc7578 section 4.8 - if (CONTENT_DISPOSITION.equalsIgnoreCase(headerName) || CONTENT_TYPE.equalsIgnoreCase(headerName) || - CONTENT_TRANSFER_ENCODING.equalsIgnoreCase(headerName)) { + if (CONTENT_DISPOSITION.equalsIgnoreCase(headerName) || CONTENT_TYPE.equalsIgnoreCase(headerName) + || CONTENT_TRANSFER_ENCODING.equalsIgnoreCase(headerName)) { // Only listed part header fields are supported // Other header fields MUST be ignored. headers.addHeader(headerName, headerValue);