You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by re...@apache.org on 2026/07/30 13:08:29 UTC

(jackrabbit) branch 2.22 updated: JCR-5233: commons-fileupload (1.6) restricts header size in upload pa… (#357)

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

reschke pushed a commit to branch 2.22
in repository https://gitbox.apache.org/repos/asf/jackrabbit.git


The following commit(s) were added to refs/heads/2.22 by this push:
     new a5655d0dc JCR-5233: commons-fileupload (1.6) restricts header size in upload pa… (#357)
a5655d0dc is described below

commit a5655d0dc95922fff86b178d4acd254d510fe439
Author: Julian Reschke <re...@apache.org>
AuthorDate: Thu Jun 25 08:53:42 2026 +0200

    JCR-5233: commons-fileupload (1.6) restricts header size in upload pa… (#357)
---
 .../jackrabbit/server/util/HttpMultipartPost.java  |  5 ++
 .../jackrabbit/server/util/RequestDataTest.java    | 60 ++++++----------------
 2 files changed, 20 insertions(+), 45 deletions(-)

diff --git a/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/util/HttpMultipartPost.java b/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/util/HttpMultipartPost.java
index ac9c44b29..30ca4e831 100644
--- a/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/util/HttpMultipartPost.java
+++ b/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/util/HttpMultipartPost.java
@@ -45,6 +45,8 @@ class HttpMultipartPost {
     private final Map<String, List<FileItem>> nameToItems = new LinkedHashMap<String, List<FileItem>>();
     private final Set<String> fileParamNames = new HashSet<String>();
 
+    // <= 0 (default -1) -> Jackrabbit applies 4096 (overrides cfup 1.6's current 512-byte default);
+    // positive -> exact value in bytes. Set to 512 to restore the library's own default.
     private final int PARTHEADERSIZEMAX = Integer.getInteger("jackrabbit-server-PartHeaderSizeMax", -1);
 
     private boolean initialized;
@@ -69,6 +71,9 @@ class HttpMultipartPost {
         ServletFileUpload upload = new ServletFileUpload(getFileItemFactory(tmpDir));
         if (PARTHEADERSIZEMAX > 0) {
             upload.setPartHeaderSizeMax(PARTHEADERSIZEMAX);
+        } else {
+            // override the default limit of 512 in commons-fileupload 1.6
+            upload.setPartHeaderSizeMax(4096);
         }
         // make sure the content disposition headers are read with the charset
         // specified in the request content type (or UTF-8 if no charset is specified).
diff --git a/jackrabbit-jcr-server/src/test/java/org/apache/jackrabbit/server/util/RequestDataTest.java b/jackrabbit-jcr-server/src/test/java/org/apache/jackrabbit/server/util/RequestDataTest.java
index bb86153d1..36d59c55a 100755
--- a/jackrabbit-jcr-server/src/test/java/org/apache/jackrabbit/server/util/RequestDataTest.java
+++ b/jackrabbit-jcr-server/src/test/java/org/apache/jackrabbit/server/util/RequestDataTest.java
@@ -34,7 +34,6 @@ import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.*;
 
-
 import javax.servlet.ServletInputStream;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
@@ -210,29 +209,36 @@ public class RequestDataTest {
         }
     }
 
-    @Test(expected=IOException.class)
+    @Test(expected = IOException.class)
     public void testMultipartPostWithExtremelyLongFilename() throws Exception {
-        buildRequestWithFilenameOfVaryingLength(1000);
+        // header bytes ~= filename length + ~107; at 5000 chars this far exceeds the 4096 default
+        buildRequestWithFilenameOfVaryingLength(5000);
         File testTmpDir = tempFolder.newFolder("jackrabbit_long_filename");
+        new RequestData(mockRequest, testTmpDir); // must throw IOException
+    }
+
+    @Test
+    public void testMultipartPostWithLongFilenameUnderNewDefault() throws Exception {
+        buildRequestWithFilenameOfVaryingLength(3800); // above 512, below 4096
+        File testTmpDir = tempFolder.newFolder("jackrabbit_medium_filename");
         RequestData requestData = new RequestData(mockRequest, testTmpDir);
         try {
-            assertTrue(
-                    requestData.getParameter("fileUpload").length() > 950);
+            assertTrue(requestData.getParameter("fileUpload").length() > 3800);
         } finally {
             requestData.dispose();
         }
     }
 
     @Test
-    public void testMultipartPostWithExtremelyLongFilenameNButHigherConfig() throws Exception {
+    public void testMultipartPostWithExtremelyLongFilenameWithHigherConfig() throws Exception {
         try {
-            System.setProperty("jackrabbit-server-PartHeaderSizeMax", "2048");
-            buildRequestWithFilenameOfVaryingLength(1000);
+            System.setProperty("jackrabbit-server-PartHeaderSizeMax", "8192");
+            buildRequestWithFilenameOfVaryingLength(7500);
             File testTmpDir = tempFolder.newFolder("jackrabbit_long_filename");
             RequestData requestData = new RequestData(mockRequest, testTmpDir);
             try {
                 assertTrue(
-                        requestData.getParameter("fileUpload").length() > 950);
+                        requestData.getParameter("fileUpload").length() > 7500);
             } finally {
                 requestData.dispose();
             }
@@ -240,40 +246,4 @@ public class RequestDataTest {
             System.clearProperty("jackrabbit-server-PartHeaderSizeMax");
         }
     }
-
-    /**
-     * Assures special Unicode (Non-ASCII) symbols preserve structural state during text decoding.
-     */
-    // @Test
-    public void testMultipartPostWithNonAsciiCharacters() throws Exception {
-        File testTmpDir = tempFolder.newFolder("jackrabbit_non_ascii");
-        String boundary = "----MockBoundaryNonAscii";
-        String nonAsciiValue = "テスト_ü_é_ñ_value";
-        String nonAsciiFilename = "マニュアル_doc.pdf";
-
-        String body = "--" + boundary + "\r\n" +
-                "Content-Disposition: form-data; name=\"unicodeField\"\r\n\r\n" +
-                nonAsciiValue + "\r\n" +
-                "--" + boundary + "\r\n" +
-                "Content-Disposition: form-data; name=\"unicodeFile\"; filename=\"" + nonAsciiFilename + "\"\r\n" +
-                "Content-Type: application/pdf\r\n\r\n" +
-                "%PDF-Mock-Bytes\r\n" +
-                "--" + boundary + "--\r\n";
-
-        byte[] payloadBytes = body.getBytes(StandardCharsets.UTF_8);
-
-        when(mockRequest.getMethod()).thenReturn("POST");
-        when(mockRequest.getContentType()).thenReturn("multipart/form-data; boundary=" + boundary);
-        lenient().when(mockRequest.getCharacterEncoding()).thenReturn("UTF-8");
-        when(mockRequest.getInputStream()).thenReturn(createServletInputStream(payloadBytes));
-
-        RequestData requestData = new RequestData(mockRequest, testTmpDir);
-        try {
-            String parsedValue = requestData.getParameter("unicodeField");
-            assertEquals("Unicode decoding was corrupted inside the parsing sequence", nonAsciiValue, parsedValue);
-            assertNotNull("Non-ASCII file part metadata parsing must complete successfully", requestData.getParameter("unicodeFile"));
-        } finally {
-            requestData.dispose();
-        }
-    }
 }
\ No newline at end of file