Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions spring-core/src/main/java/org/springframework/util/MimeType.java
Original file line number Diff line number Diff line change
Expand Up @@ -486,9 +486,9 @@ public boolean equals(@Nullable Object other) {
/**
* Determine if the parameters in this {@code MimeType} and the supplied
* {@code MimeType} are equal, performing case-insensitive comparisons
* for {@link Charset Charsets} and disregarding quoting of parameter
* values, so that, for example, {@code spring="framework"} and
* {@code spring=framework} are considered equal.
* for parameter names and {@link Charset Charsets}, and disregarding
* quoting of parameter values, so that, for example, {@code spring="framework"}
* and {@code spring=framework} are considered equal.
* @since 4.2
*/
private boolean parametersAreEqual(MimeType other) {
Expand All @@ -501,7 +501,7 @@ private boolean parametersAreEqual(MimeType other) {
if (!other.parameters.containsKey(key)) {
return false;
}
if (PARAM_CHARSET.equals(key)) {
if (PARAM_CHARSET.equalsIgnoreCase(key)) {
if (!ObjectUtils.nullSafeEquals(getCharset(), other.getCharset())) {
return false;
}
Expand All @@ -528,15 +528,15 @@ public int hashCode() {

/**
* Compute a hash code for the parameters map, consistent with
* {@link #parametersAreEqual}: normalizing {@link Charset Charsets} and
* disregarding quoting of parameter values.
* {@link #parametersAreEqual}: normalizing parameter names and
* {@link Charset Charsets}, and disregarding quoting of parameter values.
*/
private int parametersHashCode() {
int result = 0;
for (Map.Entry<String, String> entry : this.parameters.entrySet()) {
String key = entry.getKey();
Object value = (PARAM_CHARSET.equals(key) ? getCharset() : unquote(entry.getValue()));
result += key.hashCode() ^ ObjectUtils.nullSafeHashCode(value);
Object value = (PARAM_CHARSET.equalsIgnoreCase(key) ? getCharset() : unquote(entry.getValue()));
result += key.toLowerCase(Locale.ROOT).hashCode() ^ ObjectUtils.nullSafeHashCode(value);
}
return result;
}
Expand Down Expand Up @@ -602,7 +602,7 @@ public int compareTo(MimeType other) {
if (comp != 0) {
return comp;
}
if (PARAM_CHARSET.equals(thisAttribute)) {
if (PARAM_CHARSET.equalsIgnoreCase(thisAttribute)) {
Charset thisCharset = getCharset();
Charset otherCharset = other.getCharset();
if (thisCharset != otherCharset) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,28 @@ void equalsIsCaseInsensitiveForCharsets() {
assertThat(m2.compareTo(m1)).isEqualTo(0);
}

@Test
void equalsIsCaseInsensitiveForParameterNames() {
MimeType m1 = new MimeType("text", "plain", singletonMap("Spring", "framework"));
MimeType m2 = new MimeType("text", "plain", singletonMap("spring", "framework"));
assertThat(m1).isEqualTo(m2);
assertThat(m2).isEqualTo(m1);
assertThat(m1).hasSameHashCodeAs(m2);
assertThat(m1.compareTo(m2)).isEqualTo(0);
assertThat(m2.compareTo(m1)).isEqualTo(0);
}

@Test
void equalsIsCaseInsensitiveForCharsetParameterName() {
MimeType m1 = new MimeType("text", "plain", singletonMap("Charset", "UTF-8"));
MimeType m2 = new MimeType("text", "plain", singletonMap("charset", "utf-8"));
assertThat(m1).isEqualTo(m2);
assertThat(m2).isEqualTo(m1);
assertThat(m1).hasSameHashCodeAs(m2);
assertThat(m1.compareTo(m2)).isEqualTo(0);
assertThat(m2.compareTo(m1)).isEqualTo(0);
}

@Test // gh-36729
void equalsIgnoresParameterValueQuoting() {
MimeType m1 = MimeTypeUtils.parseMimeType("text/plain; spring=\"framework\"");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ public MediaType(MimeType mimeType) {
@Override
protected void checkParameters(String parameter, String value) {
super.checkParameters(parameter, value);
if (PARAM_QUALITY_FACTOR.equals(parameter)) {
if (PARAM_QUALITY_FACTOR.equalsIgnoreCase(parameter)) {
String unquotedValue = unquote(value);
double d = Double.parseDouble(unquotedValue);
Assert.isTrue(d >= 0D && d <= 1D,
Expand Down Expand Up @@ -651,7 +651,7 @@ public MediaType removeQualityValue() {
return this;
}
Map<String, String> params = new LinkedHashMap<>(getParameters());
params.remove(PARAM_QUALITY_FACTOR);
params.keySet().removeIf(PARAM_QUALITY_FACTOR::equalsIgnoreCase);
return new MediaType(this, params);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,12 @@ void parseMediaTypeIllegalQualityFactor() {
MediaType.parseMediaType("audio/basic;q=1.1"));
}

@Test
void parseMediaTypeIllegalQualityFactorWithUpperCaseParameterName() {
assertThatExceptionOfType(InvalidMediaTypeException.class).isThrownBy(() ->
MediaType.parseMediaType("audio/basic;Q=1.1"));
}

@Test
void parseMediaTypeIllegalCharset() {
assertThatExceptionOfType(InvalidMediaTypeException.class).isThrownBy(() ->
Expand Down Expand Up @@ -293,6 +299,18 @@ void isConcrete() {
assertThat(new MediaType("text", "*").isConcrete()).as("text/* concrete").isFalse();
}

@Test
void removeQualityValue() {
assertThat(MediaType.parseMediaType("audio/basic;q=0.8").removeQualityValue())
.isEqualTo(MediaType.parseMediaType("audio/basic"));
}

@Test
void removeQualityValueWithUpperCaseParameterName() {
assertThat(MediaType.parseMediaType("audio/basic;Q=0.8").removeQualityValue())
.isEqualTo(MediaType.parseMediaType("audio/basic"));
}

@Test // gh-26127
void serialize() throws Exception {
MediaType original = new MediaType("text", "plain", StandardCharsets.UTF_8);
Expand Down