MediaType parsing supports comma inside quotes
Issue: SPR-17459
This commit is contained in:
committed by
Rossen Stoyanchev
parent
46a5fb7a91
commit
f4b05dc2e7
@@ -37,6 +37,7 @@ import org.springframework.util.MimeType.SpecificityComparator;
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Dimitrios Liapis
|
||||
* @since 4.0
|
||||
*/
|
||||
public abstract class MimeTypeUtils {
|
||||
@@ -257,12 +258,24 @@ public abstract class MimeTypeUtils {
|
||||
if (!StringUtils.hasLength(mimeTypes)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
String[] tokens = StringUtils.tokenizeToStringArray(mimeTypes, ",");
|
||||
List<MimeType> result = new ArrayList<>(tokens.length);
|
||||
for (String token : tokens) {
|
||||
result.add(parseMimeType(token));
|
||||
boolean isQuoted = false;
|
||||
int nextBeginIndex = 0;
|
||||
List<MimeType> tokens = new ArrayList<>();
|
||||
for(int i = 0; i < mimeTypes.length() - 1; i++) {
|
||||
//tokenizing on commas that are not within double quotes
|
||||
if(mimeTypes.charAt(i) == ',' && !isQuoted) {
|
||||
tokens.add(parseMimeType(mimeTypes.substring(nextBeginIndex,i)));
|
||||
nextBeginIndex = i + 1;
|
||||
//ignoring escaped double quote within double quotes
|
||||
} else if(isQuoted && mimeTypes.charAt(i) == '"' && mimeTypes.charAt(i-1) == '\\') {
|
||||
continue;
|
||||
} else if(mimeTypes.charAt(i) == '"') {
|
||||
isQuoted = !isQuoted;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
//either the last part of the tokenization or the original string
|
||||
tokens.add(parseMimeType(mimeTypes.substring(nextBeginIndex)));
|
||||
return tokens;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -36,6 +36,7 @@ import static org.junit.Assert.*;
|
||||
* @author Arjen Poutsma
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
* @author Dimitrios Liapis
|
||||
*/
|
||||
public class MimeTypeTests {
|
||||
|
||||
@@ -276,6 +277,56 @@ public class MimeTypeTests {
|
||||
assertEquals("Invalid amount of mime types", 0, mimeTypes.size());
|
||||
}
|
||||
|
||||
// SPR-17459
|
||||
@Test
|
||||
public void parseMimeTypesWithOddNumberOfDoubleQuotedCommas() {
|
||||
String s = "foo/bar;param=\",\"";
|
||||
List<MimeType> mimeTypes = MimeTypeUtils.parseMimeTypes(s);
|
||||
assertEquals("Invalid amount of mime types", 1, mimeTypes.size());
|
||||
assertEquals("Comma should be part of the mime type", s, mimeTypes.get(0).toString());
|
||||
}
|
||||
|
||||
// SPR-17459
|
||||
@Test
|
||||
public void parseMimeTypesWithEvenNumberOfDoubleQuotedCommas() {
|
||||
String s = "foo/bar;param=\"s,a,\"";
|
||||
List<MimeType> mimeTypes = MimeTypeUtils.parseMimeTypes(s);
|
||||
assertEquals("Invalid amount of mime types", 1, mimeTypes.size());
|
||||
assertEquals("Comma should be part of the mime type", s, mimeTypes.get(0).toString());
|
||||
}
|
||||
|
||||
// SPR-17459
|
||||
@Test
|
||||
public void parseMimeTypesWithAndWithoutDoubleQuotedCommas() {
|
||||
String s = "foo/bar;param=\"s,\", text/x-c";
|
||||
List<MimeType> mimeTypes = MimeTypeUtils.parseMimeTypes(s);
|
||||
assertEquals("Invalid amount of mime types", 2, mimeTypes.size());
|
||||
assertEquals("Comma should be part of the mime type", "foo/bar;param=\"s,\"", mimeTypes.get(0).toString());
|
||||
}
|
||||
|
||||
// SPR-17459
|
||||
@Test
|
||||
public void parseMimeTypesIgnoreEscapedDoubleQuoteWithinDoubleQuotes() {
|
||||
String s = "foo/bar;param=\"a\\\"b,c\"";
|
||||
List<MimeType> mimeTypes = MimeTypeUtils.parseMimeTypes(s);
|
||||
assertEquals("Invalid amount of mime types", 1, mimeTypes.size());
|
||||
assertEquals("Escaped quote within quotes should be ignored when considering comma tokenization", s, mimeTypes.get(0).toString());
|
||||
}
|
||||
|
||||
// SPR-17459
|
||||
@Test
|
||||
public void parseMimeTypesIgnoreEscapedBackslash() {
|
||||
String s = "foo/bar;param=\"\\\\\"";
|
||||
List<MimeType> mimeTypes = MimeTypeUtils.parseMimeTypes(s);
|
||||
assertEquals("Invalid amount of mime types", 1, mimeTypes.size());
|
||||
assertEquals("Escaped backslash should be ignored when considering comma tokenization", s, mimeTypes.get(0).toString());
|
||||
|
||||
s = "foo/bar;param=\"\\,\\\"";
|
||||
mimeTypes = MimeTypeUtils.parseMimeTypes(s);
|
||||
assertEquals("Invalid amount of mime types", 1, mimeTypes.size());
|
||||
assertEquals("Escaped backslash should be ignored when considering comma tokenization", s, mimeTypes.get(0).toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void compareTo() {
|
||||
MimeType audioBasic = new MimeType("audio", "basic");
|
||||
|
||||
Reference in New Issue
Block a user