SPR-6786: added more checks for quality factors & charsets

git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@2912 50f2f4bb-b051-0410-bef5-90022cba6387
This commit is contained in:
Arjen Poutsma 2010-02-04 09:47:52 +00:00
parent 7473330885
commit d8a338690b
2 changed files with 37 additions and 11 deletions

View File

@ -18,6 +18,7 @@ package org.springframework.http;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
@ -26,7 +27,6 @@ import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.BitSet;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
@ -56,7 +56,7 @@ public class MediaType implements Comparable<MediaType> {
private static final String WILDCARD_TYPE = "*"; private static final String WILDCARD_TYPE = "*";
private static final String PARAM_QUALITY_FACTORY = "q"; private static final String PARAM_QUALITY_FACTOR = "q";
private static final String PARAM_CHARSET = "charset"; private static final String PARAM_CHARSET = "charset";
@ -149,7 +149,7 @@ public class MediaType implements Comparable<MediaType> {
* @throws IllegalArgumentException if any of the parameters contain illegal characters * @throws IllegalArgumentException if any of the parameters contain illegal characters
*/ */
public MediaType(String type, String subtype, double qualityValue) { public MediaType(String type, String subtype, double qualityValue) {
this(type, subtype, Collections.singletonMap(PARAM_QUALITY_FACTORY, Double.toString(qualityValue))); this(type, subtype, Collections.singletonMap(PARAM_QUALITY_FACTOR, Double.toString(qualityValue)));
} }
/** /**
@ -172,10 +172,7 @@ public class MediaType implements Comparable<MediaType> {
for (Map.Entry<String, String> entry : parameters.entrySet()) { for (Map.Entry<String, String> entry : parameters.entrySet()) {
String attribute = entry.getKey(); String attribute = entry.getKey();
String value = entry.getValue(); String value = entry.getValue();
Assert.hasLength(attribute, "pameter attribute must not be empty"); checkParameters(attribute, value);
Assert.hasLength(value, "pameter value must not be empty");
checkToken(attribute);
checkTokenOrQuotedString(value);
m.put(attribute, value); m.put(attribute, value);
} }
this.parameters = Collections.unmodifiableMap(m); this.parameters = Collections.unmodifiableMap(m);
@ -200,10 +197,24 @@ public class MediaType implements Comparable<MediaType> {
} }
} }
private void checkTokenOrQuotedString(String s) { private void checkParameters(String attribute, String value) {
if (!(s.startsWith("\"") && s.endsWith("\""))) { Assert.hasLength(attribute, "parameter attribute must not be empty");
checkToken(s); Assert.hasLength(value, "parameter value must not be empty");
checkToken(attribute);
if (PARAM_QUALITY_FACTOR.equals(attribute)) {
double d = Double.parseDouble(value);
Assert.isTrue(d >= 0D && d <= 1D, "Invalid quality value \"" + value + "\": should be between 0.0 and 1.0");
} }
else if (PARAM_CHARSET.equals(attribute)) {
Charset.forName(value);
}
else if (!isQuotedString(value)) {
checkToken(value);
}
}
private boolean isQuotedString(String s) {
return s.length() > 1 && s.startsWith("\"") && s.endsWith("\"") ;
} }
/** Return the primary type. */ /** Return the primary type. */
@ -246,7 +257,7 @@ public class MediaType implements Comparable<MediaType> {
* @return the quality factory * @return the quality factory
*/ */
public double getQualityValue() { public double getQualityValue() {
String qualityFactory = getParameter(PARAM_QUALITY_FACTORY); String qualityFactory = getParameter(PARAM_QUALITY_FACTOR);
return (qualityFactory != null ? Double.parseDouble(qualityFactory) : 1D); return (qualityFactory != null ? Double.parseDouble(qualityFactory) : 1D);
} }

View File

@ -121,11 +121,26 @@ public class MediaTypeTests {
MediaType.parseMediaType("audio/*;attr=v>alue"); MediaType.parseMediaType("audio/*;attr=v>alue");
} }
@Test(expected = IllegalArgumentException.class)
public void parseMediaTypeIllegalQualityFactor() {
MediaType.parseMediaType("audio/basic;q=1.1");
}
@Test(expected = IllegalArgumentException.class)
public void parseMediaTypeIllegalCharset() {
MediaType.parseMediaType("text/html; charset=foo-bar");
}
@Test @Test
public void parseMediaTypeQuotedParameterValue() { public void parseMediaTypeQuotedParameterValue() {
MediaType.parseMediaType("audio/*;attr=\"v>alue\""); MediaType.parseMediaType("audio/*;attr=\"v>alue\"");
} }
@Test(expected = IllegalArgumentException.class)
public void parseMediaTypeIllegalQuotedParameterValue() {
MediaType.parseMediaType("audio/*;attr=\"");
}
@Test @Test
public void parseCharset() throws Exception { public void parseCharset() throws Exception {
String s = "text/html; charset=iso-8859-1"; String s = "text/html; charset=iso-8859-1";