Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Reject MIME type parameters differing only in case#37008

Open
junhyeong9812 wants to merge 1 commit into
spring-projects:mainfrom
junhyeong9812:fix/mimetype-duplicate-parameter-case
Open

Reject MIME type parameters differing only in case#37008
junhyeong9812 wants to merge 1 commit into
spring-projects:mainfrom
junhyeong9812:fix/mimetype-duplicate-parameter-case

Conversation

@junhyeong9812

Copy link
Copy Markdown
Contributor

Overview

MimeTypeUtils rejects duplicate MIME type parameters (gh-36841), but the check is case-sensitive while MIME parameter names are case-insensitive. As a result, duplicates that differ only in case (for example charset and CHARSET) slip through and are silently collapsed to the last value. This aligns the duplicate check with the case-insensitive nature of parameter names.

Problem

When parsing parameters, MimeTypeUtils.parseMimeTypeInternal(...) accumulates them in a LinkedHashMap, and gh-36841 added a duplicate check by throwing when Map#put returns a previous value:

if (parameters.put(attribute, value) != null) {
    throw new InvalidMimeTypeException(mimeType, "duplicate parameter '" + parameter + "'");
}

Because a LinkedHashMap treats charset and CHARSET as distinct keys, a case-variant duplicate never triggers the check:

Input Before
text/plain;dupe="1";dupe="2" rejected (InvalidMimeTypeException)
text/plain;dupe="1";DUPE="2" accepted, silently keeps "2"

This is inconsistent: MIME parameter names are case-insensitive (RFC 2045), and MimeType itself stores parameters in a LinkedCaseInsensitiveMap so that getParameter("CHARSET") and getParameter("charset") resolve to the same value. RFC 6838 section 4.3 (cited by gh-36841) treats duplicate parameters as an error, so a case-only variant is logically the same duplicate.

Fix

Accumulate parameters in a LinkedCaseInsensitiveMap so that a case-variant duplicate maps to the same key, causing put to return the previous value and the existing check to reject it:

// Parameter names are case-insensitive, so use a case-insensitive
// map in order to reject duplicates that differ only in case.
parameters = new LinkedCaseInsensitiveMap<>(4, Locale.ROOT);

Locale.ROOT matches how MimeType builds its own parameter map, keeping case-insensitive comparison locale-independent. The final MimeType is unaffected: its constructor re-copies the parameters into its own LinkedCaseInsensitiveMap, and for non-duplicate input the accumulating map behaves the same as before (same keys, values, and iteration order). Only the duplicate-detection sensitivity changes.

Note on impact

This is a parsing behavior change: Content-Type/Accept-style strings that repeat a parameter with different casing now throw InvalidMimeTypeException instead of parsing successfully. This matches the intent of gh-36841 and the case-insensitive contract of parameter names; valid MIME types are unaffected.

MIME type parameter names are case-insensitive, but the duplicate
parameter check added in spring-projectsgh-36841 accumulated parameters in a
case-sensitive map. As a result, duplicates differing only in case
(such as "charset" and "CHARSET") were not rejected and were
silently collapsed to the last value.

Accumulate parameters in a LinkedCaseInsensitiveMap so that such
duplicates map to the same key and are rejected consistently, matching
the case-insensitive map already used by MimeType for parameter
storage.

Signed-off-by: junhyeong9812 <[email protected]>
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Jul 6, 2026
@sbrannen sbrannen added the in: web Issues in web modules (web, webmvc, webflux, websocket) label Jul 7, 2026
@sbrannen sbrannen requested a review from bclozel July 7, 2026 09:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

in: web Issues in web modules (web, webmvc, webflux, websocket) status: waiting-for-triage An issue we've not yet triaged or decided on

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants