You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by jo...@apache.org on 2020/05/25 19:29:00 UTC
[commons-fileupload] 02/04: Detect asterisk only if is at end &
added tests
This is an automated email from the ASF dual-hosted git repository.
jochen pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-fileupload.git
commit 1a8a103eefa5616503e9947804c6a20b12669e42
Author: Merbin J Anselm <me...@sap.com>
AuthorDate: Tue Dec 10 12:00:25 2019 +0530
Detect asterisk only if is at end & added tests
---
.../commons/fileupload2/ParameterParser.java | 9 ++----
.../fileupload2/util/mime/RFC2231Utility.java | 28 ++++++++++++++++
.../commons/fileupload2/ParameterParserTest.java | 22 +++++++++++++
.../util/mime/RFC2231UtilityTestCase.java | 37 +++++++++++++++++++---
4 files changed, 85 insertions(+), 11 deletions(-)
diff --git a/src/main/java/org/apache/commons/fileupload2/ParameterParser.java b/src/main/java/org/apache/commons/fileupload2/ParameterParser.java
index 2735259..ef24a89 100644
--- a/src/main/java/org/apache/commons/fileupload2/ParameterParser.java
+++ b/src/main/java/org/apache/commons/fileupload2/ParameterParser.java
@@ -306,12 +306,10 @@ public class ParameterParser {
String paramName = null;
String paramValue = null;
- boolean hasExtendedParams = false;
while (hasChar()) {
paramName = parseToken(new char[] {
'=', separator });
paramValue = null;
- hasExtendedParams = (paramName != null) ? paramName.contains("*") : false; //TODO: Check only if delimiter is at end
if (hasChar() && (charArray[pos] == '=')) {
pos++; // skip '='
paramValue = parseQuotedToken(new char[] {
@@ -319,7 +317,7 @@ public class ParameterParser {
if (paramValue != null) {
try {
- paramValue = hasExtendedParams ? RFC2231Utility.decodeText(paramValue)
+ paramValue = RFC2231Utility.hasEncodedValue(paramName) ? RFC2231Utility.decodeText(paramValue)
: MimeUtility.decodeText(paramValue);
} catch (UnsupportedEncodingException e) {
// let's keep the original value in this case
@@ -330,13 +328,10 @@ public class ParameterParser {
pos++; // skip separator
}
if ((paramName != null) && (paramName.length() > 0)) {
- if (hasExtendedParams) {
- paramName = paramName.replace("*", ""); //strip of the * from the name //TODO: Replace the last character alone
- }
+ paramName = RFC2231Utility.stripDelimiter(paramName);
if (this.lowerCaseNames) {
paramName = paramName.toLowerCase(Locale.ENGLISH);
}
-
params.put(paramName, paramValue);
}
}
diff --git a/src/main/java/org/apache/commons/fileupload2/util/mime/RFC2231Utility.java b/src/main/java/org/apache/commons/fileupload2/util/mime/RFC2231Utility.java
index 37dce05..955d185 100644
--- a/src/main/java/org/apache/commons/fileupload2/util/mime/RFC2231Utility.java
+++ b/src/main/java/org/apache/commons/fileupload2/util/mime/RFC2231Utility.java
@@ -44,6 +44,34 @@ public final class RFC2231Utility {
}
/**
+ * Checks if Asterisk (*) at the end of parameter name to indicate,
+ * if it has charset and language information to decode the value
+ * @param paramName
+ * @return {@code true}, if encoded as per RFC 2231, {@code false} otherwise
+ */
+ public static boolean hasEncodedValue(String paramName) {
+ if (paramName != null) {
+ return paramName.lastIndexOf("*") == (paramName.length() - 1);
+ }
+ return false;
+ }
+
+ /**
+ * If {@code paramName} has Asterisk (*) at the end, it will be stripped off,
+ * else the passed value will be returned
+ * @param paramName
+ * @return stripped {@code paramName} of Asterisk (*), if RFC2231 encoded
+ */
+ public static String stripDelimiter(String paramName) {
+ if (hasEncodedValue(paramName)) {
+ StringBuilder paramBuilder = new StringBuilder(paramName);
+ paramBuilder.deleteCharAt(paramName.lastIndexOf("*"));
+ return paramBuilder.toString();
+ }
+ return paramName;
+ }
+
+ /**
* Decode a string of text obtained from a HTTP header as per RFC 2231
*
* <p/>
diff --git a/src/test/java/org/apache/commons/fileupload2/ParameterParserTest.java b/src/test/java/org/apache/commons/fileupload2/ParameterParserTest.java
index 96988b3..70838f3 100644
--- a/src/test/java/org/apache/commons/fileupload2/ParameterParserTest.java
+++ b/src/test/java/org/apache/commons/fileupload2/ParameterParserTest.java
@@ -126,9 +126,31 @@ public class ParameterParserTest {
@Test
public void testFileUpload274() {
ParameterParser parser = new ParameterParser();
+
+ // Should parse a UTF-8 charset
String s = "Content-Disposition: form-data; name=\"file\"; filename*=UTF-8\'\'%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF\r\n";
Map<String, String> params = parser.parse(s, new char[] { ',', ';' });
assertEquals("\u3053\u3093\u306B\u3061\u306F", params.get("filename")); //filename = "こんにちは" in japanese
+
+ // Should parse ISO-8859-1 charset
+ s = "Content-Disposition: form-data; name=\"file\"; filename*=UTF-8\'\'%70%C3%A2%74%C3%A9\r\n";
+ params = parser.parse(s, new char[] { ',', ';' });
+ assertEquals("\u0070\u00e2\u0074\u00e9", params.get("filename")); //filename = "pâté" in french
+
+ // Should not decode if '*' is not at the end of param-name
+ s = "Content-Disposition: form-data; name=\"file\"; file*name=UTF-8\'\'%61%62%63\r\n";
+ params = parser.parse(s, new char[] { ',', ';' });
+ assertEquals("UTF-8\'\'%61%62%63", params.get("file*name"));
+
+ // Should not decode if param-value does not follow <charset>'<lang>'<encoded>
+ s = "Content-Disposition: form-data; name=\"file\"; filename*=a\'bc\r\n";
+ params = parser.parse(s, new char[] { ',', ';' });
+ assertEquals("a\'bc", params.get("filename"));
+
+ // Should not decode if param-name doesn't have '*' at end
+ s = "Content-Disposition: form-data; name=\"file\"; filename=a\'b\'c\r\n";
+ params = parser.parse(s, new char[] { ',', ';' });
+ assertEquals("a\'b\'c", params.get("filename"));
}
}
diff --git a/src/test/java/org/apache/commons/fileupload2/util/mime/RFC2231UtilityTestCase.java b/src/test/java/org/apache/commons/fileupload2/util/mime/RFC2231UtilityTestCase.java
index 9100728..315713c 100644
--- a/src/test/java/org/apache/commons/fileupload2/util/mime/RFC2231UtilityTestCase.java
+++ b/src/test/java/org/apache/commons/fileupload2/util/mime/RFC2231UtilityTestCase.java
@@ -17,7 +17,9 @@
package org.apache.commons.fileupload2.util.mime;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.UnsupportedEncodingException;
@@ -31,6 +33,33 @@ import org.junit.jupiter.api.Test;
public final class RFC2231UtilityTestCase {
@Test
+ public void testHasEncodedValue() {
+ String nameWithAsteriskAtEnd = "paramname*";
+ assertTrue(RFC2231Utility.hasEncodedValue(nameWithAsteriskAtEnd));
+
+ String nameWithAsteriskNotAtEnd = "param*name";
+ assertFalse(RFC2231Utility.hasEncodedValue(nameWithAsteriskNotAtEnd));
+
+ String nameWithoutAsterisk = "paramname";
+ assertFalse(RFC2231Utility.hasEncodedValue(nameWithoutAsterisk));
+ }
+
+ @Test
+ public void testStripDelimiter() {
+ String nameWithAsteriskAtEnd = "paramname*";
+ assertEquals("paramname", RFC2231Utility.stripDelimiter(nameWithAsteriskAtEnd));
+
+ String nameWithAsteriskNotAtEnd = "param*name";
+ assertEquals("param*name", RFC2231Utility.stripDelimiter(nameWithAsteriskNotAtEnd));
+
+ String nameWithTwoAsterisks = "param*name*";
+ assertEquals("param*name", RFC2231Utility.stripDelimiter(nameWithTwoAsterisks));
+
+ String nameWithoutAsterisk = "paramname";
+ assertEquals("paramname", RFC2231Utility.stripDelimiter(nameWithoutAsterisk));
+ }
+
+ @Test
public void noNeedToDecode() throws Exception {
assertEncoded("abc", "abc");
}
@@ -45,14 +74,14 @@ public final class RFC2231UtilityTestCase {
assertEncoded("\u00A3 rate", "iso-8859-1'en'%A3%20rate"); //"£ rate"
}
- private static void assertEncoded(String expected, String encoded) throws Exception {
- assertEquals(expected, RFC2231Utility.decodeText(encoded));
- }
-
@Test
public void decodeInvalidEncoding() throws Exception {
assertThrows(UnsupportedEncodingException.class, () -> {
RFC2231Utility.decodeText("abc'en'hello");
});
}
+
+ private static void assertEncoded(String expected, String encoded) throws Exception {
+ assertEquals(expected, RFC2231Utility.decodeText(encoded));
+ }
}