From 099d0168577ab498529f18a48439a8235c14839a Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Wed, 12 Jun 2024 12:28:26 +0200 Subject: [PATCH] Handle trailing semicolon in Accept-Language Closes gh-32259 --- .../org/springframework/http/HttpHeaders.java | 15 ++++++++++++++- .../springframework/http/HttpHeadersTests.java | 14 ++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/spring-web/src/main/java/org/springframework/http/HttpHeaders.java b/spring-web/src/main/java/org/springframework/http/HttpHeaders.java index 17abfa180a50..635453ab834d 100644 --- a/spring-web/src/main/java/org/springframework/http/HttpHeaders.java +++ b/spring-web/src/main/java/org/springframework/http/HttpHeaders.java @@ -509,7 +509,20 @@ public void setAcceptLanguage(List languages) { */ public List getAcceptLanguage() { String value = getFirst(ACCEPT_LANGUAGE); - return (StringUtils.hasText(value) ? Locale.LanguageRange.parse(value) : Collections.emptyList()); + if (StringUtils.hasText(value)) { + try { + return Locale.LanguageRange.parse(value); + } + catch (IllegalArgumentException ignored) { + String[] tokens = StringUtils.tokenizeToStringArray(value, ","); + for (int i = 0; i < tokens.length; i++) { + tokens[i] = StringUtils.trimTrailingCharacter(tokens[i], ';'); + } + value = StringUtils.arrayToCommaDelimitedString(tokens); + return Locale.LanguageRange.parse(value); + } + } + return Collections.emptyList(); } /** diff --git a/spring-web/src/test/java/org/springframework/http/HttpHeadersTests.java b/spring-web/src/test/java/org/springframework/http/HttpHeadersTests.java index d08892bbb4be..519a6c9d7834 100644 --- a/spring-web/src/test/java/org/springframework/http/HttpHeadersTests.java +++ b/spring-web/src/test/java/org/springframework/http/HttpHeadersTests.java @@ -517,6 +517,20 @@ void acceptLanguage() { assertThat(headers.getAcceptLanguageAsLocales()).first().isEqualTo(Locale.FRANCE); } + @Test // gh-32259 + void acceptLanguageTrailingSemicolon() { + String headerValue = "en-us,en;,nl;"; + headers.set(HttpHeaders.ACCEPT_LANGUAGE, headerValue); + assertThat(headers.getFirst(HttpHeaders.ACCEPT_LANGUAGE)).isEqualTo(headerValue); + + List expectedRanges = Arrays.asList( + new Locale.LanguageRange("en-us"), + new Locale.LanguageRange("en"), + new Locale.LanguageRange("nl") + ); + assertThat(headers.getAcceptLanguage()).isEqualTo(expectedRanges); + } + @Test // SPR-15603 void acceptLanguageWithEmptyValue() { this.headers.set(HttpHeaders.ACCEPT_LANGUAGE, "");