Merge pull request #2010 from dimitrisli/SPR-17459
This commit is contained in:
@@ -28,6 +28,7 @@ import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.MimeType.SpecificityComparator;
|
||||
@@ -37,6 +38,7 @@ import org.springframework.util.MimeType.SpecificityComparator;
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Dimitrios Liapis
|
||||
* @since 4.0
|
||||
*/
|
||||
public abstract class MimeTypeUtils {
|
||||
@@ -248,21 +250,54 @@ public abstract class MimeTypeUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the given, comma-separated string into a list of {@code MimeType} objects.
|
||||
* Parse the comma-separated string into a list of {@code MimeType} objects.
|
||||
* @param mimeTypes the string to parse
|
||||
* @return the list of mime types
|
||||
* @throws IllegalArgumentException if the string cannot be parsed
|
||||
* @throws InvalidMimeTypeException if the string cannot be parsed
|
||||
*/
|
||||
public static List<MimeType> parseMimeTypes(String mimeTypes) {
|
||||
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));
|
||||
return tokenize(mimeTypes).stream()
|
||||
.map(MimeTypeUtils::parseMimeType).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tokenize the given comma-separated string of {@code MimeType} objects
|
||||
* into a {@code List<String>}. Unlike simple tokenization by ",", this
|
||||
* method takes into account quoted parameters.
|
||||
* @param mimeTypes the string to tokenize
|
||||
* @return the list of tokens
|
||||
* @since 5.1.3
|
||||
*/
|
||||
public static List<String> tokenize(String mimeTypes) {
|
||||
if (!StringUtils.hasLength(mimeTypes)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return result;
|
||||
List<String> tokens = new ArrayList<>();
|
||||
boolean inQuotes = false;
|
||||
int startIndex = 0;
|
||||
int i = 0;
|
||||
while (i < mimeTypes.length()) {
|
||||
switch (mimeTypes.charAt(i)) {
|
||||
case '"':
|
||||
inQuotes = !inQuotes;
|
||||
break;
|
||||
case ',':
|
||||
if (!inQuotes) {
|
||||
tokens.add(mimeTypes.substring(startIndex, i));
|
||||
startIndex = i + 1;
|
||||
}
|
||||
break;
|
||||
case '\\':
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
tokens.add(mimeTypes.substring(startIndex));
|
||||
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,25 @@ public class MimeTypeTests {
|
||||
assertEquals("Invalid amount of mime types", 0, mimeTypes.size());
|
||||
}
|
||||
|
||||
@Test // SPR-17459
|
||||
public void parseMimeTypesWithQuotedParameters() {
|
||||
testWithQuotedParameters("foo/bar;param=\",\"");
|
||||
testWithQuotedParameters("foo/bar;param=\"s,a,\"");
|
||||
testWithQuotedParameters("foo/bar;param=\"s,\"", "text/x-c");
|
||||
testWithQuotedParameters("foo/bar;param=\"a\\\"b,c\"");
|
||||
testWithQuotedParameters("foo/bar;param=\"\\\\\"");
|
||||
testWithQuotedParameters("foo/bar;param=\"\\,\\\"");
|
||||
}
|
||||
|
||||
private void testWithQuotedParameters(String... mimeTypes) {
|
||||
String s = String.join(",", mimeTypes);
|
||||
List<MimeType> actual = MimeTypeUtils.parseMimeTypes(s);
|
||||
assertEquals(mimeTypes.length, actual.size());
|
||||
for (int i=0; i < mimeTypes.length; i++) {
|
||||
assertEquals(mimeTypes[i], actual.get(i).toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void compareTo() {
|
||||
MimeType audioBasic = new MimeType("audio", "basic");
|
||||
|
||||
@@ -542,7 +542,7 @@ public class MediaType extends MimeType implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the given comma-separated string into a list of {@code MediaType} objects.
|
||||
* Parse the comma-separated string into a list of {@code MediaType} objects.
|
||||
* <p>This method can be used to parse an Accept or Content-Type header.
|
||||
* @param mediaTypes the string to parse
|
||||
* @return the list of media types
|
||||
@@ -552,12 +552,8 @@ public class MediaType extends MimeType implements Serializable {
|
||||
if (!StringUtils.hasLength(mediaTypes)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
String[] tokens = StringUtils.tokenizeToStringArray(mediaTypes, ",");
|
||||
List<MediaType> result = new ArrayList<>(tokens.length);
|
||||
for (String token : tokens) {
|
||||
result.add(parseMediaType(token));
|
||||
}
|
||||
return result;
|
||||
return MimeTypeUtils.tokenize(mediaTypes).stream()
|
||||
.map(MediaType::parseMediaType).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user