Skip to content
Merged
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 @@ -45,6 +45,8 @@
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);

Check warning on line 48 in jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/util/HttpMultipartPost.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

This block of commented-out lines of code should be removed.

See more on https://sonarcloud.io/project/issues?id=apache_jackrabbit&issues=AZ754hCFnwDRD_WSoFuV&open=AZ754hCFnwDRD_WSoFuV&pullRequest=357
// 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;
Expand All @@ -69,6 +71,9 @@
ServletFileUpload upload = new ServletFileUpload(getFileItemFactory(tmpDir));
if (PARTHEADERSIZEMAX > 0) {
upload.setPartHeaderSizeMax(PARTHEADERSIZEMAX);
} else {
Comment thread
reschke marked this conversation as resolved.
// 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).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.*;


import javax.servlet.ServletInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
Expand Down Expand Up @@ -210,70 +209,41 @@ public void testMultipartPostWithShorterFilename() throws Exception {
}
}

@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");

@rishabhdaim rishabhdaim Jun 24, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nits: the method name testMultipartPostWithExtremelyLongFilenameNButHigherConfig contains the garbled fragment NButHigher. Since this PR modifies the method body, worth fixing the name too — the sibling is testMultipartPostWithExtremelyLongFilename, so the natural counterpart is testMultipartPostWithExtremelyLongFilenameWithHigherConfig.

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();
}
} finally {
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();
}
}
}
Loading