From efab6eb55dc0f1ce0d7509a0dc932f1aeb075e5d Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Sun, 7 Jul 2019 12:39:46 +0200 Subject: [PATCH] Ignore empty entries when parsing MediaTypes and MimeTypes Prior to Spring Framework 5.1.3, MimeTypeUtils.parseMimeTypes() and MediaType.parseMediaTypes() ignored empty entries, but 5.1.3 introduced a regression in that an empty entry -- for example, due to a trailing comma in the list of media types in an HTTP Accept header -- would result in a "406 Not Acceptable" response status. This commit fixes this by filtering out empty entries before parsing them into MimeType and MediaType instances. Empty entries are therefore effectively ignored. Fixes gh-23241 --- .../main/java/org/springframework/util/MimeTypeUtils.java | 6 ++++-- .../test/java/org/springframework/util/MimeTypeTests.java | 7 +++++++ .../src/main/java/org/springframework/http/MediaType.java | 7 +++++-- .../test/java/org/springframework/http/MediaTypeTests.java | 7 +++++++ 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/util/MimeTypeUtils.java b/spring-core/src/main/java/org/springframework/util/MimeTypeUtils.java index cb4a60325d..9217e06fb8 100644 --- a/spring-core/src/main/java/org/springframework/util/MimeTypeUtils.java +++ b/spring-core/src/main/java/org/springframework/util/MimeTypeUtils.java @@ -38,6 +38,7 @@ import org.springframework.lang.Nullable; * @author Arjen Poutsma * @author Rossen Stoyanchev * @author Dimitrios Liapis + * @author Sam Brannen * @since 4.0 */ public abstract class MimeTypeUtils { @@ -259,10 +260,11 @@ public abstract class MimeTypeUtils { return Collections.emptyList(); } return tokenize(mimeTypes).stream() - .map(MimeTypeUtils::parseMimeType).collect(Collectors.toList()); + .filter(StringUtils::hasText) + .map(MimeTypeUtils::parseMimeType) + .collect(Collectors.toList()); } - /** * Tokenize the given comma-separated string of {@code MimeType} objects * into a {@code List}. Unlike simple tokenization by ",", this diff --git a/spring-core/src/test/java/org/springframework/util/MimeTypeTests.java b/spring-core/src/test/java/org/springframework/util/MimeTypeTests.java index 07f179ba5d..6cd29ef856 100644 --- a/spring-core/src/test/java/org/springframework/util/MimeTypeTests.java +++ b/spring-core/src/test/java/org/springframework/util/MimeTypeTests.java @@ -277,6 +277,13 @@ public class MimeTypeTests { assertEquals("Invalid amount of mime types", 0, mimeTypes.size()); } + @Test // gh-23241 + public void parseMimeTypesWithTrailingComma() { + List mimeTypes = MimeTypeUtils.parseMimeTypes("text/plain, text/html,"); + assertNotNull("No mime types returned", mimeTypes); + assertEquals("Incorrect number of mime types", 2, mimeTypes.size()); + } + @Test // SPR-17459 public void parseMimeTypesWithQuotedParameters() { testWithQuotedParameters("foo/bar;param=\",\""); diff --git a/spring-web/src/main/java/org/springframework/http/MediaType.java b/spring-web/src/main/java/org/springframework/http/MediaType.java index 1342b98a5a..acaee586d3 100644 --- a/spring-web/src/main/java/org/springframework/http/MediaType.java +++ b/spring-web/src/main/java/org/springframework/http/MediaType.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,6 +44,7 @@ import org.springframework.util.StringUtils; * @author Rossen Stoyanchev * @author Sebastien Deleuze * @author Kazuki Shimizu + * @author Sam Brannen * @since 3.0 * @see * HTTP 1.1: Semantics and Content, section 3.1.1.1 @@ -553,7 +554,9 @@ public class MediaType extends MimeType implements Serializable { return Collections.emptyList(); } return MimeTypeUtils.tokenize(mediaTypes).stream() - .map(MediaType::parseMediaType).collect(Collectors.toList()); + .filter(StringUtils::hasText) + .map(MediaType::parseMediaType) + .collect(Collectors.toList()); } /** diff --git a/spring-web/src/test/java/org/springframework/http/MediaTypeTests.java b/spring-web/src/test/java/org/springframework/http/MediaTypeTests.java index 94c7341be8..142b01440f 100644 --- a/spring-web/src/test/java/org/springframework/http/MediaTypeTests.java +++ b/spring-web/src/test/java/org/springframework/http/MediaTypeTests.java @@ -143,6 +143,13 @@ public class MediaTypeTests { assertEquals("Invalid amount of media types", 0, mediaTypes.size()); } + @Test // gh-23241 + public void parseMediaTypesWithTrailingComma() { + List mediaTypes = MediaType.parseMediaTypes("text/plain, text/html, "); + assertNotNull("No media types returned", mediaTypes); + assertEquals("Incorrect number of media types", 2, mediaTypes.size()); + } + @Test public void compareTo() { MediaType audioBasic = new MediaType("audio", "basic");