This is an automated email from the ASF dual-hosted git repository.
garydgregory pushed a commit to branch 1.x
in repository https://gitbox.apache.org/repos/asf/commons-fileupload.git
The following commit(s) were added to refs/heads/1.x by this push:
new 6286617b Ignore invalid RFC 2231 extended value so it cannot erase a
valid filename (#480)
6286617b is described below
commit 6286617b0314bb0cf5aecb303814c8492990b080
Author: alhuda <[email protected]>
AuthorDate: Mon Jul 20 19:14:28 2026 +0530
Ignore invalid RFC 2231 extended value so it cannot erase a valid filename
(#480)
Port of #479 to 1.x.
---
.../apache/commons/fileupload/ParameterParser.java | 7 +++---
.../commons/fileupload/ParameterParserTest.java | 28 ++++++++++++++++++++++
2 files changed, 32 insertions(+), 3 deletions(-)
diff --git a/src/main/java/org/apache/commons/fileupload/ParameterParser.java
b/src/main/java/org/apache/commons/fileupload/ParameterParser.java
index 496021d3..01034b12 100644
--- a/src/main/java/org/apache/commons/fileupload/ParameterParser.java
+++ b/src/main/java/org/apache/commons/fileupload/ParameterParser.java
@@ -182,6 +182,7 @@ public class ParameterParser {
while (hasChar()) {
String paramName = parseToken(new char[] { '=', separator });
String paramValue = null;
+ boolean invalid = false;
if (hasChar() && charArray[pos] == '=') {
pos++; // skip '='
paramValue = parseQuotedToken(new char[] { separator });
@@ -189,8 +190,8 @@ public class ParameterParser {
try {
paramValue = RFC2231Utility.hasEncodedValue(paramName)
? RFC2231Utility.decodeText(paramValue) : MimeUtility.decodeText(paramValue);
} catch (final IllegalArgumentException iae) {
- // Treat invalid values as if they were not provided
- paramValue = null;
+ // Treat invalid values as if they were not provided,
so a malformed filename* cannot override a valid filename.
+ invalid = true;
} catch (final UnsupportedEncodingException ignored) {
// let's keep the original value in this case
}
@@ -199,7 +200,7 @@ public class ParameterParser {
if (hasChar() && charArray[pos] == separator) {
pos++; // skip separator
}
- if (paramName != null && !paramName.isEmpty()) {
+ if (!invalid && paramName != null && !paramName.isEmpty()) {
paramName = RFC2231Utility.stripDelimiter(paramName);
if (lowerCaseNames) {
paramName = paramName.toLowerCase(Locale.ROOT);
diff --git
a/src/test/java/org/apache/commons/fileupload/ParameterParserTest.java
b/src/test/java/org/apache/commons/fileupload/ParameterParserTest.java
index e2ac15f7..aef5c7de 100644
--- a/src/test/java/org/apache/commons/fileupload/ParameterParserTest.java
+++ b/src/test/java/org/apache/commons/fileupload/ParameterParserTest.java
@@ -98,6 +98,34 @@ public class ParameterParserTest {
assertEquals("a\'b\'c", params.get("filename"));
}
+ /**
+ * An invalid RFC 2231 / RFC 5987 extended value must be ignored rather
than overwrite a valid plain value for the same parameter.
+ */
+ @Test
+ public void testInvalidExtendedValueIgnored() {
+ final ParameterParser parser = new ParameterParser();
+
+ // A truncated %nn escape in filename* must not erase the valid
filename.
+ String s = "Content-Disposition: form-data; name=\"file\";
filename=\"safe.txt\"; filename*=UTF-8\'\'bad%2\r\n";
+ Map<String, String> params = parser.parse(s, new char[] { ',', ';' });
+ assertEquals("safe.txt", params.get("filename"));
+
+ // Order independent: an invalid filename* before the valid filename
is also ignored.
+ s = "Content-Disposition: form-data; name=\"file\";
filename*=UTF-8\'\'bad%2; filename=\"safe.txt\"\r\n";
+ params = parser.parse(s, new char[] { ',', ';' });
+ assertEquals("safe.txt", params.get("filename"));
+
+ // An invalid filename* on its own is not reported as a (null) value.
+ s = "Content-Disposition: form-data; name=\"file\";
filename*=UTF-8\'\'bad%2\r\n";
+ params = parser.parse(s, new char[] { ',', ';' });
+ assertNull(params.get("filename"));
+
+ // A valid filename* still decodes normally.
+ s = "Content-Disposition: form-data; name=\"file\";
filename=\"safe.txt\"; filename*=UTF-8\'\'real.exe\r\n";
+ params = parser.parse(s, new char[] { ',', ';' });
+ assertEquals("real.exe", params.get("filename"));
+ }
+
@Test
public void testParsing() {
String s =